MMRESULT Midi_InOpen(MIDI *midi) { MMRESULT error; int i; if (midi->inPort == -1) { return MMSYSERR_NOERROR; } /* * Open the port. */ m_closing = FALSE; error = midiInOpen(&midi->midiIn, midi->inPort , (DWORD) m_MidiInProc, (DWORD) midi, CALLBACK_FUNCTION); if (error != MMSYSERR_NOERROR) { return error; } /* * Initialize the midi header array. */ for (i = 0; i < midi->bufCnt; i++) { error = midiInPrepareHeader(midi->midiIn, &midi->midiHdrs[i] , sizeof(MIDIHDR)); if (error != MMSYSERR_NOERROR) { for (i--; i >= 0; i--) { midiInUnprepareHeader(midi->midiIn, &midi->midiHdrs[i] , sizeof(MIDIHDR)); } midiInClose(midi->midiIn); return error; } error = midiInAddBuffer(midi->midiIn, &midi->midiHdrs[i] , sizeof(MIDIHDR)); if (error != MMSYSERR_NOERROR) { midiInReset(midi->midiIn); for ( ; i >= 0; i--) { midiInUnprepareHeader(midi->midiIn, &midi->midiHdrs[i] , sizeof(MIDIHDR)); } midiInClose(midi->midiIn); return error; } } /* * Initiate MIDI input. */ error = midiInStart(midi->midiIn); if (error != MMSYSERR_NOERROR) { midiInReset(midi->midiIn); midiInClose(midi->midiIn); return error; } return error; }
boolean JMIDIInObj::auxNotify(JEvent& e, void* pdata) { #if defined(WIN32) cs.lock(); MMRESULT rc; MIDIHDR *mhdr; if (!connected) goto CSEND; mhdr = (MIDIHDR*)(char*)data; if ((void*)mhdr != pdata) goto CSEND; if (!(mhdr->dwFlags & MHDR_DONE)) goto CSEND; if (mhdr->dwBytesRecorded > 0) {} rc = midiInUnprepareHeader((HMIDIIN)handle, mhdr, sizeof(MIDIHDR)); if (rc == MMSYSERR_NOERROR) rc = midiInPrepareHeader((HMIDIIN)handle, mhdr, sizeof(MIDIHDR)); if (rc == MMSYSERR_NOERROR) rc = midiInAddBuffer((HMIDIIN)handle, mhdr, sizeof(MIDIHDR)); if (rc != MMSYSERR_NOERROR) close(); #endif cs.unlock(); return true; CSEND: cs.unlock(); return false; }
static void midirelease(COMMNG self) { CMMIDI midi; midi = (CMMIDI)(self + 1); midiallnoteoff(midi); if (midi->opened & CMMIDI_MIDIOUT) { waitlastexclusiveout(midi); midiOutReset(midi->out.win32.hmidiout); midiOutClose(midi->out.win32.hmidiout); } if (midi->opened & CMMIDI_MIDIIN) { if (midi->opened & CMMIDI_MIDIINSTART) { midiInStop(midi->hmidiin); midiInUnprepareHeader(midi->hmidiin, &midi->hmidiinhdr, sizeof(MIDIHDR)); } midiInReset(midi->hmidiin); midiInClose(midi->hmidiin); midiinhdlunreg(midi); } #if defined(VERMOUTH_LIB) if (midi->opened & CMMIDI_VERMOUTH) { midiout_destroy(midi->out.vermouth); } #endif #if defined(MT32SOUND_DLL) if (midi->opened & CMMIDI_MT32SOUND) { mt32sound_close(); } #endif _MFREE(self); }
void Close() { if (handle) { midiInUnprepareHeader(handle, &header, sizeof(MIDIHDR)); midiInClose(handle); } }
void writeIfFinished (HMIDIIN deviceHandle) { if ((hdr.dwFlags & WHDR_DONE) != 0) { MMRESULT res = midiInUnprepareHeader (deviceHandle, &hdr, sizeof (hdr)); (void) res; write (deviceHandle); } }
int rtsyn_synth_start(){ int i; UINT port; #ifdef __W32__ DWORD processPriority; processPriority = GetPriorityClass(GetCurrentProcess()); #endif port=0; sleep(2); for(port=0;port<rtsyn_portnumber;port++){ for (i=0;i<MAX_EXBUF;i++){ IMidiHdr[port][i] = (MIDIHDR *)sIMidiHdr[port][i]; memset(IMidiHdr[port][i],0,sizeof(MIDIHDR)); IMidiHdr[port][i]->lpData = sImidiHdr_data[port][i]; memset((IMidiHdr[port][i]->lpData),0,BUFF_SIZE); IMidiHdr[port][i]->dwBufferLength = BUFF_SIZE; } } evbwpoint=0; evbrpoint=0; mvbuse=0; for(port=0;port<rtsyn_portnumber;port++){ midiInOpen(&hMidiIn[port],portID[port],(DWORD)MidiInProc,(DWORD)port,CALLBACK_FUNCTION); for (i=0;i<MAX_EXBUF;i++){ midiInUnprepareHeader(hMidiIn[port],IMidiHdr[port][i],sizeof(MIDIHDR)); midiInPrepareHeader(hMidiIn[port],IMidiHdr[port][i],sizeof(MIDIHDR)); midiInAddBuffer(hMidiIn[port],IMidiHdr[port][i],sizeof(MIDIHDR)); } } #ifdef __W32__ // HACK:midiInOpen()でリセットされてしまうため、再設定 SetPriorityClass(GetCurrentProcess(), processPriority); #endif for(port=0;port<rtsyn_portnumber;port++){ if(MMSYSERR_NOERROR !=midiInStart(hMidiIn[port])){ int i; for(i=0;i<port;i++){ midiInStop(hMidiIn[i]); midiInReset(hMidiIn[i]); midiInClose(hMidiIn[i]); } goto winmmerror; } } mim_start_time = get_current_calender_time(); InitializeCriticalSection(&mim_section); return ~0; winmmerror: ctl->cmsg( CMSG_ERROR, VERB_NORMAL, "midiInStarterror\n" ); return 0; }
int rtsyn_play_some_data(void){ UINT wMsg; DWORD dwInstance; DWORD dwParam1; DWORD dwParam2; DWORD timestamp; MidiEvent ev; MidiEvent evm[260]; int port; UINT evbpoint; MIDIHDR *IIMidiHdr; int exlen; char *sysexbuffer; int ne,i,j,chk,played; played=0; if( !rtsyn_buf_check() ){ played=~0; return played; } do{ EnterCriticalSection(&mim_section); evbpoint=evbrpoint; if (++evbrpoint >= EVBUFF_SIZE) evbrpoint -= EVBUFF_SIZE; wMsg=evbuf[evbpoint].wMsg; dwInstance=evbuf[evbpoint].dwInstance; dwParam1=evbuf[evbpoint].dwParam1; dwParam2=evbuf[evbpoint].dwParam2; LeaveCriticalSection(&mim_section); port=(UINT)dwInstance; switch (wMsg) { case MIM_DATA: rtsyn_play_one_data (port, dwParam1, mim_start_time+(double)dwParam2/1000.0); break; case MIM_LONGDATA: IIMidiHdr = (MIDIHDR *) dwParam1; exlen=(int)IIMidiHdr->dwBytesRecorded; sysexbuffer=IIMidiHdr->lpData; rtsyn_play_one_sysex (sysexbuffer,exlen, mim_start_time+(double)dwParam2/1000.0); if (MMSYSERR_NOERROR != midiInUnprepareHeader( hMidiIn[port], IIMidiHdr, sizeof(MIDIHDR))) ctl->cmsg( CMSG_ERROR, VERB_NORMAL,"error1\n"); if (MMSYSERR_NOERROR != midiInPrepareHeader( hMidiIn[port], IIMidiHdr, sizeof(MIDIHDR))) ctl->cmsg( CMSG_ERROR, VERB_NORMAL,"error5\n"); if (MMSYSERR_NOERROR != midiInAddBuffer( hMidiIn[port], IIMidiHdr, sizeof(MIDIHDR))) ctl->cmsg( CMSG_ERROR, VERB_NORMAL,"error6\n"); break; } }while(rtsyn_buf_check()); return played; }
/*** * Closes the MME MIDI Input port in a safe way */ void MidiInputDeviceMme::MidiInputPortMme::CloseMmeMidiPort(void) { int res; if (MidiInOpened == true) { ExitFlag = true; midiInReset(MidiInHandle); while ((res = midiInClose(MidiInHandle)) == MIDIERR_STILLPLAYING) Sleep(100); midiInUnprepareHeader(MidiInHandle, &midiHdr, sizeof(MIDIHDR)); MidiInOpened = false; } }
void CALLBACK midiCallback(HMIDIIN handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { debugPrintf(1, "callback called %d, handle %p\n", uMsg, handle); switch (uMsg) { case MIM_DATA: midiReceive(SHORT_MSG_STATUS(dwParam1)); midiReceive(SHORT_MSG_BYTE1(dwParam1)); midiReceive(SHORT_MSG_BYTE2(dwParam1)); break; case MIM_LONGDATA: { MIDIHDR *midiHdr = (MIDIHDR *)dwParam1; if (midiHdr->dwBytesRecorded == 0) { return; } unsigned int len = 0; sleepCount = 0; for (len = 0; len < midiHdr->dwBufferLength; len++) { midiReceive(midiHdr->lpData[len]); if (((unsigned char)midiHdr->lpData[len]) == 0xF7) break; } midiInUnprepareHeader(handle, midiHdr, sizeof(*midiHdr)); midiInPrepareHeader(handle, midiHdr, sizeof(*midiHdr)); midiInAddBuffer(handle, midiHdr, sizeof(*midiHdr)); } break; case MIM_MOREDATA: // XXX set IO_STATUS flag to midiInOpen() debugPrintf(1, "midi driver is throwing away received data: %x %x %x\n", SHORT_MSG_STATUS(dwParam1), SHORT_MSG_BYTE1(dwParam1), SHORT_MSG_BYTE2(dwParam1)); break; case MIM_ERROR: logPrintf(LOG_ERROR, "error\n"); break; case MIM_LONGERROR: { logPrintf(LOG_ERROR, "long error\n"); } break; default: debugPrintf(1, "received event %x\n", uMsg); /* ignore */ return; } }
static void test_midiIn_device(UINT udev, HWND hwnd) { HMIDIIN hm; MMRESULT rc; MIDIINCAPSA capsA; MIDIHDR mhdr; rc = midiInGetDevCapsA(udev, &capsA, sizeof(capsA)); ok((MIDIMAPPER==udev) ? (rc==MMSYSERR_BADDEVICEID || broken(rc==MMSYSERR_NODRIVER /*nt,w2k*/)) : rc==0, "midiInGetDevCaps(dev=%d) rc=%s\n", udev, mmsys_error(rc)); if (!rc) { /* MIDI IN capsA.dwSupport may contain garbage, absent in old MS-Windows */ trace("* %s: manufacturer=%d, product=%d, support=%X\n", capsA.szPname, capsA.wMid, capsA.wPid, capsA.dwSupport); } if (hwnd) rc = midiInOpen(&hm, udev, (DWORD_PTR)hwnd, (DWORD_PTR)MYCBINST, CALLBACK_WINDOW); else rc = midiInOpen(&hm, udev, (DWORD_PTR)callback_func, (DWORD_PTR)MYCBINST, CALLBACK_FUNCTION); ok((MIDIMAPPER!=udev) ? rc==0 : (rc==MMSYSERR_BADDEVICEID || broken(rc==MMSYSERR_NODRIVER /*nt,w2k*/)), "midiInOpen(dev=%d) rc=%s\n", udev, mmsys_error(rc)); if (rc) return; test_notification(hwnd, "midiInOpen", MIM_OPEN, 0); memset(&mhdr, 0, sizeof(mhdr)); mhdr.dwFlags = 0; mhdr.dwUser = 0x56FA552C; mhdr.dwBufferLength = 70000; /* > 64KB! */ mhdr.lpData = HeapAlloc(GetProcessHeap(), 0 , mhdr.dwBufferLength); ok(mhdr.lpData!=NULL, "No %d bytes of memory!\n", mhdr.dwBufferLength); if (mhdr.lpData) { rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1); ok(rc==MMSYSERR_INVALPARAM, "midiInPrepare tiny rc=%s\n", mmsys_error(rc)); rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)); ok(!rc, "midiInPrepare old size rc=%s\n", mmsys_error(rc)); rc = midiInPrepareHeader(hm, &mhdr, sizeof(mhdr)); ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc)); rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr)); ok(!rc, "midiInUnprepare rc=%s\n", mmsys_error(rc)); trace("MIDIHDR flags=%x when unsent\n", mhdr.dwFlags); HeapFree(GetProcessHeap(), 0, mhdr.lpData); } ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser); rc = midiInReset(hm); /* Return any pending buffer */ ok(!rc, "midiInReset rc=%s\n", mmsys_error(rc)); rc = midiInClose(hm); ok(!rc, "midiInClose rc=%s\n", mmsys_error(rc)); test_notification(hwnd, "midiInClose", MIM_CLOSE, 0); test_notification(hwnd, "midiIn over", 0, WHATEVER); }
void unprepare (HMIDIIN deviceHandle) { if ((hdr.dwFlags & WHDR_DONE) != 0) { int c = 10; while (--c >= 0 && midiInUnprepareHeader (deviceHandle, &hdr, sizeof (hdr)) == MIDIERR_STILLPLAYING) Thread::sleep (20); jassert (c >= 0); } }
void cmmidi_recvexcv(HMIDIIN hdr, MIDIHDR *data) { CMMIDI midi; midi = midiinhdlget(hdr); if (midi) { midiinrecv(midi, (UINT8 *)data->lpData, data->dwBytesRecorded); midiInUnprepareHeader(midi->hmidiin, &midi->hmidiinhdr, sizeof(MIDIHDR)); midiInPrepareHeader(midi->hmidiin, &midi->hmidiinhdr, sizeof(MIDIHDR)); midiInAddBuffer(midi->hmidiin, &midi->hmidiinhdr, sizeof(MIDIHDR)); } }
void JMIDIInObj::close() { cs.lock(); if (!connected) goto CSEND; connected = false; #if defined(WIN32) midiInStop((HMIDIIN)handle); midiInReset((HMIDIIN)handle); midiInUnprepareHeader((HMIDIIN)handle, (MIDIHDR*)(char*)data, sizeof(MIDIHDR)); midiInClose((HMIDIIN)handle); #endif handle = -1; data.Release(); repaint(); CSEND:; cs.unlock(); }
MidiUartWinClass::~MidiUartWinClass() { if (inHandle != (HMIDIIN)-1) { if (midiInStop(inHandle) != MMSYSERR_NOERROR) { throw "Could not stop MIDI input"; } if (midiInReset(inHandle) != MMSYSERR_NOERROR) { throw "Could reset MIDI input"; } if (midiInClose(inHandle) != MMSYSERR_NOERROR) { throw "Could not close MIDI input"; } midiInUnprepareHeader(inHandle, &midiHdr, sizeof(MIDIHDR)); } if (outHandle != (HMIDIOUT)-1) { midiOutClose(outHandle); } }
bool Win32MidiIn::close() { int wResult; wResult = midiInReset(hMidiIn); if (wResult != MMSYSERR_NOERROR) { qDebug() << "Win32MidiIn: Failed to reset MIDI input port"; } wResult = midiInUnprepareHeader(hMidiIn, &MidiInHdr, sizeof(MIDIHDR)); if (wResult != MMSYSERR_NOERROR) { qDebug() << "Win32MidiIn: Failed to unprepare MIDI header"; } wResult = midiInClose(hMidiIn); if (wResult != MMSYSERR_NOERROR) { qDebug() << "Win32MidiIn: Failed to close MIDI input port"; } return true; }
void midiClose(void) { MMRESULT res; // printf("stop\n"); if (MMSYSERR_NOERROR != midiInStop(inHandle)) { logPrintf(LOG_ERROR, "input stop error\n"); } // printf("reset\n"); if (MMSYSERR_NOERROR != midiInReset(inHandle)) { logPrintf(LOG_ERROR, "input reset error\n"); } int retry = 0; do { res = midiInClose(inHandle); if (res != MMSYSERR_NOERROR) { logPrintf(LOG_ERROR, "input close error\n"); } if (res == MIDIERR_STILLPLAYING) { midiInReset(inHandle); } Sleep(10); retry++; } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); midiInUnprepareHeader(inHandle, &midiHdr, sizeof(MIDIHDR)); retry = 0; res = midiOutReset(outHandle); if (res != MMSYSERR_NOERROR) { logPrintf(LOG_ERROR, "output reset error\n"); } do { res = midiOutClose(outHandle); if (res != MMSYSERR_NOERROR) { logPrintf(LOG_ERROR, "output close error\n"); } Sleep(10); retry++; } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); }
MF_API void MFMidi_CloseInput(MFDevice *pDevice) { MFMidiPC_MidiInputDevice *pMidi = (MFMidiPC_MidiInputDevice*)pDevice->pInternal; if (!pMidi->hMidiIn) { MFDebug_Warn(1, "Midi input device not opened!"); return; } midiInReset(pMidi->hMidiIn); midiInUnprepareHeader(pMidi->hMidiIn, &pMidi->sysexRecv, sizeof(pMidi->sysexRecv)); midiInClose(pMidi->hMidiIn); pMidi->hMidiIn = NULL; MFHeap_Free(pMidi->pEvents); pDevice->state = MFDevState_Available; }
void RtMidiIn :: closePort( void ) { if ( connected_ ) { WinMidiData *data = static_cast<WinMidiData *> (apiData_); midiInReset( data->inHandle ); midiInStop( data->inHandle ); for ( int i=0; i<RT_SYSEX_BUFFER_COUNT; ++i ) { int result = midiInUnprepareHeader(data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR)); delete [] data->sysexBuffer[i]->lpData; delete [] data->sysexBuffer[i]; if ( result != MMSYSERR_NOERROR ) { midiInClose( data->inHandle ); errorString_ = "RtMidiIn::openPort: error closing Windows MM MIDI input port (midiInUnprepareHeader)."; error( RtError::DRIVER_ERROR ); } } midiInClose( data->inHandle ); connected_ = false; } }
void JackWinMMEDriver::CloseInput(MidiSlot* slot) { MMRESULT res; int retry = 0; if (slot->fHandle == 0) return; HMIDIIN handle = (HMIDIIN)slot->fHandle; slot->fHeader->dwUser = 0; res = midiInStop(handle); if (res != MMSYSERR_NOERROR) { jack_error("midiInStop error"); } res = midiInReset(handle); if (res != MMSYSERR_NOERROR) { jack_error("midiInReset error"); } res = midiInUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); if (res != MMSYSERR_NOERROR) { jack_error("midiInUnprepareHeader error"); } do { res = midiInClose(handle); if (res != MMSYSERR_NOERROR) { jack_error("midiInClose error"); } if (res == MIDIERR_STILLPLAYING) midiInReset(handle); Sleep (10); retry++; } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); if (slot->fHeader) { GlobalFreePtr(slot->fHeader); } }
MMRESULT Midi_InClose(MIDI *midi) { MMRESULT error; int i; if (midi->inPort == -1) { return MMSYSERR_NOERROR; } m_closing = TRUE; error = midiInReset(midi->midiIn); if (error != MMSYSERR_NOERROR) { return error; } /* * Unprepare the pending midi buffer header. */ for (i = 0; i < midi->bufCnt; i++) { UnprepareHeader: error = midiInUnprepareHeader(midi->midiIn, &midi->midiHdrs[i] , sizeof(MIDIHDR)); if (error == MIDIERR_STILLPLAYING) { midiInReset(midi->midiIn); SleepEx(50, FALSE); goto UnprepareHeader; } } CloseMidi: error = midiInClose(midi->midiIn); if (error == MIDIERR_STILLPLAYING) { midiInReset(midi->midiIn); SleepEx(50, FALSE); goto CloseMidi; } midi->midiIn = NULL; return error; }
void CALLBACK midiCallback(HMIDIIN handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { MidiUartWinClass *uart = (MidiUartWinClass *)dwInstance; if (uart == NULL) return; // printf("dwParam1: %lx, dwParam2: %lx\n", dwParam1, dwParam2); switch (uMsg) { case MIM_DATA: { uint8_t status = SHORT_MSG_STATUS(dwParam1); if (MIDI_IS_REALTIME_STATUS_BYTE(status)) { if (status >= 0xF8) { uart->rxRb.put(status); } else { switch (status) { case MIDI_MTC_QUARTER_FRAME: case MIDI_SONG_SELECT: uart->rxRb.put(SHORT_MSG_STATUS(dwParam1)); uart->rxRb.put(SHORT_MSG_BYTE1(dwParam1)); break; case MIDI_SONG_POSITION_PTR: uart->rxRb.put(SHORT_MSG_STATUS(dwParam1)); uart->rxRb.put(SHORT_MSG_BYTE1(dwParam1)); uart->rxRb.put(SHORT_MSG_BYTE2(dwParam1)); break; default: printf("unknown status: %x\n", status); break; } } } else { switch (status & 0xF0) { case MIDI_NOTE_OFF: case MIDI_NOTE_ON: case MIDI_AFTER_TOUCH: case MIDI_CONTROL_CHANGE: case MIDI_PITCH_WHEEL: uart->rxRb.put(SHORT_MSG_STATUS(dwParam1)); uart->rxRb.put(SHORT_MSG_BYTE1(dwParam1)); uart->rxRb.put(SHORT_MSG_BYTE2(dwParam1)); break; case MIDI_PROGRAM_CHANGE: case MIDI_CHANNEL_PRESSURE: uart->rxRb.put(SHORT_MSG_STATUS(dwParam1)); uart->rxRb.put(SHORT_MSG_BYTE1(dwParam1)); break; default: printf("unknown midi status: %x\n", status); break; } } } break; case MIM_LONGDATA: { MIDIHDR *midiHdr = (MIDIHDR *)dwParam1; if (midiHdr->dwBytesRecorded == 0) { return; } int len = 0; for (len = 0; len < midiHdr->dwBufferLength; len++) { uart->rxRb.put(midiHdr->lpData[len]); if (((unsigned char)midiHdr->lpData[len]) == 0xF7) break; } midiInUnprepareHeader(handle, midiHdr, sizeof(*midiHdr)); midiInPrepareHeader(handle, midiHdr, sizeof(*midiHdr)); midiInAddBuffer(handle, midiHdr, sizeof(*midiHdr)); } break; case MIM_MOREDATA: printf("midi driver is throwing away received data: %x %x %x\n", SHORT_MSG_STATUS(dwParam1), SHORT_MSG_BYTE1(dwParam1), SHORT_MSG_BYTE2(dwParam1)); break; case MIM_ERROR: printf("callback error\n"); break; case MIM_LONGERROR: printf("callback long error"); break; default: printf("received unknown event %x\n", uMsg); return; } }
/* Callback function executed via midiInput SW interrupt (via midiInOpen). */ static void FAR PASCAL winmm_in_callback( HMIDIIN hMidiIn, /* midiInput device Handle */ UINT wMsg, /* midi msg */ DWORD_PTR dwInstance, /* application data */ DWORD_PTR dwParam1, /* MIDI data */ DWORD_PTR dwParam2) /* device timestamp (wrt most recent midiInStart) */ { static int entry = 0; PmInternal *midi = (PmInternal *) dwInstance; midiwinmm_type m = (midiwinmm_type) midi->descriptor; /* NOTE: we do not just EnterCriticalSection() here because an * MIM_CLOSE message arrives when the port is closed, but then * the m->lock has been destroyed. */ switch (wMsg) { case MIM_DATA: { /* if this callback is reentered with data, we're in trouble. * It's hard to imagine that Microsoft would allow callbacks * to be reentrant -- isn't the model that this is like a * hardware interrupt? -- but I've seen reentrant behavior * using a debugger, so it happens. */ EnterCriticalSection(&m->lock); /* dwParam1 is MIDI data received, packed into DWORD w/ 1st byte of message LOB; dwParam2 is time message received by input device driver, specified in [ms] from when midiInStart called. each message is expanded to include the status byte */ if ((dwParam1 & 0x80) == 0) { /* not a status byte -- ignore it. This happened running the sysex.c test under Win2K with MidiMan USB 1x1 interface, but I can't reproduce it. -RBD */ /* printf("non-status byte found\n"); */ } else { /* data to process */ PmEvent event; if (midi->time_proc) dwParam2 = (*midi->time_proc)(midi->time_info); event.timestamp = (PmTimestamp)dwParam2; event.message = (PmMessage)dwParam1; pm_read_short(midi, &event); } LeaveCriticalSection(&m->lock); break; } case MIM_LONGDATA: { MIDIHDR *lpMidiHdr = (MIDIHDR *) dwParam1; unsigned char *data = (unsigned char *) lpMidiHdr->lpData; unsigned int processed = 0; int remaining = lpMidiHdr->dwBytesRecorded; EnterCriticalSection(&m->lock); /* printf("midi_in_callback -- lpMidiHdr %x, %d bytes, %2x...\n", lpMidiHdr, lpMidiHdr->dwBytesRecorded, *data); */ if (midi->time_proc) dwParam2 = (*midi->time_proc)(midi->time_info); /* can there be more than one message in one buffer? */ /* assume yes and iterate through them */ while (remaining > 0) { unsigned int amt = pm_read_bytes(midi, data + processed, remaining, (PmTimestamp)dwParam2); remaining -= amt; processed += amt; } /* when a device is closed, the pending MIM_LONGDATA buffers are returned to this callback with dwBytesRecorded == 0. In this case, we do not want to send them back to the interface (if we do, the interface will not close, and Windows OS may hang). */ if (lpMidiHdr->dwBytesRecorded > 0) { MMRESULT rslt; lpMidiHdr->dwBytesRecorded = 0; lpMidiHdr->dwFlags = 0; /* note: no error checking -- can this actually fail? */ rslt = midiInPrepareHeader(hMidiIn, lpMidiHdr, sizeof(MIDIHDR)); assert(rslt == MMSYSERR_NOERROR); /* note: I don't think this can fail except possibly for * MMSYSERR_NOMEM, but the pain of reporting this * unlikely but probably catastrophic error does not seem * worth it. */ rslt = midiInAddBuffer(hMidiIn, lpMidiHdr, sizeof(MIDIHDR)); assert(rslt == MMSYSERR_NOERROR); LeaveCriticalSection(&m->lock); } else { midiInUnprepareHeader(hMidiIn,lpMidiHdr,sizeof(MIDIHDR)); LeaveCriticalSection(&m->lock); pm_free(lpMidiHdr); } break; } case MIM_OPEN: break; case MIM_CLOSE: break; case MIM_ERROR: /* printf("MIM_ERROR\n"); */ break; case MIM_LONGERROR: /* printf("MIM_LONGERROR\n"); */ break; default: break; } }