2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
13 CRITICAL_SECTION send_cs;
14 CRITICAL_SECTION recv_cs;
16 unsigned __stdcall midi_thread(void *lpx)
18 volatile midi_thread_params_t *p = (midi_thread_params_t *)lpx;
19 HMIDIOUT hMidi = NULL;
20 MMRESULT result = midiOutOpen(&hMidi, MIDI_MAPPER, NULL, NULL, CALLBACK_NULL);
22 while(!p->terminate) {
27 EnterCriticalSection(&send_cs);
28 if(!p->send_buffer->empty()) {
29 uint8_t msg = p->send_buffer->read_not_remove(0);
32 case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0:
43 for(int i = 1; i < p->send_buffer->count(); i++) {
44 if(p->send_buffer->read_not_remove(i) == 0xf7) {
56 case 0xf6: case 0xf8: case 0xfa: case 0xfb: case 0xfc: case 0xfe: case 0xff:
61 p->send_buffer->read();
67 p->send_buffer->read();
70 if(p->send_buffer->count() >= length) {
71 for(int i = 0; i < length; i++) {
72 buffer[i] = p->send_buffer->read();
78 LeaveCriticalSection(&send_cs);
81 if(result == MMSYSERR_NOERROR) {
82 if(buffer[0] == 0xf0) {
86 ZeroMemory(&mhMidi, sizeof(mhMidi));
87 mhMidi.lpData = (LPSTR)buffer;
88 mhMidi.dwBufferLength = length;
89 mhMidi.dwBytesRecorded = length;
90 midiOutPrepareHeader(hMidi, &mhMidi, sizeof(mhMidi));
91 midiOutLongMsg(hMidi, &mhMidi, sizeof(mhMidi));
92 while(!(mhMidi.dwFlags & MHDR_DONE)) {
95 midiOutUnprepareHeader(hMidi, &mhMidi, sizeof(mhMidi));
97 union UNION_MIDI_DATA {
103 for(int i = 0; i < 4; i++) {
104 out.data[i] = (i < length) ? buffer[i] : 0;
106 midiOutShortMsg(hMidi,out.msg);
115 if(result == MMSYSERR_NOERROR) {
122 void OSD::initialize_midi()
124 midi_thread_params.send_buffer = new FIFO(1024);
125 midi_thread_params.recv_buffer = new FIFO(1024);
126 midi_thread_params.terminate = false;
128 InitializeCriticalSection(&send_cs);
129 InitializeCriticalSection(&recv_cs);
130 hMidiThread = (HANDLE)_beginthreadex(NULL, 0, midi_thread, &midi_thread_params, 0, NULL);
133 void OSD::release_midi()
136 midi_thread_params.terminate = true;
137 WaitForSingleObject(hMidiThread, INFINITE);
140 DeleteCriticalSection(&send_cs);
141 DeleteCriticalSection(&recv_cs);
143 midi_thread_params.send_buffer->release();
144 delete midi_thread_params.send_buffer;
145 midi_thread_params.send_buffer = NULL;
146 midi_thread_params.recv_buffer->release();
147 delete midi_thread_params.recv_buffer;
148 midi_thread_params.recv_buffer = NULL;
151 void OSD::send_to_midi(uint8_t data)
153 EnterCriticalSection(&send_cs);
154 midi_thread_params.send_buffer->write(data);
155 LeaveCriticalSection(&send_cs);
158 bool OSD::recv_from_midi(uint8_t *data)
161 EnterCriticalSection(&recv_cs);
162 if(!midi_thread_params.recv_buffer->empty()) {
163 *data = (uint8_t)midi_thread_params.recv_buffer->read();
166 LeaveCriticalSection(&recv_cs);