CALLBACK.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:4k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (C) 1993 - 1997  Microsoft Corporation.  All Rights Reserved.
  9.  * 
  10.  **************************************************************************/
  11. /* callback.c - Contains the low-level MIDI input callback function for
  12.  *      MIDIMon.  This module also contains the LibMain() and WEP() 
  13.  *      DLL routines, and other functions accessed by the callback.
  14.  *
  15.  *      Because this module contains a low-level callback function,
  16.  *      this entire module must reside in a FIXED code segment in a DLL.
  17.  *      The data segment must be FIXED as well, since it accessed by
  18.  *      the callback.
  19.  */
  20. #include <windows.h>
  21. #include <mmsystem.h>
  22. #include "midimon.h"
  23. #include "circbuf.h"
  24. #include "instdata.h"
  25. #include "callback.h"
  26. /* midiInputHandler - Low-level callback function to handle MIDI input.
  27.  *      Installed by midiInOpen().  The input handler takes incoming
  28.  *      MIDI events and places them in the circular input buffer.  It then
  29.  *      notifies the application by posting a MM_MIDIINPUT message.
  30.  *
  31.  *      This function is accessed at interrupt time, so it should be as 
  32.  *      fast and efficient as possible.  You can't make any
  33.  *      Windows calls here, except PostMessage().  The only Multimedia
  34.  *      Windows call you can make are timeGetSystemTime(), midiOutShortMsg().
  35.  *      
  36.  *
  37.  * Param:   hMidiIn - Handle for the associated input device.
  38.  *          wMsg - One of the MIM_***** messages.
  39.  *          dwInstance - Points to CALLBACKINSTANCEDATA structure.
  40.  *          dwParam1 - MIDI data.
  41.  *          dwParam2 - Timestamp (in milliseconds)
  42.  *
  43.  * Return:  void
  44.  */     
  45. void FAR PASCAL midiInputHandler(
  46. HMIDIIN hMidiIn, 
  47. WORD wMsg, 
  48. DWORD dwInstance, 
  49. DWORD dwParam1, 
  50. DWORD dwParam2)
  51. {
  52.     EVENT event;
  53.     
  54.     switch(wMsg)
  55.     {
  56.         case MIM_OPEN:
  57.             break;
  58.         /* The only error possible is invalid MIDI data, so just pass
  59.          * the invalid data on so we'll see it.
  60.          */
  61.         case MIM_ERROR:
  62.         case MIM_DATA:
  63.             event.fdwEvent = (wMsg == MIM_ERROR) ? EVNT_F_ERROR : 0;
  64.             event.dwDevice = ((LPCALLBACKINSTANCEDATA)dwInstance)->dwDevice;
  65.             event.data = dwParam1;
  66.             event.timestamp = dwParam2;
  67.             
  68.             /* Send the MIDI event to the MIDI Mapper, put it in the
  69.              * circular input buffer, and notify the application that
  70.              * data was received.
  71.              */
  72.             if(((LPCALLBACKINSTANCEDATA)dwInstance)->hMapper)
  73.                 midiOutShortMsg( 
  74.                             ((LPCALLBACKINSTANCEDATA)dwInstance)->hMapper, 
  75.                               dwParam1);
  76.             PutEvent(((LPCALLBACKINSTANCEDATA)dwInstance)->lpBuf,
  77.                        (LPEVENT) &event); 
  78.             PostMessage(((LPCALLBACKINSTANCEDATA)dwInstance)->hWnd,
  79.                           MM_MIDIINPUT, 0, 0L);
  80.             break;
  81.         default:
  82.             break;
  83.     }
  84. }
  85. /* PutEvent - Puts an EVENT in a CIRCULARBUFFER.  If the buffer is full, 
  86.  *      it sets the wError element of the CIRCULARBUFFER structure 
  87.  *      to be non-zero.
  88.  *
  89.  * Params:  lpBuf - Points to the CIRCULARBUFFER.
  90.  *          lpEvent - Points to the EVENT.
  91.  *
  92.  * Return:  void
  93. */
  94. void FAR PASCAL PutEvent(LPCIRCULARBUFFER lpBuf, LPEVENT lpEvent)
  95. {
  96.     /* If the buffer is full, set an error and return. 
  97.      */
  98.     if(lpBuf->dwCount >= lpBuf->dwSize){
  99.         lpBuf->wError = 1;
  100.         return;
  101.     }
  102.     
  103.     /* Put the event in the buffer, bump the head pointer and the byte count.
  104.      */
  105.     *lpBuf->lpHead = *lpEvent;
  106.     
  107.     ++lpBuf->lpHead;
  108.     ++lpBuf->dwCount;
  109.     /* Wrap the head pointer, if necessary.
  110.      */
  111.     if(lpBuf->lpHead >= lpBuf->lpEnd)
  112.         lpBuf->lpHead = lpBuf->lpStart;
  113. }