home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / audio / midimon / callback.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  4.1 KB  |  124 lines

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