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