void MidiInputDeviceMme::MidiInputPortMme::ConnectToMmeMidiSource(const char* MidiSource) { // close the old MIDI Input port if it was already opened CloseMmeMidiPort(); MIDIINCAPS midiincaps; int NumDevs = midiInGetNumDevs(); int FoundMidiInDeviceId = -1; for(int i=0;i<NumDevs;i++) { int res = midiInGetDevCaps(i, &midiincaps, sizeof(MIDIINCAPS)); if(res == MMSYSERR_NOERROR) { if(!strcmp(midiincaps.szPname, MidiSource)) { FoundMidiInDeviceId = i; break; } } } if(FoundMidiInDeviceId == -1) throw MidiInputException("MIDI port connect failed"); int res; res = midiInOpen(&MidiInHandle, FoundMidiInDeviceId, (DWORD_PTR)win32_midiin_callback, (DWORD_PTR)this, CALLBACK_FUNCTION); if(res != MMSYSERR_NOERROR) { throw MidiInputException("MIDI port connect failed. midiInOpen error"); } MidiInOpened = true; /* Store pointer to our input buffer for System Exclusive messages in MIDIHDR */ midiHdr.lpData = &TmpSysExBuf[0]; /* Store its size in the MIDIHDR */ midiHdr.dwBufferLength = MME_MAX_SYSEX_BUF_SIZE; /* Flags must be set to 0 */ midiHdr.dwFlags = 0; /* Prepare the buffer and MIDIHDR */ res = midiInPrepareHeader(MidiInHandle, &midiHdr, sizeof(MIDIHDR)); if(res != MMSYSERR_NOERROR) { CloseMmeMidiPort(); throw MidiInputException("MIDI port connect failed. midiInPrepareHeader error"); } /* Queue MIDI input buffer */ res = midiInAddBuffer(MidiInHandle, &midiHdr, sizeof(MIDIHDR)); if(res != MMSYSERR_NOERROR) { CloseMmeMidiPort(); throw MidiInputException("MIDI port connect failed. midiInAddBuffer error"); } res = midiInStart(MidiInHandle); if(res != MMSYSERR_NOERROR) { CloseMmeMidiPort(); throw MidiInputException("MIDI port connect failed, midiInStart failed."); } }
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); }
Parameter::Parameter(void) { /* Initialize values */ for (int i = 0; i < NUM_PARAMETERS; i++) { value[i] = 0.0f; changed[i] = false; } /* Open Midi device */ numDevices = midiInGetNumDevs(); if (numDevices > MAX_NUM_DEVICES) numDevices = MAX_NUM_DEVICES; for (unsigned int devID = 0; devID < numDevices; devID++) { MMRESULT rc; rc = midiInOpen(&(midiInDevice[devID]), devID, (DWORD_PTR)MidiInProc, NULL, CALLBACK_FUNCTION); /* Create input buffers */ midiInHeader[devID].lpData = (LPSTR)midiData[devID]; midiInHeader[devID].dwBufferLength = MIDI_DATA_SIZE; midiInHeader[devID].dwFlags = 0; rc = midiInPrepareHeader(midiInDevice[devID], &midiInHeader[devID], sizeof(midiInHeader[devID])); rc = midiInAddBuffer(midiInDevice[devID], &midiInHeader[devID], sizeof(midiInHeader[devID])); rc = midiInStart(midiInDevice[devID]); } }
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; }
bool Win32MidiIn::open(MidiSession *midiSession, unsigned int midiDevID) { int wResult; // Init midiIn port wResult = midiInOpen(&hMidiIn, midiDevID, (DWORD_PTR)midiInProc, (DWORD_PTR)midiSession, CALLBACK_FUNCTION); if (wResult != MMSYSERR_NOERROR) { QMessageBox::critical(NULL, "Win32MidiIn Error", "Failed to open MIDI input port"); return false; } // Prepare SysEx midiIn buffer MidiInHdr.lpData = (LPSTR)sysexbuf; MidiInHdr.dwBufferLength = 4096; MidiInHdr.dwFlags = 0L; wResult = midiInPrepareHeader(hMidiIn, &MidiInHdr, sizeof(MIDIHDR)); if (wResult != MMSYSERR_NOERROR) { QMessageBox::critical(NULL, "Win32MidiIn Error", "Failed to prepare MIDI buffer header"); return false; } // Add SysEx Buffer wResult = midiInAddBuffer(hMidiIn, &MidiInHdr, sizeof(MIDIHDR)); if (wResult != MMSYSERR_NOERROR) { QMessageBox::critical(NULL, "Win32MidiIn Error", "Failed to add SysEx buffer"); return false; } return midiInStart(hMidiIn) == MMSYSERR_NOERROR; }
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; }
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; }
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 PmError allocate_input_buffer(HMIDIIN h, long buffer_len) { LPMIDIHDR hdr = allocate_buffer(buffer_len); if (!hdr) return pmInsufficientMemory; pm_hosterror = midiInPrepareHeader(h, hdr, sizeof(MIDIHDR)); if (pm_hosterror) { pm_free(hdr); return pm_hosterror; } pm_hosterror = midiInAddBuffer(h, hdr, sizeof(MIDIHDR)); return pm_hosterror; }
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 midiInitialize(char *inputDeviceStr, char *outputDeviceStr) { int inputDevice = atoi(inputDeviceStr); int outputDevice = atoi(outputDeviceStr); char name[256]; getOutDeviceName(outputDevice, name, sizeof(name)); unsigned long result = midiOutOpen(&outHandle, outputDevice, 0, 0, CALLBACK_NULL); if (result) { logPrintf(LOG_ERROR, "Error opening output device %s with ID %d, aborting\n", name, outputDevice); exit(-1); } else { debugPrintf(1, "Opened output device %s.\n", name); } getInDeviceName(inputDevice, name, sizeof(name)); result = midiInOpen(&inHandle, inputDevice, (DWORD)midiCallback, 0, CALLBACK_FUNCTION); if (result) { logPrintf(LOG_ERROR, "Error opening input device %s with ID %d, aborting\n", name, inputDevice); exit(-1); } else { debugPrintf(1, "Opened input device %s.\n", name); } sleepCount = 0; midiHdr.lpData = inputBuffer; midiHdr.dwBufferLength = sizeof(inputBuffer); midiHdr.dwFlags = 0; result = midiInPrepareHeader(inHandle, &midiHdr, sizeof(MIDIHDR)); if (result) { logPrintf(LOG_ERROR, "Could not prepare input buffer\n"); exit(-1); } result = midiInAddBuffer(inHandle, &midiHdr, sizeof(MIDIHDR)); if (result) { logPrintf(LOG_ERROR, "could not add input buffer\n"); exit(-1); } result = midiInStart(inHandle); if (result) { logPrintf(LOG_ERROR, "Could not start recording on input\n"); exit(-1); } }
void MidiUartWinClass::init(int _inputDevice, int _outputDevice) { MidiUartHostParent::init(_inputDevice, _outputDevice); unsigned long result; char name[256]; getOutputDeviceName(outputDevice, name, sizeof(name)); result = midiOutOpen(&outHandle, outputDevice, 0, 0, CALLBACK_NULL); if (result) { throw "Error opening utput device"; } else { printf("Opened output device %s\n", name); } getInputDeviceName(inputDevice, name, sizeof(name)); result = midiInOpen(&inHandle, inputDevice, (DWORD)midiCallback, (DWORD)this, CALLBACK_FUNCTION); if (result) { throw "Error opening input devic"; } else { printf("Opening input device %s\n", name); } midiHdr.lpData = inputBuffer; midiHdr.dwBufferLength = sizeof(inputBuffer); midiHdr.dwFlags = 0; result = midiInPrepareHeader(inHandle, &midiHdr, sizeof(MIDIHDR)); if (result) { throw "Could not prepare input buffer"; } result = midiInAddBuffer(inHandle, &midiHdr, sizeof(MIDIHDR)); if (result) { throw "Could not add input buffer"; } result = midiInStart(inHandle); if (result) { throw "Could not start recording on input"; } }
MMRESULT Open(unsigned int deviceId) { // open midi input MMRESULT mmResult; mmResult = midiInOpen(&handle, deviceId, DWORD_PTR(Proc), NULL, CALLBACK_FUNCTION); if (mmResult) { char buf[256]; GetLastErrorMessage(buf, 256); DebugPrint("Error opening MIDI input: %s", buf); return mmResult; } // prepare input buffer header.lpData = sysexbuffer; header.dwBufferLength = sizeof(sysexbuffer); header.dwFlags = 0; mmResult = midiInPrepareHeader(handle, &header, sizeof(MIDIHDR)); if (mmResult) { char buf[256]; GetLastErrorMessage(buf, 256); DebugPrint("Error preparing MIDI header: %s", buf); return mmResult; } // queue input buffer mmResult = midiInAddBuffer(handle, &header, sizeof(MIDIHDR)); if (mmResult) { char buf[256]; GetLastErrorMessage(buf, 256); DebugPrint("Error adding MIDI input buffer: %s", buf); return mmResult; } return mmResult; }
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; } }
static PmError winmm_in_open(PmInternal *midi, void *driverInfo) { DWORD dwDevice; int i = midi->device_id; midiwinmm_type m; LPMIDIHDR hdr; dwDevice = (DWORD) descriptors[i].descriptor; /* create system dependent device data */ m = (midiwinmm_type) pm_alloc(sizeof(midiwinmm_node)); /* create */ midi->descriptor = m; if (!m) goto no_memory; m->handle.in = NULL; m->buffers = NULL; m->num_buffers = 0; m->next_buffer = 0; m->last_time = 0; m->first_message = TRUE; /* not used for input */ m->sysex_mode = FALSE; m->sysex_word = 0; m->sysex_byte_count = 0; m->sync_time = 0; m->delta = 0; m->error = MMSYSERR_NOERROR; m->callback_error = MMSYSERR_NOERROR; /* open device */ pm_hosterror = midiInOpen(&(m->handle.in), /* input device handle */ dwDevice, /* device ID */ (DWORD) winmm_in_callback, /* callback address */ (DWORD) midi, /* callback instance data */ CALLBACK_FUNCTION); /* callback is a procedure */ if (pm_hosterror) goto free_descriptor; /* allocate first buffer for sysex data */ hdr = allocate_buffer(PM_DEFAULT_SYSEX_BUFFER_SIZE); if (!hdr) goto close_device; pm_hosterror = midiInPrepareHeader(m->handle.in, hdr, sizeof(MIDIHDR)); if (pm_hosterror) { pm_free(hdr); goto close_device; } pm_hosterror = midiInAddBuffer(m->handle.in, hdr, sizeof(MIDIHDR)); if (pm_hosterror) goto close_device; /* allocate second buffer */ hdr = allocate_buffer(PM_DEFAULT_SYSEX_BUFFER_SIZE); if (!hdr) goto close_device; pm_hosterror = midiInPrepareHeader(m->handle.in, hdr, sizeof(MIDIHDR)); if (pm_hosterror) { pm_free(hdr); goto reset_device; /* because first buffer was added */ } pm_hosterror = midiInAddBuffer(m->handle.in, hdr, sizeof(MIDIHDR)); if (pm_hosterror) goto reset_device; /* start device */ pm_hosterror = midiInStart(m->handle.in); if (pm_hosterror) goto reset_device; return pmNoError; /* undo steps leading up to the detected error */ reset_device: /* ignore return code (we already have an error to report) */ midiInReset(m->handle.in); close_device: midiInClose(m->handle.in); /* ignore return code */ free_descriptor: midi->descriptor = NULL; pm_free(m); no_memory: if (pm_hosterror) { int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); assert(err == MMSYSERR_NOERROR); return pmHostError; } /* if !pm_hosterror, then the error must be pmInsufficientMemory */ return pmInsufficientMemory; /* note: if we return an error code, the device will be closed and memory will be freed. It's up to the caller to free the parameter midi */ }
int JackWinMMEDriver::Open(bool capturing, bool playing, int inchannels, int outchannels, bool monitor, const char* capture_driver_name, const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency) { jack_log("JackWinMMEDriver::Open"); fRealCaptureChannels = midiInGetNumDevs(); fRealPlaybackChannels = midiOutGetNumDevs(); // Generic JackMidiDriver Open if (JackMidiDriver::Open(capturing, playing, fRealCaptureChannels, fRealPlaybackChannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) return -1; fMidiDestination = new MidiSlot[fRealCaptureChannels]; assert(fMidiDestination); // Real input int devindex = 0; for (int i = 0; i < fRealCaptureChannels; i++) { HMIDIIN handle; fMidiDestination[devindex].fIndex = i; MMRESULT ret = midiInOpen(&handle, fMidiDestination[devindex].fIndex, (DWORD)MidiInProc, (DWORD)fRingBuffer[devindex], CALLBACK_FUNCTION); if (ret == MMSYSERR_NOERROR) { fMidiDestination[devindex].fHandle = handle; if (!InitHeaders(&fMidiDestination[devindex])) { jack_error("memory allocation failed"); midiInClose(handle); continue; } ret = midiInPrepareHeader(handle, fMidiDestination[devindex].fHeader, sizeof(MIDIHDR)); if (ret == MMSYSERR_NOERROR) { fMidiDestination[devindex].fHeader->dwUser = 1; ret = midiInAddBuffer(handle, fMidiDestination[devindex].fHeader, sizeof(MIDIHDR)); if (ret == MMSYSERR_NOERROR) { ret = midiInStart(handle); if (ret != MMSYSERR_NOERROR) { jack_error("midiInStart error"); CloseInput(&fMidiDestination[devindex]); continue; } } else { jack_error ("midiInAddBuffer error"); CloseInput(&fMidiDestination[devindex]); continue; } } else { jack_error("midiInPrepareHeader error"); midiInClose(handle); continue; } } else { jack_error ("midiInOpen error"); continue; } devindex += 1; } fRealCaptureChannels = devindex; fCaptureChannels = devindex; fMidiSource = new MidiSlot[fRealPlaybackChannels]; assert(fMidiSource); // Real output devindex = 0; for (int i = 0; i < fRealPlaybackChannels; i++) { MMRESULT res; HMIDIOUT handle; fMidiSource[devindex].fIndex = i; UINT ret = midiOutOpen(&handle, fMidiSource[devindex].fIndex, 0L, 0L, CALLBACK_NULL); if (ret == MMSYSERR_NOERROR) { fMidiSource[devindex].fHandle = handle; if (!InitHeaders(&fMidiSource[devindex])) { jack_error("memory allocation failed"); midiOutClose(handle); continue; } res = midiOutPrepareHeader(handle, fMidiSource[devindex].fHeader, sizeof(MIDIHDR)); if (res != MMSYSERR_NOERROR) { jack_error("midiOutPrepareHeader error %d %d %d", i, handle, res); continue; } else { fMidiSource[devindex].fHeader->dwUser = 1; } } else { jack_error("midiOutOpen error"); continue; } devindex += 1; } fRealPlaybackChannels = devindex; fPlaybackChannels = devindex; return 0; }
MF_API bool MFMidi_OpenInput(MFDevice *pDevice, bool bBuffered, MFMidiEventCallback *pEventCallback) { MFDebug_Assert(pDevice->type == MFDT_MidiInput, "Not a MIDI device!"); if (pDevice->state == MFDevState_Ready || pDevice->state == MFDevState_Active) { MFDebug_Warn(1, "Midi input device already opened!"); return false; } if (pDevice->state != MFDevState_Available) { MFDebug_Warn(1, "Unable to open midi input device!"); return false; } MFMidiPC_MidiInputDevice *pMidi = (MFMidiPC_MidiInputDevice*)pDevice->pInternal; // find and open the device // TODO: FIXME! this won't work if there are 2 instances of the same device attached to the PC!!! UINT numInputDevices = midiInGetNumDevs(); UINT i = 0; for (; i < numInputDevices; ++i) { MIDIINCAPS caps; MMRESULT r = midiInGetDevCaps(i, &caps, sizeof(caps)); if (r != MMSYSERR_NOERROR) continue; if (caps.wMid == pMidi->mid && caps.wPid == pMidi->pid) break; } if (i == numInputDevices) { MFDebug_Warn(1, MFStr("Midi output device '%s' not found!", pDevice->strings[MFDS_ID])); pDevice->state = MFDevState_Unknown; // set this flag? return false; } MMRESULT r = midiInOpen(&pMidi->hMidiIn, i, (DWORD_PTR)MidiInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION | MIDI_IO_STATUS); if (r != MMSYSERR_NOERROR) { pMidi->hMidiIn = NULL; pDevice->state = MFDevState_Unknown; wchar_t errorBuffer[256]; midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to open MIDI input device: %s", MFString_WCharAsUTF8(errorBuffer))); return false; } MFZeroMemory(&pMidi->sysexRecv, sizeof(pMidi->sysexRecv)); pMidi->sysexRecv.lpData = (LPSTR)pMidi->sysexRecvBuffer; pMidi->sysexRecv.dwBufferLength = sizeof(pMidi->sysexRecvBuffer); r = midiInPrepareHeader(pMidi->hMidiIn, &pMidi->sysexRecv, sizeof(pMidi->sysexRecv)); if (r != MMSYSERR_NOERROR) { wchar_t errorBuffer[256]; midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to open MIDI input device: %s", MFString_WCharAsUTF8(errorBuffer))); } r = midiInAddBuffer(pMidi->hMidiIn, &pMidi->sysexRecv, sizeof(pMidi->sysexRecv)); if (r != MMSYSERR_NOERROR) { wchar_t errorBuffer[256]; midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer)); MFDebug_Warn(1, MFStr("Failed to open MIDI input device: %s", MFString_WCharAsUTF8(errorBuffer))); } pMidi->bBuffered = bBuffered; pMidi->pEventCallback = pEventCallback; pMidi->numAllocated = 256; pMidi->pEvents = (MFMidiEvent*)MFHeap_Alloc(sizeof(MFMidiEvent) * pMidi->numAllocated); pDevice->state = MFDevState_Ready; if (!bBuffered && !pEventCallback) MFMidi_Start(pDevice); return true; }
/* 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; } }
COMMNG cmmidi_create(const OEMCHAR *midiout, const OEMCHAR *midiin, const OEMCHAR *module) { UINT opened; UINT id; void (*shortout)(CMMIDI self, UINT32 msg); void (*longout)(CMMIDI self, const UINT8 *msg, UINT leng); HMIDIFNOUT out; HMIDIIN hmidiin = NULL; COMMNG ret; CMMIDI midi; opened = 0; ZeroMemory(&out, sizeof(out)); shortout = midi_ncshort; longout = midi_nclong; if (getmidioutid(midiout, &id) == SUCCESS) { if (midiOutOpen(&out.win32.hmidiout, id, 0, 0, CALLBACK_NULL) == MMSYSERR_NOERROR) { midiOutReset(out.win32.hmidiout); shortout = midi_win32short; longout = midi_win32long; opened |= CMMIDI_MIDIOUT; } } if (getmidiinid(midiin, &id) == SUCCESS) { if (midiInOpen(&hmidiin, id, (DWORD)g_hWndMain, 0, CALLBACK_WINDOW) == MMSYSERR_NOERROR) { midiInReset(hmidiin); opened |= CMMIDI_MIDIIN; } } #if defined(VERMOUTH_LIB) else if (!milstr_cmp(midiout, cmmidi_vermouth)) { out.vermouth = midiout_create(vermouth_module, 512); if (out.vermouth != NULL) { shortout = midi_vermouthshort; longout = midi_vermouthlong; opened |= CMMIDI_VERMOUTH; } } #endif #if defined(MT32SOUND_DLL) else if (!milstr_cmp(midiout, cmmidi_mt32sound)) { if (mt32sound_open() == SUCCESS) { shortout = midi_mt32short; longout = midi_mt32long; opened |= CMMIDI_MT32SOUND; } } #endif if (!opened) { goto cmcre_err1; } ret = (COMMNG)_MALLOC(sizeof(_COMMNG) + sizeof(_CMMIDI), "MIDI"); if (ret == NULL) { goto cmcre_err2; } ret->connect = COMCONNECT_MIDI; ret->read = midiread; ret->write = midiwrite; ret->getstat = midigetstat; ret->msg = midimsg; ret->release = midirelease; midi = (CMMIDI)(ret + 1); ZeroMemory(midi, sizeof(_CMMIDI)); midi->opened = opened; midi->shortout = shortout; midi->longout = longout; midi->out = out; midi->midictrl = MIDICTRL_READY; #if 1 midi->hmidiin = hmidiin; if (opened & CMMIDI_MIDIIN) { if (midiinhdlreg(midi, hmidiin) == SUCCESS) { midi->opened |= CMMIDI_MIDIINSTART; midi->hmidiinhdr.lpData = (char *)midi->midiinbuf; midi->hmidiinhdr.dwBufferLength = MIDI_BUFFER; midiInPrepareHeader(hmidiin, &midi->hmidiinhdr, sizeof(MIDIHDR)); midiInAddBuffer(hmidiin, &midi->hmidiinhdr, sizeof(MIDIHDR)); midiInStart(hmidiin); } } #endif #if defined(VERMOUTH_LIB) if (opened & CMMIDI_VERMOUTH) { sound_streamregist((void *)out.vermouth, (SOUNDCB)vermouth_getpcm); } #endif #if defined(MT32SOUND_DLL) if (opened & CMMIDI_MT32SOUND) { sound_streamregist(NULL, (SOUNDCB)mt32_getpcm); } #endif // midi->midisyscnt = 0; // midi->mpos = 0; midi->midilast = 0x80; // midi->midiexcvwait = 0; midi->midimodule = (UINT8)module2number(module); FillMemory(midi->mch, sizeof(midi->mch), 0xff); return(ret); cmcre_err2: if (opened & CMMIDI_MIDIOUT) { midiOutReset(out.win32.hmidiout); midiOutClose(out.win32.hmidiout); } #if defined(VERMOUTH_LIB) if (opened & CMMIDI_VERMOUTH) { midiout_destroy(out.vermouth); } #endif #if defined(MT32SOUND_DLL) if (opened & CMMIDI_MT32SOUND) { mt32sound_close(); } #endif cmcre_err1: return(NULL); }
void write (HMIDIIN deviceHandle) { hdr.dwBytesRecorded = 0; MMRESULT res = midiInPrepareHeader (deviceHandle, &hdr, sizeof (hdr)); res = midiInAddBuffer (deviceHandle, &hdr, sizeof (hdr)); }
void RtMidiIn :: openPort( unsigned int portNumber, const std::string /*portName*/ ) { if ( connected_ ) { errorString_ = "RtMidiIn::openPort: a valid connection already exists!"; error( RtError::WARNING ); return; } unsigned int nDevices = midiInGetNumDevs(); if (nDevices == 0) { errorString_ = "RtMidiIn::openPort: no MIDI input sources found!"; error( RtError::NO_DEVICES_FOUND ); } std::ostringstream ost; if ( portNumber >= nDevices ) { ost << "RtMidiIn::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; errorString_ = ost.str(); error( RtError::INVALID_PARAMETER ); } WinMidiData *data = static_cast<WinMidiData *> (apiData_); MMRESULT result = midiInOpen( &data->inHandle, portNumber, (DWORD)&midiInputCallback, (DWORD)&inputData_, CALLBACK_FUNCTION ); if ( result != MMSYSERR_NOERROR ) { errorString_ = "RtMidiIn::openPort: error creating Windows MM MIDI input port."; error( RtError::DRIVER_ERROR ); } // Allocate and init the sysex buffers. for ( int i=0; i<RT_SYSEX_BUFFER_COUNT; ++i ) { data->sysexBuffer[i] = (MIDIHDR*) new char[ sizeof(MIDIHDR) ]; data->sysexBuffer[i]->lpData = new char[ RT_SYSEX_BUFFER_SIZE ]; data->sysexBuffer[i]->dwBufferLength = RT_SYSEX_BUFFER_SIZE; data->sysexBuffer[i]->dwUser = i; // We use the dwUser parameter as buffer indicator data->sysexBuffer[i]->dwFlags = 0; result = midiInPrepareHeader( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) ); if ( result != MMSYSERR_NOERROR ) { midiInClose( data->inHandle ); errorString_ = "RtMidiIn::openPort: error starting Windows MM MIDI input port (PrepareHeader)."; error( RtError::DRIVER_ERROR ); } // Register the buffer. result = midiInAddBuffer( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) ); if ( result != MMSYSERR_NOERROR ) { midiInClose( data->inHandle ); errorString_ = "RtMidiIn::openPort: error starting Windows MM MIDI input port (AddBuffer)."; error( RtError::DRIVER_ERROR ); } } result = midiInStart( data->inHandle ); if ( result != MMSYSERR_NOERROR ) { midiInClose( data->inHandle ); errorString_ = "RtMidiIn::openPort: error starting Windows MM MIDI input port."; error( RtError::DRIVER_ERROR ); } connected_ = true; }
MOboolean moMidiDevice::Init( moText devicetext ) { SetName(devicetext); #ifdef WIN32 /* BOOL result; GUID hidGUID; HDEVINFO hardwareDeviceInfoSet; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; DWORD Index = 0; DWORD requiredSize; //Get the HID GUID value - used as mask to get list of devices HidD_GetHidGuid ( &hidGUID ); //Get a list of devices matching the criteria (hid interface, present) hardwareDeviceInfoSet = SetupDiGetClassDevs (&hidGUID, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | DIGCF_ALLCLASSES |DIGCF_DEVICEINTERFACE)); deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); //Go through the list and get the interface data for(int i = 0; i < 10; i++) { result = SetupDiEnumDeviceInterfaces (hardwareDeviceInfoSet, NULL, //infoData, &hidGUID, //interfaceClassGuid, Index, &deviceInterfaceData); if (result == FALSE) { Index++; } } // Failed to get a device - possibly the index is larger than the number of devices if (result == FALSE) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet); return;// INVALID_HANDLE_VALUE; } //Get the details with null values to get the required size of the buffer SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfoSet, &deviceInterfaceData, NULL, //interfaceDetail, 0, //interfaceDetailSize, &requiredSize, 0); //infoData)) */ MIDIINCAPS moc; unsigned long iNumDevs, i; /* Get the number of MIDI Out devices in this computer */ iNumDevs = midiInGetNumDevs(); if (iNumDevs==0) { MODebug2->Message( moText("ERROR! NO MIDI DEVICES FOUND")); } /* Go through all of those devices, displaying their names */ for (i = 0; i < iNumDevs; i++) { /* Get info about the next device */ if (!midiInGetDevCaps(i, &moc, sizeof(MIDIINCAPS))) { /* Display its Device ID and name */ MODebug2->Message( moText("Device ID #") + IntToStr(i) + moText(":") + moText(moc.szPname)); if ( !stricmp(moc.szPname, devicetext) ) { m_DeviceId = i; break; } } } /* unsigned long result; HMIDIOUT outHandle; // Open the MIDI Mapper result = midiOutOpen(&outHandle, i, 0, 0, CALLBACK_WINDOW); if (!result) { // Output the C note (ie, sound the note) midiOutShortMsg(outHandle, 0x00403C90); // Output the E note midiOutShortMsg(outHandle, 0x00404090); // Output the G note midiOutShortMsg(outHandle, 0x00404390); // Here you should insert a delay so that you can hear the notes sounding Sleep(1000); // Now let's turn off those 3 notes midiOutShortMsg(outHandle, 0x00003C90); midiOutShortMsg(outHandle, 0x00004090); midiOutShortMsg(outHandle, 0x00004390); // Close the MIDI device midiOutClose(outHandle); } else { printf("There was an error opening MIDI Mapper!\r\n"); } */ HMIDIIN handle; MIDIHDR midiHdr; unsigned long err; if (m_DeviceId!=-1) { /* Open default MIDI In device */ if (!(err = midiInOpen(&handle, m_DeviceId, (DWORD)midiCallback, (DWORD)this, CALLBACK_FUNCTION))) { // Store pointer to our input buffer for System Exclusive messages in MIDIHDR midiHdr.lpData = (LPSTR)&SysXBuffer[0]; // Store its size in the MIDIHDR midiHdr.dwBufferLength = sizeof(SysXBuffer); // Flags must be set to 0 midiHdr.dwFlags = 0; // Prepare the buffer and MIDIHDR err = midiInPrepareHeader(handle, &midiHdr, sizeof(MIDIHDR)); if (!err) { // Queue MIDI input buffer err = midiInAddBuffer(handle, &midiHdr, sizeof(MIDIHDR)); if (!err) { // Start recording Midi err = midiInStart(handle); m_bInit = true; return true; /* if (!err) { // Wait for user to abort recording printf("Press any key to stop recording...\r\n\n"); _getch(); // We need to set a flag to tell our callback midiCallback() // not to do any more midiInAddBuffer(), because when we // call midiInReset() below, Windows will send a final // MIM_LONGDATA message to that callback. If we were to // allow midiCallback() to midiInAddBuffer() again, we'd // never get the driver to finish with our midiHdr SysXFlag |= 0x80; printf("\r\nRecording stopped!\n"); }*/ /* Stop recording */ //midiInReset(handle); } } /* // If there was an error above, then print a message if (err) PrintMidiInErrorMsg(err); // Close the MIDI In device while ((err = midiInClose(handle)) == MIDIERR_STILLPLAYING) Sleep(0); if (err) PrintMidiInErrorMsg(err); // Unprepare the buffer and MIDIHDR. Unpreparing a buffer that has not been prepared is ok midiInUnprepareHeader(handle, &midiHdr, sizeof(MIDIHDR)); */ } else { printf("Error opening the default MIDI In Device!\r\n"); PrintMidiInErrorMsg(err); return false; } } #else #endif return false; }