| @@ -55,7 +55,8 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, | |||||
| std::auto_ptr<JackMidiBufferWriteQueue> write_queue_ptr(write_queue); | std::auto_ptr<JackMidiBufferWriteQueue> write_queue_ptr(write_queue); | ||||
| sysex_buffer = new jack_midi_data_t[max_bytes]; | sysex_buffer = new jack_midi_data_t[max_bytes]; | ||||
| char error_message[MAXERRORLENGTH]; | char error_message[MAXERRORLENGTH]; | ||||
| MMRESULT result = midiInOpen(&handle, index, (DWORD_PTR)HandleMidiInputEvent, | |||||
| MMRESULT result = midiInOpen(&handle, index, | |||||
| (DWORD_PTR) HandleMidiInputEvent, | |||||
| (DWORD_PTR)this, | (DWORD_PTR)this, | ||||
| CALLBACK_FUNCTION | MIDI_IO_STATUS); | CALLBACK_FUNCTION | MIDI_IO_STATUS); | ||||
| if (result != MMSYSERR_NOERROR) { | if (result != MMSYSERR_NOERROR) { | ||||
| @@ -108,7 +109,8 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, | |||||
| close_handle: | close_handle: | ||||
| result = midiInClose(handle); | result = midiInClose(handle); | ||||
| if (result != MMSYSERR_NOERROR) { | if (result != MMSYSERR_NOERROR) { | ||||
| WriteInError("JackWinMMEInputPort [constructor]", "midiInClose", result); | |||||
| WriteInError("JackWinMMEInputPort [constructor]", "midiInClose", | |||||
| result); | |||||
| } | } | ||||
| delete_sysex_buffer: | delete_sysex_buffer: | ||||
| delete[] sysex_buffer; | delete[] sysex_buffer; | ||||
| @@ -123,8 +125,8 @@ JackWinMMEInputPort::~JackWinMMEInputPort() | |||||
| } | } | ||||
| result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); | result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); | ||||
| if (result != MMSYSERR_NOERROR) { | if (result != MMSYSERR_NOERROR) { | ||||
| WriteInError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", | |||||
| result); | |||||
| WriteInError("JackWinMMEInputPort [destructor]", | |||||
| "midiInUnprepareHeader", result); | |||||
| } | } | ||||
| result = midiInClose(handle); | result = midiInClose(handle); | ||||
| if (result != MMSYSERR_NOERROR) { | if (result != MMSYSERR_NOERROR) { | ||||
| @@ -155,6 +157,15 @@ JackWinMMEInputPort::EnqueueMessage(jack_nframes_t time, size_t length, | |||||
| } | } | ||||
| } | } | ||||
| void | |||||
| JackWinMMEInputPort::GetInErrorString(MMRESULT error, LPTSTR text) | |||||
| { | |||||
| MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); | |||||
| if (result != MMSYSERR_NOERROR) { | |||||
| snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); | |||||
| } | |||||
| } | |||||
| void | void | ||||
| JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, | JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, | ||||
| jack_nframes_t frames) | jack_nframes_t frames) | ||||
| @@ -164,7 +175,7 @@ JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, | |||||
| jack_event = thread_queue->DequeueEvent(); | jack_event = thread_queue->DequeueEvent(); | ||||
| } | } | ||||
| for (; jack_event; jack_event = thread_queue->DequeueEvent()) { | for (; jack_event; jack_event = thread_queue->DequeueEvent()) { | ||||
| switch (write_queue->EnqueueEvent(jack_event)) { | |||||
| switch (write_queue->EnqueueEvent(jack_event, frames)) { | |||||
| case JackMidiWriteQueue::BUFFER_TOO_SMALL: | case JackMidiWriteQueue::BUFFER_TOO_SMALL: | ||||
| jack_error("JackWinMMEMidiInputPort::Process - The buffer write " | jack_error("JackWinMMEMidiInputPort::Process - The buffer write " | ||||
| "queue couldn't enqueue a %d-byte event. Dropping " | "queue couldn't enqueue a %d-byte event. Dropping " | ||||
| @@ -181,7 +192,7 @@ void | |||||
| JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) | JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) | ||||
| { | { | ||||
| set_threaded_log_function(); | set_threaded_log_function(); | ||||
| jack_nframes_t current_frame = GetCurrentFrame(); | |||||
| jack_nframes_t current_frame = GetCurrentFrame(); | |||||
| switch (message) { | switch (message) { | ||||
| case MIM_CLOSE: | case MIM_CLOSE: | ||||
| @@ -219,17 +230,23 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) | |||||
| return; | return; | ||||
| } | } | ||||
| EnqueueMessage(current_frame, (size_t) length, message_buffer); | EnqueueMessage(current_frame, (size_t) length, message_buffer); | ||||
| break; | |||||
| break; | |||||
| } | } | ||||
| case MIM_LONGDATA: { | case MIM_LONGDATA: { | ||||
| LPMIDIHDR header = (LPMIDIHDR) param1; | LPMIDIHDR header = (LPMIDIHDR) param1; | ||||
| size_t byte_count = header->dwBytesRecorded; | |||||
| if (! byte_count) { | |||||
| jack_info("JackWinMMEInputPort::ProcessWinMME - WinMME driver has " | |||||
| "returned sysex header to us with no bytes. The JACK " | |||||
| "driver is probably being stopped."); | |||||
| break; | |||||
| } | |||||
| jack_midi_data_t *data = (jack_midi_data_t *) header->lpData; | jack_midi_data_t *data = (jack_midi_data_t *) header->lpData; | ||||
| size_t length1 = header->dwBytesRecorded; | |||||
| if ((data[0] != 0xf0) || (data[length1 - 1] != 0xf7)) { | |||||
| if ((data[0] != 0xf0) || (data[byte_count - 1] != 0xf7)) { | |||||
| jack_error("JackWinMMEInputPort::ProcessWinMME - Discarding " | jack_error("JackWinMMEInputPort::ProcessWinMME - Discarding " | ||||
| "%d-byte sysex chunk.", length1); | |||||
| "%d-byte sysex chunk.", byte_count); | |||||
| } else { | } else { | ||||
| EnqueueMessage(current_frame, length1, data); | |||||
| EnqueueMessage(current_frame, byte_count, data); | |||||
| } | } | ||||
| // Is this realtime-safe? This function isn't run in the JACK thread, | // Is this realtime-safe? This function isn't run in the JACK thread, | ||||
| // but we still want it to perform as quickly as possible. Even if | // but we still want it to perform as quickly as possible. Even if | ||||
| @@ -237,10 +254,10 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) | |||||
| MMRESULT result = midiInAddBuffer(handle, &sysex_header, | MMRESULT result = midiInAddBuffer(handle, &sysex_header, | ||||
| sizeof(MIDIHDR)); | sizeof(MIDIHDR)); | ||||
| if (result != MMSYSERR_NOERROR) { | if (result != MMSYSERR_NOERROR) { | ||||
| WriteInError("JackWinMMEInputPort::ProcessWinMME", "midiInAddBuffer", | |||||
| result); | |||||
| WriteInError("JackWinMMEInputPort::ProcessWinMME", | |||||
| "midiInAddBuffer", result); | |||||
| } | } | ||||
| break; | |||||
| break; | |||||
| } | } | ||||
| case MIM_LONGERROR: | case MIM_LONGERROR: | ||||
| jack_error("JackWinMMEInputPort::ProcessWinMME - Invalid or " | jack_error("JackWinMMEInputPort::ProcessWinMME - Invalid or " | ||||
| @@ -277,15 +294,6 @@ JackWinMMEInputPort::Stop() | |||||
| return ! started; | return ! started; | ||||
| } | } | ||||
| void | |||||
| JackWinMMEInputPort::GetInErrorString(MMRESULT error, LPTSTR text) | |||||
| { | |||||
| MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); | |||||
| if (result != MMSYSERR_NOERROR) { | |||||
| snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); | |||||
| } | |||||
| } | |||||
| void | void | ||||
| JackWinMMEInputPort::WriteInError(const char *jack_func, const char *mm_func, | JackWinMMEInputPort::WriteInError(const char *jack_func, const char *mm_func, | ||||
| MMRESULT result) | MMRESULT result) | ||||
| @@ -294,5 +302,3 @@ JackWinMMEInputPort::WriteInError(const char *jack_func, const char *mm_func, | |||||
| GetInErrorString(result, error_message); | GetInErrorString(result, error_message); | ||||
| jack_error("%s - %s: %s", jack_func, mm_func, error_message); | jack_error("%s - %s: %s", jack_func, mm_func, error_message); | ||||
| } | } | ||||