Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.5 KiB

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