From 20831f45ea19094d2d12d4f00faba62d9e1169dd Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 08:55:11 -0700 Subject: [PATCH 01/13] Overhaul WinMME driver to use MIDI queue system. WARNING: I don't have a Windows development environment, and haven't compiled/tested this code. --- windows/winmme/JackWinMMEDriver.cpp | 549 ++++++++++-------------- windows/winmme/JackWinMMEDriver.h | 77 ++-- windows/winmme/JackWinMMEInputPort.cpp | 287 +++++++++++++ windows/winmme/JackWinMMEInputPort.h | 89 ++++ windows/winmme/JackWinMMEOutputPort.cpp | 352 +++++++++++++++ windows/winmme/JackWinMMEOutputPort.h | 93 ++++ 6 files changed, 1069 insertions(+), 378 deletions(-) create mode 100644 windows/winmme/JackWinMMEInputPort.cpp create mode 100644 windows/winmme/JackWinMMEInputPort.h create mode 100644 windows/winmme/JackWinMMEOutputPort.cpp create mode 100644 windows/winmme/JackWinMMEOutputPort.h diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index d3635c64..455118a2 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2009 Grame +Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,401 +18,285 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "JackWinMMEDriver.h" -#include "JackGraphManager.h" #include "JackEngineControl.h" -#include "JackDriverLoader.h" - -#include -#include -#include -#include - -#include -#include -#include +#include "JackWinMMEDriver.h" -namespace Jack -{ +using Jack::JackWinMMEDriver; -static bool InitHeaders(MidiSlot* slot) +JackWinMMEDriver::JackWinMMEDriver(const char *name, const char *alias, + JackLockedEngine *engine, + JackSynchro *table): + JackMidiDriver(name, alias, engine, table) { - slot->fHeader = (LPMIDIHDR)GlobalAllocPtr(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT, sizeof(MIDIHDR) + kBuffSize); - if (!slot->fHeader) - return false; - - slot->fHeader->lpData = (LPSTR)((LPBYTE)slot->fHeader + sizeof(MIDIHDR)); - slot->fHeader->dwBufferLength = kBuffSize; - slot->fHeader->dwFlags = 0; - slot->fHeader->dwUser = 0; - slot->fHeader->lpNext = 0; - slot->fHeader->dwBytesRecorded = 0; - return true; + fCaptureChannels = 0; + fPlaybackChannels = 0; + input_ports = 0; + output_ports = 0; } -void CALLBACK JackWinMMEDriver::MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD userData, DWORD dwParam1, DWORD dwParam2) +JackWinMMEDriver::~JackWinMMEDriver() { - jack_ringbuffer_t* ringbuffer = (jack_ringbuffer_t*)userData; - //jack_info("JackWinMMEDriver::MidiInProc 0\n"); - - switch (wMsg) { - case MIM_OPEN: - break; - - case MIM_ERROR: - case MIM_DATA: { - - //jack_info("JackWinMMEDriver::MidiInProc"); - - // One event - unsigned int num_packet = 1; - jack_ringbuffer_write(ringbuffer, (char*)&num_packet, sizeof(unsigned int)); - - // Write event actual data - jack_ringbuffer_write(ringbuffer, (char*)&dwParam1, 3); - break; - } - - case MIM_LONGERROR: - case MIM_LONGDATA: - /* - Nothing for now - */ - break; - } + Stop(); + Close(); } -JackWinMMEDriver::JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackMidiDriver(name, alias, engine, table), - fRealCaptureChannels(0), - fRealPlaybackChannels(0), - fMidiSource(NULL), - fMidiDestination(NULL) -{} - -JackWinMMEDriver::~JackWinMMEDriver() -{} - -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) +int +JackWinMMEDriver::Attach() { + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + jack_port_id_t index; + jack_nframes_t latency = buffer_size; + jack_latency_range_t latency_range; + const char *name; + JackPort *port; + latency_range.max = latency; + latency_range.min = latency; + + // Inputs + for (int i = 0; i < fCaptureChannels; i++) { + JackWinMMEInputPort *input_port = input_ports[i]; + name = input_port->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + CaptureDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackWinMMEDriver::Attach - cannot register input port " + "with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(input_port->GetAlias()); + port->SetLatencyRange(JackCaptureLatency, &latency_range); + fCapturePortList[i] = index; + } - 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); + if (! fEngineControl->fSyncMode) { + latency += buffer_size; + latency_range.max = latency; + latency_range.min = latency; + } - // Real input - int devindex = 0; - for (int i = 0; i < fRealCaptureChannels; i++) { + // Outputs + for (int i = 0; i < fPlaybackChannels; i++) { + JackWinMMEOutputPort *output_port = output_ports[i]; + name = output_port->GetName(); + index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, + JACK_DEFAULT_MIDI_TYPE, + PlaybackDriverFlags, buffer_size); + if (index == NO_PORT) { + jack_error("JackWinMMEDriver::Attach - cannot register output " + "port with name '%s'.", name); + // X: Do we need to deallocate ports? + return -1; + } + port = fGraphManager->GetPort(index); + port->SetAlias(output_port->GetAlias()); + port->SetLatencyRange(JackPlaybackLatency, &latency_range); + fPlaybackPortList[i] = index; + } - HMIDIIN handle; - fMidiDestination[devindex].fIndex = i; - MMRESULT ret = midiInOpen(&handle, fMidiDestination[devindex].fIndex, (DWORD)MidiInProc, (DWORD)fRingBuffer[devindex], CALLBACK_FUNCTION); + return 0; +} - 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; +int +JackWinMMEDriver::Close() +{ + int result = JackMidiDriver::Close(); + if (input_ports) { + for (int i = 0; i < fCaptureChannels; i++) { + delete input_ports[i]; } - devindex += 1; + delete[] input_ports; + input_ports = 0; } - 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; + if (output_ports) { + for (int i = 0; i < fPlaybackChannels; i++) { + delete output_ports[i]; } - devindex += 1; + delete[] output_ports; + output_ports = 0; } - fRealPlaybackChannels = devindex; - fPlaybackChannels = devindex; - return 0; + return result; } -void JackWinMMEDriver::CloseInput(MidiSlot* slot) +int +JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, + int out_channels, bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) { - 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"); + const char *client_name = fClientControl.fName; + int input_count = 0; + int num_potential_inputs = midiInGetNumDevs(); + int num_potential_outputs = midiOutGetNumDevs(); + int output_count = 0; + if (num_potential_inputs) { + try { + input_ports = new JackWinMMEInputPort *[num_potential_inputs]; + } catch (std::exception e) { + jack_error("JackWinMMEDriver::Open - while creating input port " + "array: %s", e.what()); + return -1; + } + for (int i = 0; i < num_potential_inputs; i++) { + try { + input_ports[input_count] = + new JackWinMMEInputPort(fAliasName, client_name, + capture_driver_name, i); + } catch (std::exception e) { + jack_error("JackWinMMEDriver::Open - while creating input " + "port: %s", e.what()); + continue; + } + input_count++; + } } - res = midiInReset(handle); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInReset error"); + if (num_potential_outputs) { + try { + output_ports = new JackWinMMEOutputPort *[num_potential_outputs]; + } catch (std::exception e) { + jack_error("JackWinMMEDriver::Open - while creating output port " + "array: %s", e.what()); + goto destroy_input_ports; + } + for (int i = 0; i < num_potential_outputs; i++) { + try { + output_ports[output_count] = + new JackWinMMEOutputPort(fAliasName, client_name, + playback_driver_name, i); + } catch (std::exception e) { + jack_error("JackWinMMEDriver::Open - while creating output " + "port: %s", e.what()); + continue; + } + output_count++; + } } - res = midiInUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInUnprepareHeader error"); + if (! (input_count || output_count)) { + jack_error("JackWinMMEDriver::Open - no WinMME inputs or outputs " + "allocated."); + } else if (! JackMidiDriver::Open(capturing, playing, input_count, + output_count, monitor, + capture_driver_name, + playback_driver_name, capture_latency, + playback_latency)) { + return 0; } - do { - res = midiInClose(handle); - if (res != MMSYSERR_NOERROR) { - jack_error("midiInClose error"); + + destroy_input_ports: + if (input_ports) { + for (int i = 0; i < input_count; i++) { + delete input_ports[i]; } - if (res == MIDIERR_STILLPLAYING) - midiInReset(handle); - Sleep (10); - retry++; - } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); - - if (slot->fHeader) { - GlobalFreePtr(slot->fHeader); + delete[] input_ports; + input_ports = 0; } + return -1; } -void JackWinMMEDriver::CloseOutput(MidiSlot* slot) +int +JackWinMMEDriver::Read() { - MMRESULT res; - int retry = 0; - - if (slot->fHandle == 0) - return; - - HMIDIOUT handle = (HMIDIOUT)slot->fHandle; - res = midiOutReset(handle); - if (res != MMSYSERR_NOERROR) - jack_error("midiOutReset error"); - midiOutUnprepareHeader(handle, slot->fHeader, sizeof(MIDIHDR)); - do { - res = midiOutClose(handle); - if (res != MMSYSERR_NOERROR) - jack_error("midiOutClose error"); - Sleep(10); - retry++; - } while ((res == MIDIERR_STILLPLAYING) && (retry < 10)); - - if (slot->fHeader) { - GlobalFreePtr(slot->fHeader); + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < fCaptureChannels; i++) { + input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); } + return 0; } -int JackWinMMEDriver::Close() +int +JackWinMMEDriver::Start() { - jack_log("JackWinMMEDriver::Close"); + jack_info("JackWinMMEDriver::Start - Starting driver."); + + JackMidiDriver::Start(); + + int input_count = 0; + int output_count = 0; - // Generic midi driver close - int res = JackMidiDriver::Close(); + jack_info("JackWinMMEDriver::Start - Enabling input ports."); - // Close input - if (fMidiDestination) { - for (int i = 0; i < fRealCaptureChannels; i++) { - CloseInput(&fMidiDestination[i]); + for (; input_count < fCaptureChannels; input_count++) { + if (input_ports[input_count]->Start() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to enable input " + "port."); + goto stop_input_ports; } - delete[] fMidiDestination; } - // Close output - if (fMidiSource) { - for (int i = 0; i < fRealPlaybackChannels; i++) { - CloseOutput(&fMidiSource[i]); + jack_info("JackWinMMEDriver::Start - Enabling output ports."); + + for (; output_count < fPlaybackChannels; output_count++) { + if (output_ports[output_count]->Start() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to enable output " + "port."); + goto stop_output_ports; } - delete[] fMidiSource; } - return res; -} + jack_info("JackWinMMEDriver::Start - Driver started."); -int JackWinMMEDriver::Attach() -{ - JackPort* port; - jack_port_id_t port_index; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - MMRESULT res; - int i; - - jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); - - for (i = 0; i < fCaptureChannels; i++) { - MIDIINCAPS caps; - res = midiInGetDevCaps(fMidiDestination[i].fIndex, &caps, sizeof(caps)); - if (res == MMSYSERR_NOERROR) { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); - } else { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); - } - snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); - - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { - jack_error("driver: cannot register port for %s", name); - return -1; + return 0; + + stop_output_ports: + for (int i = 0; i < output_count; i++) { + if (output_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to disable output " + "port."); } - port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); - fCapturePortList[i] = port_index; - jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index); } - - for (i = 0; i < fPlaybackChannels; i++) { - MIDIOUTCAPS caps; - res = midiOutGetDevCaps(fMidiSource[i].fIndex, &caps, sizeof(caps)); - if (res == MMSYSERR_NOERROR) { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, caps.szPname, i + 1); - } else { - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fPlaybackDriverName, i + 1); - } - snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); - - if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { - jack_error("driver: cannot register port for %s", name); - return -1; + stop_input_ports: + for (int i = 0; i < input_count; i++) { + if (input_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Start - Failed to disable input " + "port."); } - port = fGraphManager->GetPort(port_index); - port->SetAlias(alias); - fPlaybackPortList[i] = port_index; - jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); } - return 0; + return -1; } -int JackWinMMEDriver::Read() +int +JackWinMMEDriver::Stop() { - size_t size; + int result = 0; - for (int chan = 0; chan < fCaptureChannels; chan++) { + jack_info("JackWinMMEDriver::Stop - disabling input ports."); - if (fGraphManager->GetConnectionsNum(fCapturePortList[chan]) > 0) { - - JackMidiBuffer* midi_buffer = GetInputBuffer(chan); - - if (jack_ringbuffer_read_space (fRingBuffer[chan]) == 0) { - // Reset buffer - midi_buffer->Reset(midi_buffer->nframes); - } else { - - while ((size = jack_ringbuffer_read_space (fRingBuffer[chan])) > 0) { + for (int i = 0; i < fCaptureChannels; i++) { + if (input_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Stop - Failed to disable input " + "port."); + result = -1; + } + } - //jack_info("jack_ringbuffer_read_space %d", size); - int ev_count = 0; - jack_ringbuffer_read(fRingBuffer[chan], (char*)&ev_count, sizeof(int)); + jack_info("JackWinMMEDriver::Stop - disabling output ports."); - if (ev_count > 0) { - for (int j = 0; j < ev_count; j++) { - unsigned int event_len = 3; - // Read event actual data - jack_midi_data_t* dest = midi_buffer->ReserveEvent(0, event_len); - jack_ringbuffer_read(fRingBuffer[chan], (char*)dest, event_len); - } - } - } - } - } else { - //jack_info("Consume ring buffer"); - jack_ringbuffer_read_advance(fRingBuffer[chan], jack_ringbuffer_read_space(fRingBuffer[chan])); + for (int i = 0; i < fPlaybackChannels; i++) { + if (output_ports[i]->Stop() < 0) { + jack_error("JackWinMMEDriver::Stop - Failed to disable output " + "port."); + result = -1; } } - return 0; + + return result; } -int JackWinMMEDriver::Write() +int +JackWinMMEDriver::Write() { - for (int chan = 0; chan < fPlaybackChannels; chan++) { - - if (fGraphManager->GetConnectionsNum(fPlaybackPortList[chan]) > 0) { - - JackMidiBuffer* midi_buffer = GetOutputBuffer(chan); - - // TODO : use timestamp - - for (unsigned int j = 0; j < midi_buffer->event_count; j++) { - JackMidiEvent* ev = &midi_buffer->events[j]; - if (ev->size <= 3) { - jack_midi_data_t *d = ev->GetData(midi_buffer); - DWORD winev = 0; - if (ev->size > 0) winev |= d[0]; - if (ev->size > 1) winev |= (d[1] << 8); - if (ev->size > 2) winev |= (d[2] << 16); - MMRESULT res = midiOutShortMsg((HMIDIOUT)fMidiSource[chan].fHandle, winev); - if (res != MMSYSERR_NOERROR) - jack_error ("midiOutShortMsg error res %d", res); - } else { - - } - } - } + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < fPlaybackChannels; i++) { + output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); } - return 0; } -} // end of namespace - #ifdef __cplusplus extern "C" { diff --git a/windows/winmme/JackWinMMEDriver.h b/windows/winmme/JackWinMMEDriver.h index 6c28a0ef..52ae5f2b 100644 --- a/windows/winmme/JackWinMMEDriver.h +++ b/windows/winmme/JackWinMMEDriver.h @@ -1,5 +1,6 @@ /* Copyright (C) 2009 Grame +Copyright (C) 2011 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,67 +22,51 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define __JackWinMMEDriver__ #include "JackMidiDriver.h" -#include "JackTime.h" +#include "JackWinMMEInputPort.h" +#include "JackWinMMEOutputPort.h" -namespace Jack -{ +namespace Jack { -/*! -\brief The WinMME driver. -*/ - -#define kBuffSize 512 - -struct MidiSlot { - - LPVOID fHandle; // MMSystem handler - short fIndex; // MMSystem dev index - LPMIDIHDR fHeader; // for long msg output - - MidiSlot():fHandle(0),fIndex(0) - {} + class JackWinMMEDriver : public JackMidiDriver { -}; + private: -class JackWinMMEDriver : public JackMidiDriver -{ + JackWinMMEInputPort **input_ports; + JackWinMMEOutputPort **output_ports; - private: + public: - int fRealCaptureChannels; - int fRealPlaybackChannels; + JackWinMMEDriver(const char* name, const char* alias, + JackLockedEngine* engine, JackSynchro* table); - MidiSlot* fMidiSource; - MidiSlot* fMidiDestination; + ~JackWinMMEDriver(); - void CloseInput(MidiSlot* slot); - void CloseOutput(MidiSlot* slot); + int + Attach(); - static void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); + int + Close(); - public: + int + Open(bool capturing, bool playing, int num_inputs, int num_outputs, + bool monitor, const char* capture_driver_name, + const char* playback_driver_name, jack_nframes_t capture_latency, + jack_nframes_t playback_latency); - JackWinMMEDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table); - virtual ~JackWinMMEDriver(); + int + Read(); - int Open(bool capturing, - bool playing, - int chan_in, - int chan_out, - bool monitor, - const char* capture_driver_name, - const char* playback_driver_name, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency); - int Close(); + int + Start(); - int Attach(); + int + Stop(); - int Read(); - int Write(); + int + Write(); -}; + }; -} // end of namespace +} #endif diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp new file mode 100644 index 00000000..f5c74023 --- /dev/null +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -0,0 +1,287 @@ +/* +Copyright (C) 2011 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include + +#include "JackError.h" +#include "JackMidiUtil.h" +#include "JackWinMMEInputPort.h" + +using Jack::JackWinMMEInputPort; + +/////////////////////////////////////////////////////////////////////////////// +// Static callbacks +/////////////////////////////////////////////////////////////////////////////// + +void CALLBACK +JackWinMMEInputPort::HandleMidiInputEvent(HMIDIIN handle, UINT message, + DWORD port, DWORD param1, + DWORD param2) +{ + ((JackWinMMEInputPort *) port)->ProcessWinMME(message, param1, param2); +} + +/////////////////////////////////////////////////////////////////////////////// +// Class +/////////////////////////////////////////////////////////////////////////////// + +JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, + const char *client_name, + const char *driver_name, UINT index, + size_t max_bytes, size_t max_messages) +{ + thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); + std::auto_ptr thread_queue_ptr(thread_queue); + write_queue = new JackMidiBufferWriteQueue(); + std::auto_ptr write_queue_ptr(write_queue); + sysex_buffer = new jack_midi_data_t[max_bytes]; + char error_message[MAXERRORLENGTH]; + MMRESULT result = midiInOpen(&handle, index, HandleMidiInputEvent, this, + CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) { + GetErrorString(result, error_message); + goto delete_sysex_buffer; + } + sysex_header.dwBufferLength = max_bytes; + sysex_header.dwBytesRecorded = 0; + sysex_header.dwFlags = 0; + sysex_header.dwUser = 0; + sysex_header.lpData = (((LPBYTE) sysex_header) + sizeof(MIDIHDR)); + sysex_header.lpNext = 0; + result = midiInPrepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + GetErrorString(result, error_message); + goto close_handle; + } + result = midiInAddBuffer(handle, &sysex_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + GetErrorString(result, error_message); + goto unprepare_header; + } + + jack_event = 0; + started = false; + write_queue_ptr.release(); + thread_queue_ptr.release(); + return; + + unprepare_header: + result = midiInUnprepareHeader(handle, sysex_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [constructor]", + "midiInUnprepareHeader", result); + } + close_handle: + result = midiInClose(handle); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [constructor]", "midiInClose", result); + } + delete_sysex_buffer: + delete[] sysex_buffer; + throw std::runtime_error(error_message); +} + +JackWinMMEInputPort::~JackWinMMEInputPort() +{ + Stop(); + MMRESULT result = midiInReset(handle); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [destructor]", "midiInReset", result); + } + result = midiInUnprepareHeader(handle, sysex_header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", + result); + } + result = midiInClose(handle); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [destructor]", "midiInClose", result); + } + delete[] sysex_buffer; + delete thread_queue; + delete write_queue; +} + +void +JackWinMMEInputPort::EnqueueMessage(jack_nframes_t time, size_t length, + jack_midi_data_t *data) +{ + switch (thread_queue->EnqueueEvent(time, length, data)) { + case JackMidiWriteQueue::BUFFER_FULL: + jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " + "cannot currently accept a %d-byte event. Dropping event.", + size); + break; + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " + "buffer is too small to enqueue a %d-byte event. Dropping " + "event.", size); + break; + default: + ; + } +} + +const char * +JackWinMMEInputPort::GetAlias() +{ + return alias; +} + +void +JackWinMMEInputPort::GetErrorString(MMRESULT error, LPTSTR text) +{ + MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); + } +} + +const char * +JackWinMMEInputPort::GetName() +{ + return name; +} + +void +JackWinMMEInputPort::ProcessJack() +{ + write_queue->ResetMidiBuffer(port_buffer, frames); + if (! jack_event) { + jack_event = thread_queue->DequeueEvent(); + } + for (; jack_event; jack_event = thread_queue->DequeueEvent()) { + switch (write_queue->EnqueueEvent(event)) { + case BUFFER_TOO_SMALL: + jack_error("JackWinMMEMidiInputPort::Process - The buffer write " + "queue couldn't enqueue a %d-byte event. Dropping " + "event.", event->size); + // Fallthrough on purpose + case OK: + continue; + } + break; + } +} + +void +JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) +{ + jack_nframes_t current_frame = GetCurrentFrame(); + switch (message) { + case MIM_CLOSE: + jack_info("JackWinMMEInputPort::ProcessWinMME - MIDI device closed."); + break; + case MIM_MOREDATA: + jack_info("JackWinMMEInputPort::ProcessWinMME - The MIDI input device " + "driver thinks that JACK is not processing messages fast " + "enough."); + // Fallthrough on purpose. + case MIM_DATA: + jack_midi_data_t message_buffer[3]; + jack_midi_data_t status = param1 & 0xff; + int length = GetMessageLength(status); + switch (length) { + case 3: + message_buffer[2] = param1 & 0xff0000; + // Fallthrough on purpose. + case 2: + message_buffer[1] = param1 & 0xff00; + // Fallthrough on purpose. + case 1: + message_buffer[0] = status; + break; + case 0: + jack_error("JackWinMMEInputPort::ProcessWinMME - **BUG** MIDI " + "input driver sent an MIM_DATA message with a sysex " + "status byte."); + return; + case -1: + jack_error("JackWinMMEInputPort::ProcessWinMME - **BUG** MIDI " + "input driver sent an MIM_DATA message with an invalid " + "status byte."); + return; + } + EnqueueMessage(current_frame, (size_t) length, message_buffer); + break; + case MIM_LONGDATA: + LPMIDIHDR header = (LPMIDIHDR) dwParam1; + jack_midi_data_t *data = (jack_midi_data_t *) header->lpData; + size_t length = header->dwBytesRecorded; + if ((data[0] != 0xf0) || (data[length - 1] != 0xf7)) { + jack_error("JackWinMMEInputPort::ProcessWinMME - Discarding " + "%d-byte sysex chunk.", length); + } else { + EnqueueMessage(current_frame, length, data); + } + // 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 + // this isn't realtime safe, it may not be avoidable. + MMRESULT result = midiInAddBuffer(handle, &sysex_header, + sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort::ProcessWinMME", "midiInAddBuffer", + result); + } + break; + case MIM_LONGERROR: + jack_error("JackWinMMEInputPort::ProcessWinMME - Invalid or " + "incomplete sysex message received."); + break; + case MIM_OPEN: + jack_info("JackWinMMEInputPort::ProcessWinMME - MIDI device opened."); + } +} + +bool +JackWinMMEInputPort::Start() +{ + if (! started) { + MMRESULT result = midiInStart(handle); + started = result == MMSYSERR_NOERROR; + if (! started) { + WriteError("JackWinMMEInputPort::Start", "midiInStart", result); + } + } + return started; +} + +bool +JackWinMMEInputPort::Stop() +{ + if (started) { + MMRESULT result = midiInStop(handle); + started = result != MMSYSERR_NOERROR; + if (started) { + WriteError("JackWinMMEInputPort::Stop", "midiInStop", result); + } + } + return ! started; +} + +void +JackWinMMEInputPort::WriteError(const char *jack_func, const char *mm_func, + MMRESULT result) +{ + const char error_message[MAXERRORLENGTH]; + GetErrorString(result, error_message); + jack_error("%s - %s: %s", jack_func, mm_func, error_message); +} diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h new file mode 100644 index 00000000..5ce042b9 --- /dev/null +++ b/windows/winmme/JackWinMMEInputPort.h @@ -0,0 +1,89 @@ +/* +Copyright (C) 2011 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __JackWinMMEInputPort__ +#define __JackWinMMEInputPort__ + +#include + +#include "JackMidiAsyncQueue.h" +#include "JackMidiBufferWriteQueue.h" + +namespace Jack { + + class JackWinMMEInputPort { + + private: + + static void CALLBACK + HandleMidiInputEvent(HMIDIIN handle, UINT message, DWORD port, + DWORD param1, DWORD param2); + + void + EnqueueMessage(jack_nframes_t time, size_t length, + jack_midi_data_t *data); + + void + GetErrorString(MMRESULT error, LPTSTR text); + + void + ProcessWinMME(UINT message, DWORD param1, DWORD param2); + + void + WriteError(const char *jack_func, const char *mm_func, + MMRESULT result); + + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + HMIDIIN handle; + jack_midi_event_t *jack_event; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + bool started; + jack_midi_data_t *sysex_buffer; + MIDIHDR sysex_header + JackMidiAsyncQueue *thread_queue; + JackMidiBufferWriteQueue *write_queue; + + public: + + JackWinMMEInputPort(const char *alias_name, const char *client_name, + const char *driver_name, UINT index, + size_t max_bytes=4096, size_t max_messages=1024); + + ~JackWinMMEInputPort(); + + const char * + GetAlias(); + + const char * + GetName(); + + void + ProcessJack(); + + bool + Start(); + + bool + Stop(); + + }; + +} + +#endif diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp new file mode 100644 index 00000000..8f25feaf --- /dev/null +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -0,0 +1,352 @@ +/* +Copyright (C) 2011 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include + +#include "JackMidiUtil.h" +#include "JackTime.h" +#include "JackWinMMEOutputPort.h" + +using Jack::JackWinMMEOutputPort; + +/////////////////////////////////////////////////////////////////////////////// +// Static callbacks +/////////////////////////////////////////////////////////////////////////////// + +void CALLBACK +JackWinMMEOutputPort::HandleMessageEvent(HMIDIOUT handle, UINT message, + DWORD_PTR port, DWORD_PTR param1, + DWORD_PTR param2) +{ + ((JackWinMMEOutputPort *) port)->HandleMessage(message, param1, param2); +} + +/////////////////////////////////////////////////////////////////////////////// +// Class +/////////////////////////////////////////////////////////////////////////////// + +JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, + const char *client_name, + const char *driver_name, UINT index, + size_t max_bytes, + size_t max_messages) +{ + read_queue = new JackMidiBufferReadQueue(); + std::auto_ptr read_queue_ptr(read_queue); + thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); + std::auto_ptr thread_queue_ptr(thread_queue); + char error_message[MAXERRORLENGTH]; + MMRESULT result = midiOutOpen(&handle, index, HandleMessageEvent, this, + CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) { + GetErrorString(result, error_message); + goto raise_exception; + } + thread_queue_semaphore = CreateSemaphore(NULL, 0, max_messages, NULL); + if (thread_queue_semaphore == NULL) { + GetOSErrorString(error_message); + goto close_handle; + } + sysex_semaphore = CreateSemaphore(NULL, 0, 1, NULL); + if (sysex_semaphore == NULL) { + GetOSErrorString(error_message); + goto destroy_thread_queue_semaphore; + } + MIDIINCAPS capabilities; + char *name; + result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", + result); + name = driver_name; + } else { + name = capabilities.szPname; + } + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, driver_name, + index + 1); + snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); + write_queue_ptr.release(); + thread_queue_ptr.release(); + return; + + destroy_thread_queue_semaphore: + if (! CloseHandle(thread_queue_semaphore)) { + WriteOSError("JackWinMMEOutputPort [constructor]", "CloseHandle"); + } + close_handle: + result = midiOutClose(handle); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutClose", + result); + } + raise_exception: + throw std::runtime_error(error_message); +} + +JackWinMMEOutputPort::~JackWinMMEOutputPort() +{ + Stop(); + MMRESULT result = midiOutReset(handle); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [destructor]", "midiOutReset", + result); + } + result = midiOutClose(handle); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [destructor]", "midiOutClose", + result); + } + if (! CloseHandle(sysex_semaphore)) { + WriteOSError("JackWinMMEOutputPort [destructor]", "CloseHandle"); + } + if (! CloseHandle(thread_queue_semaphore)) { + WriteOSError("JackWinMMEOutputPort [destructor]", "CloseHandle"); + } + delete read_queue; + delete thread_queue; +} + +bool +JackWinMMEOutputPort::Execute() +{ + for (;;) { + if (! Wait(thread_queue_semaphore)) { + break; + } + jack_midi_event_t *event = thread_queue->DequeueEvent(); + if (! event) { + break; + } + jack_time_t frame_time = GetTimeFromFrames(event->time); + for (jack_time_t current_time = GetMicroSeconds(); + frame_time > current_time; current_time = GetMicroSeconds()) { + jack_time_t sleep_time = frame_time - current_time; + + // Windows has a millisecond sleep resolution for its Sleep calls. + // This is unfortunate, as MIDI timing often requires a higher + // resolution. For now, we attempt to compensate by letting an + // event be sent if we're less than 500 microseconds from sending + // the event. We assume that it's better to let an event go out + // 499 microseconds early than let an event go out 501 microseconds + // late. Of course, that's assuming optimal sleep times, which is + // a whole different Windows issue ... + if (sleep_time < 500) { + break; + } + + if (sleep_time < 1000) { + sleep_time = 1000; + } + JackSleep(sleep_time); + } + jack_midi_data_t *data = event->buffer; + DWORD message = 0; + MMRESULT result; + size_t size = event->size; + switch (size) { + case 3: + message |= (((DWORD) data[2]) << 16); + // Fallthrough on purpose. + case 2: + message |= (((DWORD) data[1]) << 8); + // Fallthrough on purpose. + case 1: + message |= (DWORD) data[0]; + result = midiOutShortMsg(handle, message); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort::Execute", + "midiOutShortMsg", result); + } + continue; + } + MIDIHDR header; + header.dwFlags = 0; + header.dwLength = size; + header.lpData = data; + result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort::Execute", + "midiOutPrepareHeader", result); + continue; + } + result = midiOutLongMsg(handle, &header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort::Execute", "midiOutLongMsg", + result); + continue; + } + + // System exclusive messages may be sent synchronously or + // asynchronously. The choice is up to the WinMME driver. So, we wait + // until the message is sent, regardless of the driver's choice. + if (! Wait(sysex_semaphore)) { + break; + } + + result = midiOutUnprepareHeader(handle, &header, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort::Execute", + "midiOutUnprepareHeader", result); + break; + } + } + stop_execution: + return false; +} + +void +JackWinMMEOutputPort::GetMMErrorString(MMRESULT error, LPTSTR text) +{ + MMRESULT result = midiOutGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown MM error code '%d'", error); + } +} + +void +JackWinMMEOutputPort::GetOSErrorString(LPTSTR text) +{ + DWORD error = GetLastError(); + if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &text, + MAXERRORLENGTH, NULL)) { + snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); + } +} + +void +JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, + DWORD_PTR param2) +{ + switch (message) { + case MOM_CLOSE: + jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device closed."); + break; + case MOM_DONE: + if (! ReleaseSemaphore(sysex_semaphore, 1, NULL)) { + WriteOSError("JackWinMMEOutputPort::HandleMessage", + "ReleaseSemaphore"); + } + break; + case MOM_OPEN: + jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device opened."); + } +} + +bool +JackWinMMEOutputPort::Init() +{ + set_threaded_log_function(); + // XX: Can more be done? Ideally, this thread should have the JACK server + // thread priority + 1. + if (thread->AcquireSelfRealTime()) { + jack_error("JackWinMMEOutputPort::Init - could not acquire realtime " + "scheduling. Continuing anyway."); + } + return true; +} + +void +JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, + jack_nframes_t frames) +{ + read_queue->ResetMidiBuffer(port_buffer); + for (jack_midi_event_t *event = read_queue->DequeueEvent(); event; + event = read_queue->DequeueEvent()) { + switch (thread_queue->EnqueueEvent(event, frames)) { + case JackMidiWriteQueue::BUFFER_FULL: + jack_error("JackWinMMEOutputPort::ProcessJack - The thread queue " + "buffer is full. Dropping event."); + break; + case JackMidiWriteQueue::BUFFER_TOO_SMALL: + jack_error("JackWinMMEOutputPort::ProcessJack - The thread queue " + "couldn't enqueue a %d-byte event. Dropping event.", + event->size); + break; + default: + if (! ReleaseSemaphore(thread_queue_semaphore, 1, NULL)) { + WriteOSError("JackWinMMEOutputPort::ProcessJack", + "ReleaseSemaphore"); + } + } + } +} + +bool +JackWinMMEOutputPort::Start() +{ + bool result = thread->GetStatus() != JackThread::kIdle; + if (! result) { + result = ! thread->StartSync(); + if (! result) { + jack_error("JackWinMMEOutputPort::Start - failed to start MIDI " + "processing thread."); + } + } + return result; +} + +bool +JackWinMMEOutputPort::Stop() +{ + bool result = thread->GetStatus() == JackThread::kIdle; + if (! result) { + result = ! thread->Kill(); + if (! result) { + jack_error("JackWinMMEOutputPort::Stop - failed to stop MIDI " + "processing thread."); + } + } + return result; +} + +bool +JackWinMMEOutputPort::Wait(Handle semaphore) +{ + DWORD result = WaitForSingleObject(semaphore, INFINITE); + switch (result) { + case WAIT_FAILED: + WriteOSError("JackWinMMEOutputPort::Wait", "WaitForSingleObject"); + break; + case WAIT_OBJECT_0: + return true; + default: + jack_error("JackWinMMEOutputPort::Wait - unexpected result from " + "'WaitForSingleObject'."); + } + return false; +} + +void +JackWinMMEOutputPort::WriteMMError(const char *jack_func, const char *mm_func, + MMRESULT result) +{ + const char error_message[MAXERRORLENGTH]; + GetMMErrorString(result, error_message); + jack_error("%s - %s: %s", jack_func, mm_func, error_message); +} + +void +JackWinMMEOutputPort::WriteOSError(const char *jack_func, const char *os_func) +{ + const char error_message[MAXERRORLENGTH]; + GetOSErrorString(result, error_message); + jack_error("%s - %s: %s", jack_func, os_func, error_message); +} diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h new file mode 100644 index 00000000..8da32066 --- /dev/null +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -0,0 +1,93 @@ +/* +Copyright (C) 2011 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __JackWinMMEOutputPort__ +#define __JackWinMMEOutputPort__ + +#include +#include + +#include "JackMidiAsyncQueue.h" +#include "JackMidiBufferReadQueue.h" + +namespace Jack { + + class JackWinMMEOutputPort { + + private: + + static void CALLBACK + HandleMessageEvent(HMIDIOUT handle, UINT message, DWORD_PTR port, + DWORD_PTR param1, DWORD_PTR param2); + + void + GetMMErrorString(MMRESULT error, LPTSTR text); + + void + GetOSErrorString(LPTSTR text); + + void + HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); + + bool + Wait(Handle semaphore); + + void + WriteMMError(const char *jack_func, const char *mm_func, + MMRESULT result); + + void + WriteOSError(const char *jack_func, const char *os_func); + + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + HMIDIOUT handle; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + JackMidiBufferReadQueue *read_queue; + HANDLE sysex_semaphore; + JackMidiAsyncQueue *thread_queue; + HANDLE thread_queue_semaphore; + + public: + + JackWinMMEOutputPort(const char *alias_name, const char *client_name, + const char *driver_name, UINT index, + size_t max_bytes=4096, size_t max_messages=1024); + + ~JackWinMMEOutputPort(); + + bool + Execute(); + + bool + Init(); + + void + ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); + + bool + Start(); + + bool + Stop(); + + }; + +} + +#endif From 8c7cabfe3dd13df72a2ed6fc1f39f606d3c1b64d Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 09:41:28 -0700 Subject: [PATCH 02/13] Add missing thread functionality to JackWinMMEOutputPort. --- windows/winmme/JackWinMMEOutputPort.cpp | 3 +++ windows/winmme/JackWinMMEOutputPort.h | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 8f25feaf..7c6789f8 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -52,6 +52,8 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, std::auto_ptr read_queue_ptr(read_queue); thread_queue = new JackMidiAsyncQueue(max_bytes, max_messages); std::auto_ptr thread_queue_ptr(thread_queue); + thread = new JackThread(this); + std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; MMRESULT result = midiOutOpen(&handle, index, HandleMessageEvent, this, CALLBACK_FUNCTION); @@ -82,6 +84,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, driver_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); + thread_ptr.release(); write_queue_ptr.release(); thread_queue_ptr.release(); return; diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index 8da32066..ef1bd65d 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -25,10 +25,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackMidiAsyncQueue.h" #include "JackMidiBufferReadQueue.h" +#include "JackThread.h" namespace Jack { - class JackWinMMEOutputPort { + class JackWinMMEOutputPort: public JackRunnableInterface { private: @@ -60,6 +61,7 @@ namespace Jack { char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; JackMidiBufferReadQueue *read_queue; HANDLE sysex_semaphore; + JackThread *thread; JackMidiAsyncQueue *thread_queue; HANDLE thread_queue_semaphore; From 194ce1cd57d30a92669159fd5bf59fcd9a900cd0 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 11:15:39 -0700 Subject: [PATCH 03/13] Make sure threaded log functions are set. Add MOM_POSITIONCB info. --- windows/winmme/JackWinMMEInputPort.cpp | 3 ++- windows/winmme/JackWinMMEOutputPort.cpp | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index f5c74023..c9b9cbb1 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -55,7 +55,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; MMRESULT result = midiInOpen(&handle, index, HandleMidiInputEvent, this, - CALLBACK_FUNCTION); + CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { GetErrorString(result, error_message); goto delete_sysex_buffer; @@ -185,6 +185,7 @@ JackWinMMEInputPort::ProcessJack() void JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) { + set_threaded_log_function(); jack_nframes_t current_frame = GetCurrentFrame(); switch (message) { case MIM_CLOSE: diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 7c6789f8..3e615742 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -180,8 +180,11 @@ JackWinMMEOutputPort::Execute() continue; } MIDIHDR header; + header.dwBufferLength = size; + header.dwBytesRecorded = size; header.dwFlags = 0; - header.dwLength = size; + header.dwOffset = 0; + header.dwUser = 0; header.lpData = data; result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { @@ -238,6 +241,7 @@ void JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2) { + set_threaded_log_function(); switch (message) { case MOM_CLOSE: jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device closed."); @@ -250,6 +254,12 @@ JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, break; case MOM_OPEN: jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device opened."); + break; + case MOM_POSITIONCB: + LPMIDIHDR header = (LPMIDIHDR) param2; + jack_info("JackWinMMEOutputPort::HandleMessage - %d bytes out of %d " + "bytes of the current sysex message have been sent.", + header->dwOffset, header->dwBytesRecorded); } } From 8e4ee25c7f9e6a8a18b25fbe6e9c5c2f43c40a93 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Tue, 29 Mar 2011 11:27:21 -0700 Subject: [PATCH 04/13] Make thread termination more elegant. --- windows/winmme/JackWinMMEOutputPort.cpp | 52 +++++++++++++++++-------- windows/winmme/JackWinMMEOutputPort.h | 3 ++ 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 3e615742..aa87de0f 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -247,10 +247,7 @@ JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device closed."); break; case MOM_DONE: - if (! ReleaseSemaphore(sysex_semaphore, 1, NULL)) { - WriteOSError("JackWinMMEOutputPort::HandleMessage", - "ReleaseSemaphore"); - } + Signal(sysex_semaphore); break; case MOM_OPEN: jack_info("JackWinMMEOutputPort::HandleMessage - MIDI device opened."); @@ -294,14 +291,21 @@ JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, event->size); break; default: - if (! ReleaseSemaphore(thread_queue_semaphore, 1, NULL)) { - WriteOSError("JackWinMMEOutputPort::ProcessJack", - "ReleaseSemaphore"); - } + Signal(thread_queue_semaphore); } } } +bool +JackWinMMEOutputPort::Signal(Handle semaphore) +{ + bool result = (bool) ReleaseSemaphore(semaphore, 1, NULL); + if (! result) { + WriteOSError("JackWinMMEOutputPort::Signal", "ReleaseSemaphore"); + } + return result; +} + bool JackWinMMEOutputPort::Start() { @@ -319,15 +323,31 @@ JackWinMMEOutputPort::Start() bool JackWinMMEOutputPort::Stop() { - bool result = thread->GetStatus() == JackThread::kIdle; - if (! result) { - result = ! thread->Kill(); - if (! result) { - jack_error("JackWinMMEOutputPort::Stop - failed to stop MIDI " - "processing thread."); - } + + jack_info("JackWinMMEOutputPort::Stop - stopping MIDI output port " + "processing thread."); + + int result; + const char *verb; + switch (thread->GetStatus()) { + case JackThread::kIniting: + case JackThread::kStarting: + result = thread->Kill(); + verb = "kill"; + break; + case JackThread::kRunning: + Signal(thread_queue_semaphore); + result = thread->Stop(); + verb = "stop"; + break; + default: + return true; } - return result; + if (result) { + jack_error("JackWinMMEOutputPort::Stop - could not %s MIDI processing " + "thread.", verb); + } + return ! result; } bool diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index ef1bd65d..1033ec3e 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -46,6 +46,9 @@ namespace Jack { void HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); + bool + Signal(Handle semaphore); + bool Wait(Handle semaphore); From 69c59f4423ce79f41444479f5dde8dbc8ba977db Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 11:34:58 +0200 Subject: [PATCH 05/13] Renaming for Windows compatibility. --- common/JackMidiWriteQueue.h | 4 ++-- linux/alsarawmidi/JackALSARawMidiSendQueue.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/JackMidiWriteQueue.h b/common/JackMidiWriteQueue.h index a39776c9..f21a58ff 100644 --- a/common/JackMidiWriteQueue.h +++ b/common/JackMidiWriteQueue.h @@ -37,7 +37,7 @@ namespace Jack { BUFFER_FULL, BUFFER_TOO_SMALL, EVENT_EARLY, - ERROR, + EN_ERROR, OK }; @@ -54,7 +54,7 @@ namespace Jack { * if the write queue isn't able to accept the event right now, * `BUFFER_TOO_SMALL` if this write queue will never be able to accept * the event because the event is too large, `EVENT_EARLY` if this - * queue cannot schedule events ahead of time, and `ERROR` if an error + * queue cannot schedule events ahead of time, and `EN_ERROR` if an error * occurs that cannot be specified by another return code. */ diff --git a/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp b/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp index 5f314263..80a11b56 100755 --- a/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp +++ b/linux/alsarawmidi/JackALSARawMidiSendQueue.cpp @@ -30,7 +30,7 @@ JackALSARawMidiSendQueue::EnqueueEvent(jack_nframes_t time, size_t size, } jack_error("JackALSARawMidiSendQueue::EnqueueEvent - snd_rawmidi_write: " "%s", snd_strerror(result)); - return ERROR; + return EN_ERROR; } bool From 07f7895991345ac8a0b66d271052d9c145e8cb6f Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 13:16:19 +0200 Subject: [PATCH 06/13] New driver compiles. --- windows/jack_winmme.cbp | 11 +++++ windows/jackd.workspace | 4 +- windows/libjackserver.cbp | 2 - windows/portaudio/JackPortAudioDriver.cpp | 2 +- windows/winmme/JackWinMMEInputPort.cpp | 33 +++++++------- windows/winmme/JackWinMMEInputPort.h | 4 +- windows/winmme/JackWinMMEOutputPort.cpp | 52 +++++++++++++++++------ windows/winmme/JackWinMMEOutputPort.h | 16 +++++-- 8 files changed, 85 insertions(+), 39 deletions(-) diff --git a/windows/jack_winmme.cbp b/windows/jack_winmme.cbp index 2c6d8bbe..7de61fa8 100644 --- a/windows/jack_winmme.cbp +++ b/windows/jack_winmme.cbp @@ -102,10 +102,21 @@ + + + + + + + + + + + diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 05f5b3d1..4384140e 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -5,7 +5,7 @@ - + @@ -57,6 +57,6 @@ - + diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index e4db2136..89cd2dd3 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -154,8 +154,6 @@ - - diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index 790bcda1..f7611add 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -248,7 +248,7 @@ error: } else { JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails // PortAudio specific - UpdateLatencies(); + JackAudioDriver::UpdateLatencies(); return 0; } } diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index c9b9cbb1..0adf3bec 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackError.h" #include "JackMidiUtil.h" #include "JackWinMMEInputPort.h" +#include "JackMidiWriteQueue.h" using Jack::JackWinMMEInputPort; @@ -54,7 +55,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, std::auto_ptr write_queue_ptr(write_queue); sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; - MMRESULT result = midiInOpen(&handle, index, HandleMidiInputEvent, this, + MMRESULT result = midiInOpen(&handle, index, (DWORD)HandleMidiInputEvent, (DWORD)this, CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { GetErrorString(result, error_message); @@ -64,7 +65,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, sysex_header.dwBytesRecorded = 0; sysex_header.dwFlags = 0; sysex_header.dwUser = 0; - sysex_header.lpData = (((LPBYTE) sysex_header) + sizeof(MIDIHDR)); + sysex_header.lpData = (LPSTR)(((LPBYTE) &sysex_header) + sizeof(MIDIHDR)); sysex_header.lpNext = 0; result = midiInPrepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { @@ -84,7 +85,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, return; unprepare_header: - result = midiInUnprepareHeader(handle, sysex_header, sizeof(MIDIHDR)); + result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteError("JackWinMMEInputPort [constructor]", "midiInUnprepareHeader", result); @@ -106,7 +107,7 @@ JackWinMMEInputPort::~JackWinMMEInputPort() if (result != MMSYSERR_NOERROR) { WriteError("JackWinMMEInputPort [destructor]", "midiInReset", result); } - result = midiInUnprepareHeader(handle, sysex_header, sizeof(MIDIHDR)); + result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", result); @@ -128,12 +129,12 @@ JackWinMMEInputPort::EnqueueMessage(jack_nframes_t time, size_t length, case JackMidiWriteQueue::BUFFER_FULL: jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " "cannot currently accept a %d-byte event. Dropping event.", - size); + length); break; case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEInputPort::EnqueueMessage - The thread queue " "buffer is too small to enqueue a %d-byte event. Dropping " - "event.", size); + "event.", length); break; default: ; @@ -162,20 +163,20 @@ JackWinMMEInputPort::GetName() } void -JackWinMMEInputPort::ProcessJack() +JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { write_queue->ResetMidiBuffer(port_buffer, frames); if (! jack_event) { jack_event = thread_queue->DequeueEvent(); } for (; jack_event; jack_event = thread_queue->DequeueEvent()) { - switch (write_queue->EnqueueEvent(event)) { - case BUFFER_TOO_SMALL: + switch (write_queue->EnqueueEvent(jack_event)) { + case JackMidiWriteQueue::BUFFER_TOO_SMALL: jack_error("JackWinMMEMidiInputPort::Process - The buffer write " "queue couldn't enqueue a %d-byte event. Dropping " - "event.", event->size); + "event.", jack_event->size); // Fallthrough on purpose - case OK: + case JackMidiWriteQueue::OK: continue; } break; @@ -224,14 +225,14 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) EnqueueMessage(current_frame, (size_t) length, message_buffer); break; case MIM_LONGDATA: - LPMIDIHDR header = (LPMIDIHDR) dwParam1; + LPMIDIHDR header = (LPMIDIHDR) param1; jack_midi_data_t *data = (jack_midi_data_t *) header->lpData; - size_t length = header->dwBytesRecorded; - if ((data[0] != 0xf0) || (data[length - 1] != 0xf7)) { + size_t length1 = header->dwBytesRecorded; + if ((data[0] != 0xf0) || (data[length1 - 1] != 0xf7)) { jack_error("JackWinMMEInputPort::ProcessWinMME - Discarding " "%d-byte sysex chunk.", length); } else { - EnqueueMessage(current_frame, length, data); + EnqueueMessage(current_frame, length1, data); } // 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 @@ -282,7 +283,7 @@ void JackWinMMEInputPort::WriteError(const char *jack_func, const char *mm_func, MMRESULT result) { - const char error_message[MAXERRORLENGTH]; + char error_message[MAXERRORLENGTH]; GetErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h index 5ce042b9..dd4c53f1 100644 --- a/windows/winmme/JackWinMMEInputPort.h +++ b/windows/winmme/JackWinMMEInputPort.h @@ -55,7 +55,7 @@ namespace Jack { char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; bool started; jack_midi_data_t *sysex_buffer; - MIDIHDR sysex_header + MIDIHDR sysex_header; JackMidiAsyncQueue *thread_queue; JackMidiBufferWriteQueue *write_queue; @@ -74,7 +74,7 @@ namespace Jack { GetName(); void - ProcessJack(); + ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); bool Start(); diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index aa87de0f..eb9ba49e 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -55,7 +55,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, thread = new JackThread(this); std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; - MMRESULT result = midiOutOpen(&handle, index, HandleMessageEvent, this, + MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, (DWORD)this, CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { GetErrorString(result, error_message); @@ -71,22 +71,24 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, GetOSErrorString(error_message); goto destroy_thread_queue_semaphore; } - MIDIINCAPS capabilities; - char *name; + MIDIOUTCAPS capabilities; + char *name_tmp; result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); + /* + Devin : FIXME if (result != MMSYSERR_NOERROR) { WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); - name = driver_name; + name_tmp = driver_name; } else { - name = capabilities.szPname; + name_tmp = capabilities.szPname; } + */ snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, driver_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); thread_ptr.release(); - write_queue_ptr.release(); - thread_queue_ptr.release(); + thread_queue_ptr.release(); return; destroy_thread_queue_semaphore: @@ -185,7 +187,7 @@ JackWinMMEOutputPort::Execute() header.dwFlags = 0; header.dwOffset = 0; header.dwUser = 0; - header.lpData = data; + header.lpData = (LPSTR)data; result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { WriteMMError("JackWinMMEOutputPort::Execute", @@ -230,11 +232,14 @@ void JackWinMMEOutputPort::GetOSErrorString(LPTSTR text) { DWORD error = GetLastError(); + /* + Devin: FIXME if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &text, MAXERRORLENGTH, NULL)) { snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); } + */ } void @@ -297,7 +302,7 @@ JackWinMMEOutputPort::ProcessJack(JackMidiBuffer *port_buffer, } bool -JackWinMMEOutputPort::Signal(Handle semaphore) +JackWinMMEOutputPort::Signal(HANDLE semaphore) { bool result = (bool) ReleaseSemaphore(semaphore, 1, NULL); if (! result) { @@ -351,7 +356,7 @@ JackWinMMEOutputPort::Stop() } bool -JackWinMMEOutputPort::Wait(Handle semaphore) +JackWinMMEOutputPort::Wait(HANDLE semaphore) { DWORD result = WaitForSingleObject(semaphore, INFINITE); switch (result) { @@ -371,7 +376,7 @@ void JackWinMMEOutputPort::WriteMMError(const char *jack_func, const char *mm_func, MMRESULT result) { - const char error_message[MAXERRORLENGTH]; + char error_message[MAXERRORLENGTH]; GetMMErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } @@ -379,7 +384,28 @@ JackWinMMEOutputPort::WriteMMError(const char *jack_func, const char *mm_func, void JackWinMMEOutputPort::WriteOSError(const char *jack_func, const char *os_func) { - const char error_message[MAXERRORLENGTH]; - GetOSErrorString(result, error_message); + char error_message[MAXERRORLENGTH]; + // Devin : FIXME + //GetOSErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, os_func, error_message); } + +const char * +JackWinMMEOutputPort::GetAlias() +{ + return alias; +} +const char * +JackWinMMEOutputPort::GetName() +{ + return name; +} + +void +JackWinMMEOutputPort::GetErrorString(MMRESULT error, LPTSTR text) +{ + MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); + } +} diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index 1033ec3e..c343ff55 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -47,10 +47,10 @@ namespace Jack { HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); bool - Signal(Handle semaphore); + Signal(HANDLE semaphore); bool - Wait(Handle semaphore); + Wait(HANDLE semaphore); void WriteMMError(const char *jack_func, const char *mm_func, @@ -60,14 +60,18 @@ namespace Jack { WriteOSError(const char *jack_func, const char *os_func); char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - HMIDIOUT handle; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + + HMIDIOUT handle; JackMidiBufferReadQueue *read_queue; HANDLE sysex_semaphore; JackThread *thread; JackMidiAsyncQueue *thread_queue; HANDLE thread_queue_semaphore; + void + GetErrorString(MMRESULT error, LPTSTR text); + public: JackWinMMEOutputPort(const char *alias_name, const char *client_name, @@ -91,6 +95,12 @@ namespace Jack { bool Stop(); + const char * + GetAlias(); + + const char * + GetName(); + }; } From 2997da1f23403a84501d229d951e8808026aea79 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 15:53:55 +0200 Subject: [PATCH 07/13] Move MIDI common files in server library on OSX. --- macosx/Jackdmp.xcodeproj/project.pbxproj | 144 +++++++++++------------ 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 195dd976..eb5eb758 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -108,42 +108,6 @@ /* Begin PBXBuildFile section */ 4B0A28ED0D520852002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; }; 4B0A29260D52108E002EFF74 /* tw.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A28EC0D520852002EFF74 /* tw.c */; }; - 4B193933133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; - 4B193934133F311400547810 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; - 4B193935133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; - 4B193936133F311400547810 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; - 4B19393D133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; - 4B19393E133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; - 4B19393F133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; - 4B193940133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; - 4B193947133F315300547810 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; - 4B193948133F315300547810 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; - 4B193949133F315300547810 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; - 4B19394A133F315300547810 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; - 4B19395F133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; - 4B193960133F317300547810 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; - 4B193961133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; - 4B193962133F317300547810 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; - 4B19396A133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; - 4B19396B133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; - 4B19396C133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; - 4B19396D133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; - 4B19397B133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; - 4B19397C133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; - 4B19397D133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; - 4B19397E133F31CB00547810 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; - 4B19397F133F31CB00547810 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; - 4B193980133F31CB00547810 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; - 4B193981133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; - 4B193982133F31CB00547810 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; - 4B193983133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; - 4B193984133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; - 4B193985133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; - 4B193986133F31CB00547810 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; - 4B193987133F31CB00547810 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; - 4B193988133F31CB00547810 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; - 4B193989133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; - 4B19398A133F31CB00547810 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; 4B193991133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193992133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; 4B193993133F321500547810 /* JackFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193990133F321500547810 /* JackFilters.h */; }; @@ -671,6 +635,42 @@ 4B94334A10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B94334B10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B95BCAE0D913073000F7695 /* control.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B95BCAD0D913073000F7695 /* control.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B97B6381344B3C100794F57 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; + 4B97B6391344B3C300794F57 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; + 4B97B63A1344B3C700794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; + 4B97B63D1344B3EC00794F57 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; + 4B97B63E1344B3F100794F57 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; + 4B97B6411344B40C00794F57 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; + 4B97B6531344B41E00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; + 4B97B6541344B42400794F57 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; + 4B97B6561344B43600794F57 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; + 4B97B6571344B43A00794F57 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; + 4B97B6581344B43F00794F57 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; + 4B97B6591344B44800794F57 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; + 4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; + 4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; + 4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; + 4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; + 4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; + 4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; + 4B97B6601344B48F00794F57 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; }; + 4B97B6611344B49500794F57 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; }; + 4B97B6621344B49C00794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; }; + 4B97B6631344B4A800794F57 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; }; + 4B97B6641344B4AE00794F57 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; }; + 4B97B6651344B4B500794F57 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; }; + 4B97B6671344B4C700794F57 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; }; + 4B97B6691344B4CE00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; }; + 4B97B66E1344B4D500794F57 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; }; + 4B97B66F1344B4DC00794F57 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; }; + 4B97B6701344B4E300794F57 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; }; + 4B97B6711344B4EA00794F57 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; }; + 4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; }; + 4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; }; + 4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; }; + 4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; }; + 4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; }; + 4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; }; 4B9A25B50DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A25B60DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26010DBF8584006E9FBC /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -3454,6 +3454,15 @@ 4B8A38C4117B814000664E07 /* JackSocketServerNotifyChannel.h in Headers */, 4B5160AA13215ED900BB7DCB /* systemdeps.h in Headers */, 4B193995133F321500547810 /* JackFilters.h in Headers */, + 4B97B6611344B49500794F57 /* JackMidiAsyncQueue.h in Headers */, + 4B97B6631344B4A800794F57 /* JackMidiAsyncWaitQueue.h in Headers */, + 4B97B6651344B4B500794F57 /* JackMidiBufferReadQueue.h in Headers */, + 4B97B6671344B4C700794F57 /* JackMidiBufferWriteQueue.h in Headers */, + 4B97B66F1344B4DC00794F57 /* JackMidiReadQueue.h in Headers */, + 4B97B6711344B4EA00794F57 /* JackMidiReceiveQueue.h in Headers */, + 4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */, + 4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */, + 4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3917,6 +3926,15 @@ 4B2209E712F6BC0300E5DC26 /* JackSocket.h in Headers */, 4B2209EA12F6BC1600E5DC26 /* JackSocketNotifyChannel.h in Headers */, 4B193992133F321500547810 /* JackFilters.h in Headers */, + 4B97B6391344B3C300794F57 /* JackMidiAsyncQueue.h in Headers */, + 4B97B63D1344B3EC00794F57 /* JackMidiAsyncWaitQueue.h in Headers */, + 4B97B6411344B40C00794F57 /* JackMidiBufferReadQueue.h in Headers */, + 4B97B6541344B42400794F57 /* JackMidiBufferWriteQueue.h in Headers */, + 4B97B6561344B43600794F57 /* JackMidiReadQueue.h in Headers */, + 4B97B6591344B44800794F57 /* JackMidiReceiveQueue.h in Headers */, + 4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */, + 4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */, + 4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4152,15 +4170,6 @@ 4B370A3F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, 4B370A41133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, 4B370A43133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, - 4B193936133F311400547810 /* JackMidiAsyncQueue.h in Headers */, - 4B193940133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */, - 4B19394A133F315300547810 /* JackMidiReadQueue.h in Headers */, - 4B193962133F317300547810 /* JackMidiBufferReadQueue.h in Headers */, - 4B19396D133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */, - 4B193984133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */, - 4B193986133F31CB00547810 /* JackMidiSendQueue.h in Headers */, - 4B193988133F31CB00547810 /* JackMidiUtil.h in Headers */, - 4B19398A133F31CB00547810 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4229,15 +4238,6 @@ 4B370A2F133DD7E300237B68 /* JackCoreMidiUtil.h in Headers */, 4B370A31133DD7E300237B68 /* JackCoreMidiVirtualInputPort.h in Headers */, 4B370A33133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.h in Headers */, - 4B193934133F311400547810 /* JackMidiAsyncQueue.h in Headers */, - 4B19393E133F313000547810 /* JackMidiAsyncWaitQueue.h in Headers */, - 4B193948133F315300547810 /* JackMidiReadQueue.h in Headers */, - 4B193960133F317300547810 /* JackMidiBufferReadQueue.h in Headers */, - 4B19396B133F319000547810 /* JackMidiBufferWriteQueue.h in Headers */, - 4B19397C133F31CB00547810 /* JackMidiReceiveQueue.h in Headers */, - 4B19397E133F31CB00547810 /* JackMidiSendQueue.h in Headers */, - 4B193980133F31CB00547810 /* JackMidiUtil.h in Headers */, - 4B193982133F31CB00547810 /* JackMidiWriteQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6885,6 +6885,15 @@ 4B8A38AE117B811100664E07 /* JackSocketNotifyChannel.cpp in Sources */, 4B8A38B1117B812D00664E07 /* JackSocketServerChannel.cpp in Sources */, 4B8A38B2117B813400664E07 /* JackSocketServerNotifyChannel.cpp in Sources */, + 4B97B6601344B48F00794F57 /* JackMidiAsyncQueue.cpp in Sources */, + 4B97B6621344B49C00794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */, + 4B97B6641344B4AE00794F57 /* JackMidiBufferReadQueue.cpp in Sources */, + 4B97B6691344B4CE00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */, + 4B97B66E1344B4D500794F57 /* JackMidiReadQueue.cpp in Sources */, + 4B97B6701344B4E300794F57 /* JackMidiReceiveQueue.cpp in Sources */, + 4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */, + 4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */, + 4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7337,6 +7346,15 @@ 4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */, 4B2209E612F6BC0200E5DC26 /* JackSocket.cpp in Sources */, 4B2209E912F6BC1500E5DC26 /* JackSocketNotifyChannel.cpp in Sources */, + 4B97B6381344B3C100794F57 /* JackMidiAsyncQueue.cpp in Sources */, + 4B97B63A1344B3C700794F57 /* JackMidiAsyncWaitQueue.cpp in Sources */, + 4B97B63E1344B3F100794F57 /* JackMidiBufferReadQueue.cpp in Sources */, + 4B97B6531344B41E00794F57 /* JackMidiBufferWriteQueue.cpp in Sources */, + 4B97B6571344B43A00794F57 /* JackMidiReadQueue.cpp in Sources */, + 4B97B6581344B43F00794F57 /* JackMidiReceiveQueue.cpp in Sources */, + 4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */, + 4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */, + 4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7575,15 +7593,6 @@ 4B370A3E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, 4B370A40133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, 4B370A42133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, - 4B193935133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */, - 4B19393F133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */, - 4B193949133F315300547810 /* JackMidiReadQueue.cpp in Sources */, - 4B193961133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */, - 4B19396C133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */, - 4B193983133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */, - 4B193985133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */, - 4B193987133F31CB00547810 /* JackMidiUtil.cpp in Sources */, - 4B193989133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7657,15 +7666,6 @@ 4B370A2E133DD7E300237B68 /* JackCoreMidiUtil.cpp in Sources */, 4B370A30133DD7E300237B68 /* JackCoreMidiVirtualInputPort.cpp in Sources */, 4B370A32133DD7E300237B68 /* JackCoreMidiVirtualOutputPort.cpp in Sources */, - 4B193933133F311400547810 /* JackMidiAsyncQueue.cpp in Sources */, - 4B19393D133F313000547810 /* JackMidiAsyncWaitQueue.cpp in Sources */, - 4B193947133F315300547810 /* JackMidiReadQueue.cpp in Sources */, - 4B19395F133F317300547810 /* JackMidiBufferReadQueue.cpp in Sources */, - 4B19396A133F319000547810 /* JackMidiBufferWriteQueue.cpp in Sources */, - 4B19397B133F31CB00547810 /* JackMidiReceiveQueue.cpp in Sources */, - 4B19397D133F31CB00547810 /* JackMidiSendQueue.cpp in Sources */, - 4B19397F133F31CB00547810 /* JackMidiUtil.cpp in Sources */, - 4B193981133F31CB00547810 /* JackMidiWriteQueue.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From a871bb2496c14c125c3c7007441874a1dd60101e Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 18:22:52 +0200 Subject: [PATCH 08/13] Correct JackWinMMEInputPort.cpp. --- common/shm.h | 2 +- windows/jackd.workspace | 4 +-- windows/winmme/JackWinMMEDriver.cpp | 39 ++++++++++++++++++------- windows/winmme/JackWinMMEInputPort.cpp | 29 ++++++++++++++---- windows/winmme/JackWinMMEInputPort.h | 6 ++-- windows/winmme/JackWinMMEOutputPort.cpp | 11 ++++++- 6 files changed, 68 insertions(+), 23 deletions(-) diff --git a/common/shm.h b/common/shm.h index ed5a953f..f1edc8ed 100644 --- a/common/shm.h +++ b/common/shm.h @@ -14,7 +14,7 @@ extern "C" { #endif -#define MAX_SERVERS 8 /* maximum concurrent servers */ +#define MAX_SERVERS 64 /* maximum concurrent servers */ #define MAX_SHM_ID 256 /* generally about 16 per server */ #define JACK_SERVER_NAME_SIZE 256 /* maximum length of server name */ #define JACK_SHM_MAGIC 0x4a41434b /* shm magic number: "JACK" */ diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 4384140e..c424a7b4 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -5,7 +5,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index 455118a2..96bebda1 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -52,6 +52,9 @@ JackWinMMEDriver::Attach() latency_range.max = latency; latency_range.min = latency; + jack_info("JackWinMMEDriver::Attach - fCaptureChannels %d", fCaptureChannels); + jack_info("JackWinMMEDriver::Attach - fPlaybackChannels %d", fPlaybackChannels); + // Inputs for (int i = 0; i < fCaptureChannels; i++) { JackWinMMEInputPort *input_port = input_ports[i]; @@ -130,9 +133,13 @@ JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, { const char *client_name = fClientControl.fName; int input_count = 0; + int output_count = 0; int num_potential_inputs = midiInGetNumDevs(); int num_potential_outputs = midiOutGetNumDevs(); - int output_count = 0; + + jack_info("JackWinMMEDriver::Open - num_potential_inputs %d", num_potential_inputs); + jack_info("JackWinMMEDriver::Open - num_potential_outputs %d", num_potential_outputs); + if (num_potential_inputs) { try { input_ports = new JackWinMMEInputPort *[num_potential_inputs]; @@ -175,6 +182,11 @@ JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, output_count++; } } + + jack_info("JackWinMMEDriver::Open - input_count %d", input_count); + jack_info("JackWinMMEDriver::Open - output_count %d", output_count); + + if (! (input_count || output_count)) { jack_error("JackWinMMEDriver::Open - no WinMME inputs or outputs " "allocated."); @@ -200,10 +212,25 @@ JackWinMMEDriver::Open(bool capturing, bool playing, int in_channels, int JackWinMMEDriver::Read() { + jack_nframes_t buffer_size = fEngineControl->fBufferSize; for (int i = 0; i < fCaptureChannels; i++) { input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size); } + + return 0; +} + + +int +JackWinMMEDriver::Write() +{ + /* + jack_nframes_t buffer_size = fEngineControl->fBufferSize; + for (int i = 0; i < fPlaybackChannels; i++) { + output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); + } + */ return 0; } @@ -287,16 +314,6 @@ JackWinMMEDriver::Stop() return result; } -int -JackWinMMEDriver::Write() -{ - jack_nframes_t buffer_size = fEngineControl->fBufferSize; - for (int i = 0; i < fPlaybackChannels; i++) { - output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size); - } - return 0; -} - #ifdef __cplusplus extern "C" { diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 0adf3bec..6c573cf0 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -78,6 +78,23 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, goto unprepare_header; } + MIDIINCAPS capabilities; + char *name_tmp; + result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); + /* + Devin : FIXME + if (result != MMSYSERR_NOERROR) { + WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", + result); + name_tmp = driver_name; + } else { + name_tmp = capabilities.szPname; + } + */ + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", alias_name, driver_name, + index + 1); + snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); + jack_event = 0; started = false; write_queue_ptr.release(); @@ -147,6 +164,12 @@ JackWinMMEInputPort::GetAlias() return alias; } +const char * +JackWinMMEInputPort::GetName() +{ + return name; +} + void JackWinMMEInputPort::GetErrorString(MMRESULT error, LPTSTR text) { @@ -156,12 +179,6 @@ JackWinMMEInputPort::GetErrorString(MMRESULT error, LPTSTR text) } } -const char * -JackWinMMEInputPort::GetName() -{ - return name; -} - void JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) { diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h index dd4c53f1..568bd9f5 100644 --- a/windows/winmme/JackWinMMEInputPort.h +++ b/windows/winmme/JackWinMMEInputPort.h @@ -50,15 +50,17 @@ namespace Jack { MMRESULT result); char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + HMIDIIN handle; jack_midi_event_t *jack_event; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - bool started; jack_midi_data_t *sysex_buffer; MIDIHDR sysex_header; JackMidiAsyncQueue *thread_queue; JackMidiBufferWriteQueue *write_queue; + bool started; + public: JackWinMMEInputPort(const char *alias_name, const char *client_name, diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index eb9ba49e..0b05cb2c 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -88,7 +88,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); thread_ptr.release(); - thread_queue_ptr.release(); + thread_queue_ptr.release(); return; destroy_thread_queue_semaphore: @@ -132,9 +132,15 @@ bool JackWinMMEOutputPort::Execute() { for (;;) { + jack_log("JackWinMMEOutputPort::Execute TOTO"); + JackSleep(100000); + if (! Wait(thread_queue_semaphore)) { + jack_log("JackWinMMEOutputPort::Execute BREAK"); + break; } + /* jack_midi_event_t *event = thread_queue->DequeueEvent(); if (! event) { break; @@ -214,6 +220,7 @@ JackWinMMEOutputPort::Execute() "midiOutUnprepareHeader", result); break; } + */ } stop_execution: return false; @@ -358,6 +365,8 @@ JackWinMMEOutputPort::Stop() bool JackWinMMEOutputPort::Wait(HANDLE semaphore) { + jack_log("JackWinMMEOutputPort::Wait %d", semaphore); + DWORD result = WaitForSingleObject(semaphore, INFINITE); switch (result) { case WAIT_FAILED: From 173f1629a95298dfb0692044dd9b932245685d3d Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Thu, 31 Mar 2011 10:37:17 -0700 Subject: [PATCH 09/13] Fix problems sent by Stephane. --- windows/winmme/JackWinMMEInputPort.cpp | 20 ++++++++-- windows/winmme/JackWinMMEOutputPort.cpp | 53 +++++++++---------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 0adf3bec..79d1c8af 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -55,7 +55,8 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, std::auto_ptr write_queue_ptr(write_queue); sysex_buffer = new jack_midi_data_t[max_bytes]; char error_message[MAXERRORLENGTH]; - MMRESULT result = midiInOpen(&handle, index, (DWORD)HandleMidiInputEvent, (DWORD)this, + MMRESULT result = midiInOpen(&handle, index, (DWORD)HandleMidiInputEvent, + (DWORD)this, CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { GetErrorString(result, error_message); @@ -77,7 +78,19 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, GetErrorString(result, error_message); goto unprepare_header; } - + MIDIINCAPS capabilities; + char *name_tmp; + result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); + if (result != MMSYSERR_NOERROR) { + WriteError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", + result); + name_tmp = driver_name; + } else { + name_tmp = capabilities.szPname; + } + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", alias_name, name_tmp, + index + 1); + snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); jack_event = 0; started = false; write_queue_ptr.release(); @@ -163,7 +176,8 @@ JackWinMMEInputPort::GetName() } void -JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) +JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, + jack_nframes_t frames) { write_queue->ResetMidiBuffer(port_buffer, frames); if (! jack_event) { diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index eb9ba49e..ff001d96 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -55,10 +55,10 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, thread = new JackThread(this); std::auto_ptr thread_ptr(thread); char error_message[MAXERRORLENGTH]; - MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, (DWORD)this, - CALLBACK_FUNCTION); + MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, + (DWORD)this, CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { - GetErrorString(result, error_message); + GetMMErrorString(result, error_message); goto raise_exception; } thread_queue_semaphore = CreateSemaphore(NULL, 0, max_messages, NULL); @@ -74,8 +74,6 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, MIDIOUTCAPS capabilities; char *name_tmp; result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); - /* - Devin : FIXME if (result != MMSYSERR_NOERROR) { WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); @@ -83,12 +81,11 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, } else { name_tmp = capabilities.szPname; } - */ - snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, driver_name, + snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", alias_name, name_tmp, index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); thread_ptr.release(); - thread_queue_ptr.release(); + thread_queue_ptr.release(); return; destroy_thread_queue_semaphore: @@ -219,6 +216,12 @@ JackWinMMEOutputPort::Execute() return false; } +const char * +JackWinMMEOutputPort::GetAlias() +{ + return alias; +} + void JackWinMMEOutputPort::GetMMErrorString(MMRESULT error, LPTSTR text) { @@ -228,18 +231,21 @@ JackWinMMEOutputPort::GetMMErrorString(MMRESULT error, LPTSTR text) } } +const char * +JackWinMMEOutputPort::GetName() +{ + return name; +} + void JackWinMMEOutputPort::GetOSErrorString(LPTSTR text) { DWORD error = GetLastError(); - /* - Devin: FIXME if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &text, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), text, MAXERRORLENGTH, NULL)) { snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); } - */ } void @@ -385,27 +391,6 @@ void JackWinMMEOutputPort::WriteOSError(const char *jack_func, const char *os_func) { char error_message[MAXERRORLENGTH]; - // Devin : FIXME - //GetOSErrorString(result, error_message); + GetOSErrorString(error_message); jack_error("%s - %s: %s", jack_func, os_func, error_message); } - -const char * -JackWinMMEOutputPort::GetAlias() -{ - return alias; -} -const char * -JackWinMMEOutputPort::GetName() -{ - return name; -} - -void -JackWinMMEOutputPort::GetErrorString(MMRESULT error, LPTSTR text) -{ - MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); - if (result != MMSYSERR_NOERROR) { - snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); - } -} From a3318119b3df546061b6960d7d6a4a8752265383 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 19:52:14 +0200 Subject: [PATCH 10/13] Correct MIDI ports memory management in JackNetDriver. --- common/JackNetDriver.cpp | 52 +++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index d2327eb1..66e4f7dd 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -151,8 +151,16 @@ namespace Jack //allocate midi ports lists fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels]; fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels]; - assert ( fMidiCapturePortList ); - assert ( fMidiPlaybackPortList ); + + assert(fMidiCapturePortList); + assert(fMidiPlaybackPortList); + + for (uint midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { + fMidiCapturePortList[midi_port_index] = NULL; + } + for (uint midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { + fMidiPlaybackPortList[midi_port_index] = NULL; + } //register jack ports if ( AllocPorts() != 0 ) @@ -362,20 +370,32 @@ namespace Jack { jack_log ( "JackNetDriver::FreePorts" ); - int audio_port_index; - uint midi_port_index; - for ( audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++ ) - if (fCapturePortList[audio_port_index] > 0) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fCapturePortList[audio_port_index] ); - for ( audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++ ) - if (fPlaybackPortList[audio_port_index] > 0) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fPlaybackPortList[audio_port_index] ); - for ( midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++ ) - if (fMidiCapturePortList[midi_port_index] > 0) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiCapturePortList[midi_port_index] ); - for ( midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++ ) - if (fMidiPlaybackPortList[midi_port_index] > 0) - fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index] ); + for (int audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) { + if (fCapturePortList[audio_port_index] > 0) { + fGraphManager->ReleasePort ( fClientControl.fRefNum, fCapturePortList[audio_port_index]); + } + } + + for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { + if (fPlaybackPortList[audio_port_index] > 0) { + fGraphManager->ReleasePort ( fClientControl.fRefNum, fPlaybackPortList[audio_port_index]); + } + } + + for (uint midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { + if (fMidiCapturePortList && fMidiCapturePortList[midi_port_index] > 0) { + fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiCapturePortList[midi_port_index]); + } + } + + for (uint midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { + if (fMidiPlaybackPortList && fMidiPlaybackPortList[midi_port_index] > 0) { + fGraphManager->ReleasePort ( fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index]); + } + } + // Clear MIDI channels + fParams.fSendMidiChannels = 0; + fParams.fReturnMidiChannels = 0; return 0; } From 9ce3e4fc5224eda16c677497e070150f9af8b918 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 21:15:42 +0200 Subject: [PATCH 11/13] Correct test.cpp. --- tests/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test.cpp b/tests/test.cpp index 1a6e4a05..7c3f5b5e 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -972,14 +972,14 @@ int main (int argc, char *argv[]) float factor = 0.5f; old_buffer_size = jack_get_buffer_size(client1); - Log("Testing BufferSize change & Callback...\n--> Current buffer size : %i.\n", old_buffer_size); + Log("Testing BufferSize change & Callback...\n--> Current buffer size : %d.\n", old_buffer_size); linebuf = linecount; if (jack_set_buffer_size(client1, (jack_nframes_t)(old_buffer_size * factor)) < 0) { printf("!!! ERROR !!! jack_set_buffer_size fails !\n"); } jack_sleep(1 * 1000); cur_buffer_size = jack_get_buffer_size(client1); - if ((old_buffer_size * factor) != cur_buffer_size) { + if (abs((old_buffer_size * factor) - cur_buffer_size) > 5) { // Tolerance needed for dummy driver... printf("!!! ERROR !!! Buffer size has not been changed !\n"); printf("!!! Maybe jack was compiled without the '--enable-resize' flag...\n"); } else { From eb24bdac93a1871785ca4db191f5817267f0cc46 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Thu, 31 Mar 2011 22:03:34 +0200 Subject: [PATCH 12/13] New JackWinMMEPort class to factorize some code. --- windows/winmme/JackWinMMEInputPort.cpp | 59 +++++++++------------ windows/winmme/JackWinMMEInputPort.h | 25 ++++----- windows/winmme/JackWinMMEOutputPort.cpp | 67 +++++++----------------- windows/winmme/JackWinMMEOutputPort.h | 31 +++-------- windows/winmme/JackWinMMEPort.cpp | 69 +++++++++++++++++++++++++ windows/winmme/JackWinMMEPort.h | 58 +++++++++++++++++++++ 6 files changed, 185 insertions(+), 124 deletions(-) create mode 100644 windows/winmme/JackWinMMEPort.cpp create mode 100644 windows/winmme/JackWinMMEPort.h diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index ae526cbc..9d72cc42 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -59,7 +59,7 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, (DWORD)this, CALLBACK_FUNCTION | MIDI_IO_STATUS); if (result != MMSYSERR_NOERROR) { - GetErrorString(result, error_message); + GetInErrorString(result, error_message); goto delete_sysex_buffer; } sysex_header.dwBufferLength = max_bytes; @@ -70,19 +70,19 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, sysex_header.lpNext = 0; result = midiInPrepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - GetErrorString(result, error_message); + GetInErrorString(result, error_message); goto close_handle; } result = midiInAddBuffer(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - GetErrorString(result, error_message); + GetInErrorString(result, error_message); goto unprepare_header; } MIDIINCAPS capabilities; char *name_tmp; result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", + WriteInError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", result); name_tmp = driver_name; } else { @@ -100,13 +100,13 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, unprepare_header: result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [constructor]", + WriteInError("JackWinMMEInputPort [constructor]", "midiInUnprepareHeader", result); } close_handle: result = midiInClose(handle); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [constructor]", "midiInClose", result); + WriteInError("JackWinMMEInputPort [constructor]", "midiInClose", result); } delete_sysex_buffer: delete[] sysex_buffer; @@ -118,16 +118,16 @@ JackWinMMEInputPort::~JackWinMMEInputPort() Stop(); MMRESULT result = midiInReset(handle); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [destructor]", "midiInReset", result); + WriteInError("JackWinMMEInputPort [destructor]", "midiInReset", result); } result = midiInUnprepareHeader(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", + WriteInError("JackWinMMEInputPort [destructor]", "midiInUnprepareHeader", result); } result = midiInClose(handle); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort [destructor]", "midiInClose", result); + WriteInError("JackWinMMEInputPort [destructor]", "midiInClose", result); } delete[] sysex_buffer; delete thread_queue; @@ -154,27 +154,6 @@ JackWinMMEInputPort::EnqueueMessage(jack_nframes_t time, size_t length, } } -const char * -JackWinMMEInputPort::GetAlias() -{ - return alias; -} - -const char * -JackWinMMEInputPort::GetName() -{ - return name; -} - -void -JackWinMMEInputPort::GetErrorString(MMRESULT error, LPTSTR text) -{ - MMRESULT result = midiInGetErrorText(error, text, MAXERRORLENGTH); - if (result != MMSYSERR_NOERROR) { - snprintf(text, MAXERRORLENGTH, "Unknown error code '%d'", error); - } -} - void JackWinMMEInputPort::ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames) @@ -254,7 +233,7 @@ JackWinMMEInputPort::ProcessWinMME(UINT message, DWORD param1, DWORD param2) MMRESULT result = midiInAddBuffer(handle, &sysex_header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteError("JackWinMMEInputPort::ProcessWinMME", "midiInAddBuffer", + WriteInError("JackWinMMEInputPort::ProcessWinMME", "midiInAddBuffer", result); } break; @@ -274,7 +253,7 @@ JackWinMMEInputPort::Start() MMRESULT result = midiInStart(handle); started = result == MMSYSERR_NOERROR; if (! started) { - WriteError("JackWinMMEInputPort::Start", "midiInStart", result); + WriteInError("JackWinMMEInputPort::Start", "midiInStart", result); } } return started; @@ -287,17 +266,27 @@ JackWinMMEInputPort::Stop() MMRESULT result = midiInStop(handle); started = result != MMSYSERR_NOERROR; if (started) { - WriteError("JackWinMMEInputPort::Stop", "midiInStop", result); + WriteInError("JackWinMMEInputPort::Stop", "midiInStop", result); } } return ! started; } void -JackWinMMEInputPort::WriteError(const char *jack_func, const char *mm_func, +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 +JackWinMMEInputPort::WriteInError(const char *jack_func, const char *mm_func, MMRESULT result) { char error_message[MAXERRORLENGTH]; - GetErrorString(result, error_message); + GetInErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } + diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h index 568bd9f5..a7305340 100644 --- a/windows/winmme/JackWinMMEInputPort.h +++ b/windows/winmme/JackWinMMEInputPort.h @@ -24,10 +24,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackMidiAsyncQueue.h" #include "JackMidiBufferWriteQueue.h" +#include "JackWinMMEPort.h" namespace Jack { - class JackWinMMEInputPort { + class JackWinMMEInputPort : public JackRunnableInterface { private: @@ -39,19 +40,10 @@ namespace Jack { EnqueueMessage(jack_nframes_t time, size_t length, jack_midi_data_t *data); - void - GetErrorString(MMRESULT error, LPTSTR text); void ProcessWinMME(UINT message, DWORD param1, DWORD param2); - void - WriteError(const char *jack_func, const char *mm_func, - MMRESULT result); - - char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - HMIDIIN handle; jack_midi_event_t *jack_event; jack_midi_data_t *sysex_buffer; @@ -61,6 +53,13 @@ namespace Jack { bool started; + void + WriteOSError(const char *jack_func, const char *os_func); + + void + WriteInError(const char *jack_func, const char *mm_func, + MMRESULT result); + public: JackWinMMEInputPort(const char *alias_name, const char *client_name, @@ -69,12 +68,6 @@ namespace Jack { ~JackWinMMEInputPort(); - const char * - GetAlias(); - - const char * - GetName(); - void ProcessJack(JackMidiBuffer *port_buffer, jack_nframes_t frames); diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 7af41ca7..dcc1dd79 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -58,7 +58,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, MMRESULT result = midiOutOpen(&handle, index, (DWORD)HandleMessageEvent, (DWORD)this, CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { - GetMMErrorString(result, error_message); + GetOutErrorString(result, error_message); goto raise_exception; } thread_queue_semaphore = CreateSemaphore(NULL, 0, max_messages, NULL); @@ -75,7 +75,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, char *name_tmp; result = midiOutGetDevCaps(index, &capabilities, sizeof(capabilities)); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", + WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); name_tmp = driver_name; } else { @@ -95,7 +95,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, close_handle: result = midiOutClose(handle); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort [constructor]", "midiOutClose", + WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutClose", result); } raise_exception: @@ -107,12 +107,12 @@ JackWinMMEOutputPort::~JackWinMMEOutputPort() Stop(); MMRESULT result = midiOutReset(handle); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort [destructor]", "midiOutReset", + WriteOutError("JackWinMMEOutputPort [destructor]", "midiOutReset", result); } result = midiOutClose(handle); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort [destructor]", "midiOutClose", + WriteOutError("JackWinMMEOutputPort [destructor]", "midiOutClose", result); } if (! CloseHandle(sysex_semaphore)) { @@ -179,7 +179,7 @@ JackWinMMEOutputPort::Execute() message |= (DWORD) data[0]; result = midiOutShortMsg(handle, message); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort::Execute", + WriteOutError("JackWinMMEOutputPort::Execute", "midiOutShortMsg", result); } continue; @@ -193,13 +193,13 @@ JackWinMMEOutputPort::Execute() header.lpData = (LPSTR)data; result = midiOutPrepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort::Execute", + WriteOutError("JackWinMMEOutputPort::Execute", "midiOutPrepareHeader", result); continue; } result = midiOutLongMsg(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort::Execute", "midiOutLongMsg", + WriteOutError("JackWinMMEOutputPort::Execute", "midiOutLongMsg", result); continue; } @@ -213,7 +213,7 @@ JackWinMMEOutputPort::Execute() result = midiOutUnprepareHeader(handle, &header, sizeof(MIDIHDR)); if (result != MMSYSERR_NOERROR) { - WriteMMError("JackWinMMEOutputPort::Execute", + WriteOutError("JackWinMMEOutputPort::Execute", "midiOutUnprepareHeader", result); break; } @@ -223,38 +223,6 @@ JackWinMMEOutputPort::Execute() return false; } -const char * -JackWinMMEOutputPort::GetAlias() -{ - return alias; -} - -void -JackWinMMEOutputPort::GetMMErrorString(MMRESULT error, LPTSTR text) -{ - MMRESULT result = midiOutGetErrorText(error, text, MAXERRORLENGTH); - if (result != MMSYSERR_NOERROR) { - snprintf(text, MAXERRORLENGTH, "Unknown MM error code '%d'", error); - } -} - -const char * -JackWinMMEOutputPort::GetName() -{ - return name; -} - -void -JackWinMMEOutputPort::GetOSErrorString(LPTSTR text) -{ - DWORD error = GetLastError(); - if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), text, - MAXERRORLENGTH, NULL)) { - snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); - } -} - void JackWinMMEOutputPort::HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2) @@ -388,18 +356,19 @@ JackWinMMEOutputPort::Wait(HANDLE semaphore) } void -JackWinMMEOutputPort::WriteMMError(const char *jack_func, const char *mm_func, - MMRESULT result) +JackWinMMEOutputPort::GetOutErrorString(MMRESULT error, LPTSTR text) { - char error_message[MAXERRORLENGTH]; - GetMMErrorString(result, error_message); - jack_error("%s - %s: %s", jack_func, mm_func, error_message); + MMRESULT result = midiOutGetErrorText(error, text, MAXERRORLENGTH); + if (result != MMSYSERR_NOERROR) { + snprintf(text, MAXERRORLENGTH, "Unknown MM error code '%d'", error); + } } void -JackWinMMEOutputPort::WriteOSError(const char *jack_func, const char *os_func) +JackWinMMEOutputPort::WriteOutError(const char *jack_func, const char *mm_func, + MMRESULT result) { char error_message[MAXERRORLENGTH]; - GetOSErrorString(error_message); - jack_error("%s - %s: %s", jack_func, os_func, error_message); + GetMMErrorString(result, error_message); + jack_error("%s - %s: %s", jack_func, mm_func, error_message); } diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index c343ff55..36fa28b1 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -29,7 +29,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - class JackWinMMEOutputPort: public JackRunnableInterface { + class JackWinMMEOutputPort : + public JackWinMMEPort, public JackRunnableInterface { private: @@ -37,12 +38,6 @@ namespace Jack { HandleMessageEvent(HMIDIOUT handle, UINT message, DWORD_PTR port, DWORD_PTR param1, DWORD_PTR param2); - void - GetMMErrorString(MMRESULT error, LPTSTR text); - - void - GetOSErrorString(LPTSTR text); - void HandleMessage(UINT message, DWORD_PTR param1, DWORD_PTR param2); @@ -52,16 +47,6 @@ namespace Jack { bool Wait(HANDLE semaphore); - void - WriteMMError(const char *jack_func, const char *mm_func, - MMRESULT result); - - void - WriteOSError(const char *jack_func, const char *os_func); - - char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - HMIDIOUT handle; JackMidiBufferReadQueue *read_queue; HANDLE sysex_semaphore; @@ -70,7 +55,11 @@ namespace Jack { HANDLE thread_queue_semaphore; void - GetErrorString(MMRESULT error, LPTSTR text); + GetOutErrorString(MMRESULT error, LPTSTR text); + + void + WriteOutError(const char *jack_func, const char *mm_func, + MMRESULT result); public: @@ -95,12 +84,6 @@ namespace Jack { bool Stop(); - const char * - GetAlias(); - - const char * - GetName(); - }; } diff --git a/windows/winmme/JackWinMMEPort.cpp b/windows/winmme/JackWinMMEPort.cpp new file mode 100644 index 00000000..577cfbeb --- /dev/null +++ b/windows/winmme/JackWinMMEPort.cpp @@ -0,0 +1,69 @@ +/* +Copyright (C) 2011 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include + +#include "JackWinMMEPort.h" + +using Jack::JackWinMMEPort; + +/////////////////////////////////////////////////////////////////////////////// +// Class +/////////////////////////////////////////////////////////////////////////////// + +JackWinMMEPort::JackWinMMEPort(const char *alias_name, + const char *client_name, + const char *driver_name) +{} + +JackWinMMEPort::~JackWinMMEPort() +{} + +const JackWinMMEPort * +JackWinMMEOutputPort::GetAlias() +{ + return alias; +} + +const char * +JackWinMMEPort::GetName() +{ + return name; +} + +void +JackWinMMEPort::GetOSErrorString(LPTSTR text) +{ + DWORD error = GetLastError(); + if (! FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), text, + MAXERRORLENGTH, NULL)) { + snprintf(text, MAXERRORLENGTH, "Unknown OS error code '%d'", error); + } +} + +void +JackWinMMEPort::WriteOSError(const char *jack_func, const char *os_func) +{ + char error_message[MAXERRORLENGTH]; + GetOSErrorString(error_message); + jack_error("%s - %s: %s", jack_func, os_func, error_message); +} + diff --git a/windows/winmme/JackWinMMEPort.h b/windows/winmme/JackWinMMEPort.h new file mode 100644 index 00000000..3b53fd5f --- /dev/null +++ b/windows/winmme/JackWinMMEPort.h @@ -0,0 +1,58 @@ +/* +Copyright (C) 2011 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __JackWinMMEPort__ +#define __JackWinMMEPort__ + +#include +#include + +namespace Jack { + + class JackWinMMEPort { + + protected: + + char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + + public: + + JackWinMMEPort(const char *alias_name, const char *client_name, + const char *driver_name); + + ~JackWinMMEPort(); + + const char * + GetAlias(); + + const char * + GetName(); + + void + GetOSErrorString(LPTSTR text); + + void + GetInErrorString(MMRESULT error, LPTSTR text); + + }; + +} + +#endif From 8e55718c3834d458690315c4dba55c93ef6e6145 Mon Sep 17 00:00:00 2001 From: Stephane Letz Date: Fri, 1 Apr 2011 10:45:55 +0200 Subject: [PATCH 13/13] Winmme driver compiles again. --- windows/jack_winmme.cbp | 7 +------ windows/libjackserver.cbp | 6 ++++++ windows/winmme/JackWinMMEInputPort.cpp | 4 +++- windows/winmme/JackWinMMEInputPort.h | 7 ++++--- windows/winmme/JackWinMMEOutputPort.cpp | 4 ++-- windows/winmme/JackWinMMEOutputPort.h | 4 +--- windows/winmme/JackWinMMEPort.cpp | 9 ++++----- windows/winmme/JackWinMMEPort.h | 9 +++++---- 8 files changed, 26 insertions(+), 24 deletions(-) diff --git a/windows/jack_winmme.cbp b/windows/jack_winmme.cbp index 7de61fa8..7fe93703 100644 --- a/windows/jack_winmme.cbp +++ b/windows/jack_winmme.cbp @@ -102,12 +102,6 @@ - - - - - - @@ -117,6 +111,7 @@ + diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index 89cd2dd3..84b8985d 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -150,8 +150,14 @@ + + + + + + diff --git a/windows/winmme/JackWinMMEInputPort.cpp b/windows/winmme/JackWinMMEInputPort.cpp index 9d72cc42..c3b04453 100644 --- a/windows/winmme/JackWinMMEInputPort.cpp +++ b/windows/winmme/JackWinMMEInputPort.cpp @@ -78,16 +78,18 @@ JackWinMMEInputPort::JackWinMMEInputPort(const char *alias_name, GetInErrorString(result, error_message); goto unprepare_header; } + MIDIINCAPS capabilities; char *name_tmp; result = midiInGetDevCaps(index, &capabilities, sizeof(capabilities)); if (result != MMSYSERR_NOERROR) { WriteInError("JackWinMMEInputPort [constructor]", "midiInGetDevCaps", result); - name_tmp = driver_name; + name_tmp = (char*) driver_name; } else { name_tmp = capabilities.szPname; } + snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", alias_name, name_tmp, index + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", client_name, index + 1); diff --git a/windows/winmme/JackWinMMEInputPort.h b/windows/winmme/JackWinMMEInputPort.h index a7305340..13eb32a6 100644 --- a/windows/winmme/JackWinMMEInputPort.h +++ b/windows/winmme/JackWinMMEInputPort.h @@ -28,7 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - class JackWinMMEInputPort : public JackRunnableInterface { + class JackWinMMEInputPort : public JackWinMMEPort { private: @@ -53,13 +53,14 @@ namespace Jack { bool started; - void - WriteOSError(const char *jack_func, const char *os_func); void WriteInError(const char *jack_func, const char *mm_func, MMRESULT result); + void + GetInErrorString(MMRESULT error, LPTSTR text); + public: JackWinMMEInputPort(const char *alias_name, const char *client_name, diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index dcc1dd79..51a9ddbd 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -77,7 +77,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, if (result != MMSYSERR_NOERROR) { WriteOutError("JackWinMMEOutputPort [constructor]", "midiOutGetDevCaps", result); - name_tmp = driver_name; + name_tmp = (char*)driver_name; } else { name_tmp = capabilities.szPname; } @@ -369,6 +369,6 @@ JackWinMMEOutputPort::WriteOutError(const char *jack_func, const char *mm_func, MMRESULT result) { char error_message[MAXERRORLENGTH]; - GetMMErrorString(result, error_message); + GetOutErrorString(result, error_message); jack_error("%s - %s: %s", jack_func, mm_func, error_message); } diff --git a/windows/winmme/JackWinMMEOutputPort.h b/windows/winmme/JackWinMMEOutputPort.h index 36fa28b1..d43eae35 100644 --- a/windows/winmme/JackWinMMEOutputPort.h +++ b/windows/winmme/JackWinMMEOutputPort.h @@ -20,12 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackWinMMEOutputPort__ #define __JackWinMMEOutputPort__ -#include -#include - #include "JackMidiAsyncQueue.h" #include "JackMidiBufferReadQueue.h" #include "JackThread.h" +#include "JackWinMMEPort.h" namespace Jack { diff --git a/windows/winmme/JackWinMMEPort.cpp b/windows/winmme/JackWinMMEPort.cpp index 577cfbeb..46c4546b 100644 --- a/windows/winmme/JackWinMMEPort.cpp +++ b/windows/winmme/JackWinMMEPort.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackWinMMEPort.h" +#include "JackError.h" using Jack::JackWinMMEPort; @@ -28,16 +29,14 @@ using Jack::JackWinMMEPort; // Class /////////////////////////////////////////////////////////////////////////////// -JackWinMMEPort::JackWinMMEPort(const char *alias_name, - const char *client_name, - const char *driver_name) +JackWinMMEPort::JackWinMMEPort() {} JackWinMMEPort::~JackWinMMEPort() {} -const JackWinMMEPort * -JackWinMMEOutputPort::GetAlias() +const char * +JackWinMMEPort::GetAlias() { return alias; } diff --git a/windows/winmme/JackWinMMEPort.h b/windows/winmme/JackWinMMEPort.h index 3b53fd5f..a544c4a6 100644 --- a/windows/winmme/JackWinMMEPort.h +++ b/windows/winmme/JackWinMMEPort.h @@ -20,8 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackWinMMEPort__ #define __JackWinMMEPort__ -#include #include +#include + +#include "JackConstants.h" namespace Jack { @@ -34,8 +36,7 @@ namespace Jack { public: - JackWinMMEPort(const char *alias_name, const char *client_name, - const char *driver_name); + JackWinMMEPort(); ~JackWinMMEPort(); @@ -49,7 +50,7 @@ namespace Jack { GetOSErrorString(LPTSTR text); void - GetInErrorString(MMRESULT error, LPTSTR text); + WriteOSError(const char *jack_func, const char *os_func); };