diff --git a/ChangeLog b/ChangeLog index 07d96b54..55985ae9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,10 @@ Tom Szilagyi Jackdmp changes log --------------------------- +2007-10-25 Stephane Letz + + * Merge of Dmitry Baikov MIDI branch. + 2007-10-24 Stephane Letz * Implementation of server_name setting (-n). @@ -130,6 +134,10 @@ Tom Szilagyi 2007-05-29 Stephane Letz * Add "callback exiting" and "jack_frame_time" tests in jack_test. + +2007-05-09 Stephane Letz + + * Add a mutex in JackGraphManager AllocatePort/ReleasePort methods. 2007-05-05 Stephane Letz @@ -154,14 +162,39 @@ Tom Szilagyi 2007-04-23 Stephane Letz * Dmitry Baikov jackmp-time patch: add jack_get_time, jack_time_to_frames, jack_frames_to_time. + +2007-04-03 Stephane Letz + + * Dmitry Baikov remove-nframes patch. + +2007-04-02 Stephane Letz + + * Dmitry Baikov lost-event patch. 2007-04-01 Stephane Letz * Merge JackGraphManager Remove and Release method in a unique Release method. + +2007-03-12 Stephane Letz + + * Bug fix in JackMidiBuffer::MaxEventSize(). + +2007-03-09 Stephane Letz + + * Dmitry Baikov MIDI patch phase 2. + +2007-03-08 Stephane Letz + + * Dmitry Baikov jackmp-port-clear patch. + +2007-03-06 Stephane Letz + + * Dmitry Baikov MIDI patch phase 1. 2007-03-04 Stephane Letz - * Dmitry Baikov patch for JackGraphManager.cpp. + * Dmitry Baikov patch for JackGraphManager.cpp. + * Dmitry Baikov MIDI patch phase 0. 2007-02-19 Stephane Letz diff --git a/common/JackAtomicState.h b/common/JackAtomicState.h index 07caf509..7b6e4ed9 100644 --- a/common/JackAtomicState.h +++ b/common/JackAtomicState.h @@ -220,7 +220,7 @@ class JackAtomicState UInt16 cur_index; UInt16 next_index = GetCurrentIndex(); do { - cur_index = next_index; + cur_index = next_index; state = ReadCurrentState(); ...... diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 9c33c544..6aa5310d 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -53,6 +53,7 @@ int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size) { fEngineControl->fBufferSize = buffer_size; fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec + fGraphManager->SetBufferSize(buffer_size); return 0; } @@ -86,7 +87,7 @@ int JackAudioDriver::Attach() for (i = 0; i < fCaptureChannels; i++) { snprintf(buf, sizeof(buf) - 1, "%s:%s:out%d", fClientControl->fName, fCaptureDriverName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; } @@ -101,7 +102,7 @@ int JackAudioDriver::Attach() for (i = 0; i < fPlaybackChannels; i++) { snprintf(buf, sizeof(buf) - 1, "%s:%s:in%d", fClientControl->fName, fPlaybackDriverName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; } @@ -115,7 +116,7 @@ int JackAudioDriver::Attach() if (fWithMonitorPorts) { JackLog("Create monitor port \n"); snprintf(buf, sizeof(buf) - 1, "%s:%s:monitor_%u", fClientControl->fName, fPlaybackDriverName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JackPortIsOutput)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput)) == NO_PORT) { jack_error("Cannot register monitor port for %s", buf); return -1; } else { diff --git a/common/JackAudioPort.cpp b/common/JackAudioPort.cpp new file mode 100644 index 00000000..7b6548d8 --- /dev/null +++ b/common/JackAudioPort.cpp @@ -0,0 +1,95 @@ +/* +Copyright (C) 2001-2003 Paul Davis +Copyright (C) 2004-2006 Grame + +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 "JackPortType.h" +#include + +namespace Jack +{ + +static void AudioBufferInit(void* buffer, size_t buffer_size, jack_nframes_t) +{ + memset(buffer, 0, buffer_size); +} + +static inline void MixAudioBuffer(float* mixbuffer, float* buffer, jack_nframes_t frames) +{ + jack_nframes_t frames_group = frames / 4; + frames = frames % 4; + + while (frames_group > 0) { + register float mixFloat1 = *mixbuffer; + register float sourceFloat1 = *buffer; + register float mixFloat2 = *(mixbuffer + 1); + register float sourceFloat2 = *(buffer + 1); + register float mixFloat3 = *(mixbuffer + 2); + register float sourceFloat3 = *(buffer + 2); + register float mixFloat4 = *(mixbuffer + 3); + register float sourceFloat4 = *(buffer + 3); + + buffer += 4; + frames_group--; + + mixFloat1 += sourceFloat1; + mixFloat2 += sourceFloat2; + mixFloat3 += sourceFloat3; + mixFloat4 += sourceFloat4; + + *mixbuffer = mixFloat1; + *(mixbuffer + 1) = mixFloat2; + *(mixbuffer + 2) = mixFloat3; + *(mixbuffer + 3) = mixFloat4; + + mixbuffer += 4; + } + + while (frames > 0) { + register float mixFloat1 = *mixbuffer; + register float sourceFloat1 = *buffer; + buffer++; + frames--; + mixFloat1 += sourceFloat1; + *mixbuffer = mixFloat1; + mixbuffer++; + } +} + +static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes) +{ + void* buffer; + + // Copy first buffer + memcpy(mixbuffer, src_buffers[0], nframes * sizeof(float)); + + // Mix remaining buffers + for (int i = 1; i < src_count; ++i) { + buffer = src_buffers[i]; + MixAudioBuffer((float*)mixbuffer, (float*)buffer, nframes); + } +} + +const JackPortType gAudioPortType = { + JACK_DEFAULT_AUDIO_TYPE, + AudioBufferInit, + AudioBufferMixdown +}; + +} // namespace Jack + diff --git a/common/JackChannel.h b/common/JackChannel.h index df1414e2..e9969138 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -86,7 +86,7 @@ class JackClientChannelInterface virtual void ClientDeactivate(int refnum, int* result) {} - virtual void PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) + virtual void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) {} virtual void PortUnRegister(int refnum, jack_port_id_t port_index, int* result) {} diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 9bdabcae..99c90c53 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -414,11 +414,11 @@ int JackClient::PortRegister(const char* port_name, const char* port_type, unsig return 0; // Means failure here... } - JackLog("JackClient::PortRegister ref = %ld name = %s \n", GetClientControl()->fRefNum, name.c_str()); + JackLog("JackClient::PortRegister ref = %ld name = %s type = %s\n", GetClientControl()->fRefNum, name.c_str(), port_type); int result = -1; jack_port_id_t port_index = NO_PORT; - fChannel->PortRegister(GetClientControl()->fRefNum, name.c_str(), flags, buffer_size, &port_index, &result); + fChannel->PortRegister(GetClientControl()->fRefNum, name.c_str(), port_type, flags, buffer_size, &port_index, &result); JackLog("JackClient::PortRegister port_index = %ld \n", port_index); if (result == 0) { diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index e15abbc7..5d71be36 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -129,6 +129,7 @@ int JackDriver::Open(jack_nframes_t nframes, if (fEngineControl->fTimeOutUsecs == 0) /* usecs; if zero, use 2 period size. */ fEngineControl->fTimeOutUsecs = (jack_time_t)(2.f * fEngineControl->fPeriodUsecs); + fGraphManager->SetBufferSize(nframes); fGraphManager->DirectConnect(fClientControl->fRefNum, fClientControl->fRefNum); // Connect driver to itself for sync /* diff --git a/common/JackDummyDriver.h b/common/JackDummyDriver.h index 43d921a3..38ce03df 100644 --- a/common/JackDummyDriver.h +++ b/common/JackDummyDriver.h @@ -59,6 +59,7 @@ class JackDummyDriver : public JackAudioDriver jack_nframes_t playback_latency); int Process(); + }; } // end of namespace diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 8e82c3bf..46a7687a 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -680,12 +680,12 @@ int JackEngine::ClientDeactivate(int refnum) // Port management //----------------- -int JackEngine::PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index) +int JackEngine::PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index) { - JackLog("JackEngine::PortRegister ref = %ld name = %s flags = %d buffer_size = %d\n", refnum, name, flags, buffer_size); + JackLog("JackEngine::PortRegister ref = %ld name = %s type = %s flags = %d buffer_size = %d\n", refnum, name, type, flags, buffer_size); assert(fClientTable[refnum]); - *port_index = fGraphManager->AllocatePort(refnum, name, (JackPortFlags)flags); + *port_index = fGraphManager->AllocatePort(refnum, name, type, (JackPortFlags)flags); if (*port_index != NO_PORT) { NotifyPortRegistation(*port_index, true); return 0; diff --git a/common/JackEngine.h b/common/JackEngine.h index d329821b..312a320e 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -96,7 +96,7 @@ class JackEngine int InternalClientUnload(int refnum, int* status); // Port management - int PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index); + int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index); int PortUnRegister(int refnum, jack_port_id_t port); int PortConnect(int refnum, const char* src, const char* dst); diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 2e53e195..2c30df9e 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -165,31 +165,26 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff jack_int_t len = manager->Connections(port_index); if (len == 0) { // No connections: return a zero-filled buffer - float* buffer = GetBuffer(port_index); - memset(buffer, 0, buffer_size * sizeof(float)); // Clear buffer - return buffer; + port->ClearBuffer(buffer_size); + return port->GetBuffer(); } else if (len == 1) { // One connection: use zero-copy mode - just pass the buffer of the connected (output) port. assert(manager->GetPort(port_index, 0) != port_index); // Check recursion return GetBuffer(manager->GetPort(port_index, 0), buffer_size); } else { // Multiple connections + const jack_int_t* connections = manager->GetConnections(port_index); - float* mixbuffer = GetBuffer(port_index); - jack_port_id_t src_index; - float* buffer; - - // Copy first buffer - src_index = connections[0]; - AssertPort(src_index); - buffer = (float*)GetBuffer(src_index, buffer_size); - memcpy(mixbuffer, buffer, buffer_size * sizeof(float)); - - // Mix remaining buffers - for (int i = 1; (i < CONNECTION_NUM) && ((src_index = connections[i]) != EMPTY); i++) { + void* buffers[CONNECTION_NUM]; + jack_port_id_t src_index; + int i; + + for (i = 0; (i < CONNECTION_NUM) && ((src_index = connections[i]) != EMPTY); i++) { AssertPort(src_index); - buffer = (float*)GetBuffer(src_index, buffer_size); - JackPort::MixBuffer(mixbuffer, buffer, buffer_size); + buffers[i] = GetBuffer(src_index, buffer_size); } - return mixbuffer; + + JackPort* port = GetPort(port_index); + port->MixBuffers(buffers, i, buffer_size); + return port->GetBuffer(); } } @@ -202,7 +197,7 @@ int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // C /** jackd.h * If @ref JackPortCanMonitor is set for this @a port, turn input - * monitoring on or off. Otherwise, do nothing. + * monitoring on or off. Otherwise, do nothing. if (!(fFlags & JackPortCanMonitor)) return -1; @@ -266,7 +261,7 @@ jack_nframes_t JackGraphManager::GetTotalLatency(jack_port_id_t port_index) } // Server -jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_name, JackPortFlags flags) +jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) { jack_port_id_t port_index; @@ -274,8 +269,9 @@ jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_na for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) { JackPort* port = GetPort(port_index); if (!port->IsUsed()) { - JackLog("JackGraphManager::AllocatePortAux port_index = %ld name = %s\n", port_index, port_name); - port->Allocate(refnum, port_name, flags); + JackLog("JackGraphManager::AllocatePortAux port_index = %ld name = %s type = %s\n", port_index, port_name, port_type); + if (!port->Allocate(refnum, port_name, port_type, flags)) + return NO_PORT; break; } } @@ -284,12 +280,19 @@ jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_na } // Server -jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, JackPortFlags flags) +jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) { + JackLock lock(this); JackConnectionManager* manager = WriteNextStateStart(); - jack_port_id_t port_index = AllocatePortAux(refnum, port_name, flags); + jack_port_id_t port_index = AllocatePortAux(refnum, port_name, port_type, flags); + + assert(fBufferSize != 0); if (port_index != NO_PORT) { + JackPort* port = GetPort(port_index); + assert(port); + port->ClearBuffer(fBufferSize); + int res; if (flags & JackPortIsOutput) { res = manager->AddOutputPort(refnum, port_index); @@ -298,8 +301,6 @@ jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, } // Insertion failure if (res < 0) { - JackPort* port = GetPort(port_index); - assert(port); port->Release(); port_index = NO_PORT; } @@ -309,9 +310,26 @@ jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, return port_index; } +// Server +void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) +{ + JackLock lock(this); + JackLog("JackGraphManager::SetBufferSize size = %ld\n", (long int)buffer_size); + jack_port_id_t port_index; + + fBufferSize = buffer_size; + + for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) { + JackPort* port = GetPort(port_index); + if (port->IsUsed()) + port->ClearBuffer(fBufferSize); + } +} + // Server int JackGraphManager::ReleasePort(int refnum, jack_port_id_t port_index) { + JackLock lock(this); JackConnectionManager* manager = WriteNextStateStart(); JackPort* port = GetPort(port_index); int res; @@ -469,18 +487,23 @@ int JackGraphManager::Connect(jack_port_id_t port_src, jack_port_id_t port_dst) { JackConnectionManager* manager = WriteNextStateStart(); JackLog("JackGraphManager::Connect port_src = %ld port_dst = %ld\n", port_src, port_dst); - bool in_use_src = GetPort(port_src)->fInUse; - bool in_use_dst = GetPort(port_dst)->fInUse; + JackPort* src = GetPort(port_src); + JackPort* dst = GetPort(port_dst); int res = 0; - if (!in_use_src || !in_use_dst) { - if (!in_use_src) + if (!src->fInUse || !dst->fInUse) { + if (!src->fInUse) jack_error("JackGraphManager::Connect: port_src = %ld not used name = %s", port_src, GetPort(port_src)->fName); - if (!in_use_dst) + if (!dst->fInUse) jack_error("JackGraphManager::Connect: port_dst = %ld not used name = %s", port_dst, GetPort(port_dst)->fName); res = -1; goto end; } + if (src->fTypeId != dst->fTypeId) { + jack_error("JackGraphManager::Connect: different port types: port_src = %ld port_dst = %ld", port_src, port_dst); + res = -1; + goto end; + } if (manager->IsConnected(port_src, port_dst)) { jack_error("JackGraphManager::Connect already connected port_src = %ld port_dst = %ld", port_src, port_dst); res = EEXIST; diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index dd8af9d8..f4de7a70 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -26,6 +26,7 @@ This program is free software; you can redistribute it and/or modify #include "JackConstants.h" #include "JackConnectionManager.h" #include "JackAtomicState.h" +#include "JackMutex.h" namespace Jack { @@ -34,15 +35,16 @@ namespace Jack \brief Graph manager: contains the connection manager and the port array. */ -class JackGraphManager : public JackShmMem, public JackAtomicState +class JackGraphManager : public JackShmMem, public JackAtomicState, public JackLockAble { private: JackPort fPortArray[PORT_NUM]; JackClientTiming fClientTiming[CLIENT_NUM]; + jack_nframes_t fBufferSize; - jack_port_id_t AllocatePortAux(int refnum, const char* port_name, JackPortFlags flags); + jack_port_id_t AllocatePortAux(int refnum, const char* port_name, const char* port_type, JackPortFlags flags); void GetConnectionsAux(JackConnectionManager* manager, const char** res, jack_port_id_t port_index); const char** GetPortsAux(const char* port_name_pattern, const char* type_name_pattern, unsigned long flags); float* GetBuffer(jack_port_id_t port_index); @@ -51,13 +53,15 @@ class JackGraphManager : public JackShmMem, public JackAtomicStateClientDeactivate(refnum); } - void PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) + void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) { - *result = fEngine->PortRegister(refnum, name, flags, buffer_size, port_index); + *result = fEngine->PortRegister(refnum, name, type, flags, buffer_size, port_index); } void PortUnRegister(int refnum, jack_port_id_t port_index, int* result) { diff --git a/common/JackMidiAPI.cpp b/common/JackMidiAPI.cpp new file mode 100644 index 00000000..f6abb56c --- /dev/null +++ b/common/JackMidiAPI.cpp @@ -0,0 +1,133 @@ +/* +Copyright (C) 2007 Dmitry Baikov +Original JACK MIDI implementation Copyright (C) 2004 Ian Esten + +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 "JackError.h" +#include "JackMidiPort.h" +#include "JackExports.h" +#include +#include + + +#ifdef WIN32 +#define ENOBUFS 55 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + EXPORT jack_nframes_t jack_midi_get_event_count(void* port_buffer); + + EXPORT int jack_midi_event_get(jack_midi_event_t* event, + void* port_buffer, jack_nframes_t event_index); + + EXPORT void jack_midi_clear_buffer(void* port_buffer); + + EXPORT size_t jack_midi_max_event_size(void* port_buffer); + + EXPORT jack_midi_data_t* jack_midi_event_reserve(void* port_buffer, + jack_nframes_t time, size_t data_size); + + EXPORT int jack_midi_event_write(void* port_buffer, + jack_nframes_t time, const jack_midi_data_t* data, size_t data_size); + + EXPORT jack_nframes_t jack_midi_get_lost_event_count(void* port_buffer); + +#ifdef __cplusplus +} +#endif + +using namespace Jack; + +EXPORT +jack_nframes_t jack_midi_get_event_count(void* port_buffer) +{ + JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; + if (!buf || !buf->IsValid()) + return 0; + return buf->event_count; +} + +EXPORT +int jack_midi_event_get(jack_midi_event_t *event, void* port_buffer, jack_nframes_t event_index) +{ + JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; + if (!buf || !buf->IsValid()) + return -EINVAL; + if (event_index < 0 || event_index >= buf->event_count) + return -ENOBUFS; + JackMidiEvent* ev = &buf->events[event_index]; + event->time = ev->time; + event->size = ev->size; + event->buffer = ev->GetData(buf); + return 0; +} + +EXPORT +void jack_midi_clear_buffer(void* port_buffer) +{ + JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; + if (buf && buf->IsValid()) + buf->Reset(buf->nframes); +} + +EXPORT +size_t jack_midi_max_event_size(void* port_buffer) +{ + JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; + if (buf && buf->IsValid()) + return buf->MaxEventSize(); + return 0; +} + +EXPORT +jack_midi_data_t* jack_midi_event_reserve(void* port_buffer, jack_nframes_t time, size_t data_size) +{ + JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; + if (!buf && !buf->IsValid()) + return 0; + if (time < 0 || time >= buf->nframes || (buf->event_count && buf->events[buf->event_count - 1].time > time)) + return 0; + return buf->ReserveEvent(time, data_size); +} + +EXPORT +int jack_midi_event_write(void* port_buffer, + jack_nframes_t time, const jack_midi_data_t* data, size_t data_size) +{ + JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; + if (!buf && !buf->IsValid()) + return -EINVAL; + if (time < 0 || time >= buf->nframes || (buf->event_count && buf->events[buf->event_count - 1].time > time)) + return -EINVAL; + jack_midi_data_t* dest = buf->ReserveEvent(time, data_size); + if (!dest) + return -ENOBUFS; + memcpy(dest, data, data_size); + return 0; +} + +EXPORT +jack_nframes_t jack_midi_get_lost_event_count(void* port_buffer) +{ + JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; + if (buf && buf->IsValid()) + return buf->lost_events; + return 0; +} diff --git a/common/JackMidiPort.cpp b/common/JackMidiPort.cpp new file mode 100644 index 00000000..6a7b42c8 --- /dev/null +++ b/common/JackMidiPort.cpp @@ -0,0 +1,140 @@ +/* +Copyright (C) 2007 Dmitry Baikov +Original JACK MIDI implementation Copyright (C) 2004 Ian Esten + +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 "JackError.h" +#include "JackPortType.h" +#include "JackMidiPort.h" +#include +#include + +namespace Jack +{ + +void JackMidiBuffer::Reset(jack_nframes_t nframes) +{ + /* This line ate 1 hour of my life... dsbaikov */ + this->nframes = nframes; + write_pos = 0; + event_count = 0; + lost_events = 0; + mix_index = 0; +} + +jack_shmsize_t JackMidiBuffer::MaxEventSize() const +{ + assert (((jack_shmsize_t) - 1) < 0); // jack_shmsize_t should be signed + jack_shmsize_t left = buffer_size - (sizeof(JackMidiBuffer) + sizeof(JackMidiEvent) * (event_count + 1) + write_pos); + if (left < 0) + return 0; + if (left <= JackMidiEvent::INLINE_SIZE_MAX) + return JackMidiEvent::INLINE_SIZE_MAX; + return left; +} + +jack_midi_data_t* JackMidiBuffer::ReserveEvent(jack_nframes_t time, jack_shmsize_t size) +{ + jack_shmsize_t space = MaxEventSize(); + if (space == 0 || size > space) { + lost_events++; + return 0; + } + + JackMidiEvent* event = &events[event_count++]; + event->time = time; + event->size = size; + if (size <= JackMidiEvent::INLINE_SIZE_MAX) + return event->data; + + write_pos += size; + event->offset = buffer_size - write_pos; + return (jack_midi_data_t*)this + event->offset; +} + +static void MidiBufferInit(void* buffer, size_t buffer_size, jack_nframes_t nframes) +{ + JackMidiBuffer* midi = (JackMidiBuffer*)buffer; + midi->magic = JackMidiBuffer::MAGIC; + midi->buffer_size = buffer_size; + midi->Reset(nframes); +} + +/* + * The mixdown function below, is a simplest (read slowest) implementation possible. + * But, since it is unlikely that it will mix many buffers with many events, + * it should perform quite good. + * More efficient (and possibly, fastest possible) implementation (it exists), + * using calendar queue algorithm is about 3 times bigger, and uses alloca(). + * So, let's listen to D.Knuth about premature optimisation, a leave the current + * implementation as is, until it is proved to be a bottleneck. + * Dmitry Baikov. + */ +static void MidiBufferMixdown(void* mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes) +{ + JackMidiBuffer* mix = (JackMidiBuffer*)mixbuffer; + if (!mix->IsValid()) { + jack_error("MIDI: invalid mix buffer"); + return; + } + mix->Reset(nframes); + + int event_count = 0; + for (int i = 0; i < src_count; ++i) { + JackMidiBuffer* buf = (JackMidiBuffer*)src_buffers[i]; + if (!buf->IsValid()) + return; + buf->mix_index = 0; + event_count += buf->event_count; + mix->lost_events += buf->lost_events; + } + + int events_done; + for (events_done = 0; events_done < event_count; ++events_done) { + JackMidiBuffer* next_buf = 0; + JackMidiEvent* next_event = 0; + + // find the earliest event + for (int i = 0; i < src_count; ++i) { + JackMidiBuffer* buf = (JackMidiBuffer*)src_buffers[i]; + if (buf->mix_index >= buf->event_count) + continue; + JackMidiEvent* e = &buf->events[buf->mix_index]; + if (!next_event || e->time < next_event->time) { + next_event = e; + next_buf = buf; + } + } + assert (next_event != 0); + + // write the event + jack_midi_data_t* dest = mix->ReserveEvent(next_event->time, next_event->size); + if (!dest) + break; + memcpy(dest, next_event->GetData(next_buf), next_event->size); + next_buf->mix_index++; + } + mix->lost_events += event_count - events_done; +} + +const JackPortType gMidiPortType = { + JACK_DEFAULT_MIDI_TYPE, + MidiBufferInit, + MidiBufferMixdown +}; + +} // namespace Jack diff --git a/common/JackMidiPort.h b/common/JackMidiPort.h new file mode 100644 index 00000000..bb30d7cc --- /dev/null +++ b/common/JackMidiPort.h @@ -0,0 +1,97 @@ +/* +Copyright (C) 2007 Dmitry Baikov +Original JACK MIDI API implementation Copyright (C) 2004 Ian Esten + +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 __JackMidiPort__ +#define __JackMidiPort__ + +#include "types.h" +#include "JackConstants.h" +#include + +/** Type for raw event data contained in @ref jack_midi_event_t. */ +typedef unsigned char jack_midi_data_t; + +/** A Jack MIDI event. */ +struct jack_midi_event_t +{ + jack_nframes_t time; /**< Sample index at which event is valid */ + size_t size; /**< Number of bytes of data in \a buffer */ + jack_midi_data_t *buffer; /**< Raw MIDI data */ +}; + +/** A Jack MIDI port type. */ +#define JACK_DEFAULT_MIDI_TYPE "8 bit raw midi" + +namespace Jack +{ + +struct JackMidiEvent +{ + // Most MIDI events are < 4 bytes in size, so we can save a lot, storing them inplace. + enum { INLINE_SIZE_MAX = sizeof(jack_shmsize_t) }; + + uint32_t time; + jack_shmsize_t size; + union { + jack_shmsize_t offset; + jack_midi_data_t data[INLINE_SIZE_MAX]; + }; + + jack_midi_data_t* GetData(void* buffer) + { + if (size <= INLINE_SIZE_MAX) + return data; + else + return (jack_midi_data_t*)buffer + offset; + } +}; + +/* + * To store events with arbitrarily sized payload, but still have O(1) indexed access + * we use a trick here: + * Events are stored in an linear array from the beginning of the buffer, + * but their data (if not inlined) is stored from the end of the same buffer. + */ + +struct JackMidiBuffer +{ + enum { MAGIC = 0x900df00d }; + + uint32_t magic; + jack_shmsize_t buffer_size; + jack_nframes_t nframes; + jack_shmsize_t write_pos; //!< data write position from the end of the buffer. + uint32_t event_count; + uint32_t lost_events; + uint32_t mix_index; + + JackMidiEvent events[0]; + + int IsValid() const { return magic == MAGIC; } + void Reset(jack_nframes_t nframes); + jack_shmsize_t MaxEventSize() const; + + // checks only size constraints. + jack_midi_data_t* ReserveEvent(jack_nframes_t time, jack_shmsize_t size); +}; + +} // namespace Jack + +#endif diff --git a/common/JackMutex.h b/common/JackMutex.h new file mode 100644 index 00000000..5f0c9ec0 --- /dev/null +++ b/common/JackMutex.h @@ -0,0 +1,151 @@ + /* + + Copyright (C) 2006 Grame + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Grame Research Laboratory, 9 rue du Garet, 69001 Lyon - France + grame@grame.fr + +*/ + +#ifndef __JackMutex__ +#define __JackMutex__ + +#ifdef WIN32 +#include +#else +#include +#endif + +#include + +namespace Jack +{ + +class JackMutex +{ + + private: + + #ifdef WIN32 + HANDLE fMutex; + #else + pthread_mutex_t fMutex; + #endif + + public: + + #ifdef WIN32 + + JackMutex() + { + fMutex = CreateMutex(0, FALSE, 0); + } + virtual ~JackMutex() + { + CloseHandle(fMutex); + } + + void Lock() + { + DWORD dwWaitResult = WaitForSingleObject(fMutex, INFINITE); + } + + void Unlock() + { + ReleaseMutex(fMutex); + } + + #else + + JackMutex() + { + // Use recursive mutex + pthread_mutexattr_t mutex_attr; + assert(pthread_mutexattr_init(&mutex_attr) == 0); + assert(pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE) == 0); + assert(pthread_mutex_init(&fMutex, &mutex_attr) == 0); + } + virtual ~JackMutex() + { + pthread_mutex_destroy(&fMutex); + } + + void Lock() + { + pthread_mutex_lock(&fMutex); + } + + void Unlock() + { + pthread_mutex_unlock(&fMutex); + } + + #endif +}; + +class JackLockAble +{ + + private: + + JackMutex fMutex; + + public: + + JackLockAble() {} + virtual ~JackLockAble() {} + + void Lock() + { + fMutex.Lock(); + } + + void Unlock() + { + fMutex.Unlock(); + } + +}; + +class JackLock +{ + private: + + JackLockAble* fObj; + + public: + + JackLock(JackLockAble* obj):fObj(obj) + { + fObj->Lock(); + } + + JackLock(const JackLockAble* obj):fObj((JackLockAble*)obj) + { + fObj->Lock(); + } + + virtual ~JackLock() + { + fObj->Unlock(); + } +}; + + +} // namespace + +#endif diff --git a/common/JackPort.cpp b/common/JackPort.cpp index 3632e531..be766774 100644 --- a/common/JackPort.cpp +++ b/common/JackPort.cpp @@ -20,9 +20,11 @@ This program is free software; you can redistribute it and/or modify #include "JackPort.h" #include "JackError.h" +#include "JackPortType.h" #include #include + namespace Jack { @@ -33,26 +35,37 @@ JackPort::JackPort() JackPort::~JackPort() {} -void JackPort::Allocate(int refnum, const char* port_name, JackPortFlags flags) +bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) { + int id = GetPortTypeId(port_type); + if (id < 0) + return false; + fTypeId = id; fFlags = flags; fRefNum = refnum; strcpy(fName, port_name); - memset(fBuffer, 0, BUFFER_SIZE_MAX * sizeof(float)); fInUse = true; fLocked = false; fLatency = 0; fTied = NO_PORT; + // DB: At this point we do not know current buffer size in frames, + // but every time buffer will be returned to any user, + // it will be called with either ClearBuffer or MixBuffers + // with correct current buffer size. + // So it is safe to init with 0 here. + ClearBuffer(0); + return true; } void JackPort::Release() { + fTypeId = 0; fFlags = JackPortIsInput; fRefNum = -1; fInUse = false; fLocked = false; fLatency = 0; - fTied = NO_PORT; + fTied = NO_PORT; fAlias1[0] = '\0'; fAlias2[0] = '\0'; } @@ -175,8 +188,8 @@ int JackPort::Flags() const const char* JackPort::Type() const { - // TO IMPROVE - return JACK_DEFAULT_AUDIO_TYPE; + const JackPortType* type = GetPortType(fTypeId); + return type->name; } int JackPort::SetName(const char* new_name) @@ -243,46 +256,16 @@ int JackPort::UnsetAlias(const char* alias) return 0; } -void JackPort::MixBuffer(float* mixbuffer, float* buffer, jack_nframes_t frames) +void JackPort::ClearBuffer(jack_nframes_t frames) { - jack_nframes_t frames_group = frames / 4; - frames = frames % 4; - - while (frames_group > 0) { - register float mixFloat1 = *mixbuffer; - register float sourceFloat1 = *buffer; - register float mixFloat2 = *(mixbuffer + 1); - register float sourceFloat2 = *(buffer + 1); - register float mixFloat3 = *(mixbuffer + 2); - register float sourceFloat3 = *(buffer + 2); - register float mixFloat4 = *(mixbuffer + 3); - register float sourceFloat4 = *(buffer + 3); - - buffer += 4; - frames_group--; - - mixFloat1 += sourceFloat1; - mixFloat2 += sourceFloat2; - mixFloat3 += sourceFloat3; - mixFloat4 += sourceFloat4; - - *mixbuffer = mixFloat1; - *(mixbuffer + 1) = mixFloat2; - *(mixbuffer + 2) = mixFloat3; - *(mixbuffer + 3) = mixFloat4; - - mixbuffer += 4; - } + const JackPortType* type = GetPortType(fTypeId); + (type->init)(fBuffer, BUFFER_SIZE_MAX * sizeof(float), frames); +} - while (frames > 0) { - register float mixFloat1 = *mixbuffer; - register float sourceFloat1 = *buffer; - buffer++; - frames--; - mixFloat1 += sourceFloat1; - *mixbuffer = mixFloat1; - mixbuffer++; - } +void JackPort::MixBuffers(void** src_buffers, int src_count, jack_nframes_t buffer_size) +{ + const JackPortType* type = GetPortType(fTypeId); + (type->mixdown)(fBuffer, src_buffers, src_count, buffer_size); } } // end of namespace diff --git a/common/JackPort.h b/common/JackPort.h index 73a25980..df285587 100644 --- a/common/JackPort.h +++ b/common/JackPort.h @@ -41,6 +41,7 @@ class JackPort private: + int fTypeId; enum JackPortFlags fFlags; char fName[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char fAlias1[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; @@ -66,14 +67,16 @@ class JackPort bool IsUsed() const; - static void MixBuffer(float* mixbuffer, float* buffer, jack_nframes_t frames); + // RT + void ClearBuffer(jack_nframes_t frames); + void MixBuffers(void** src_buffers, int src_count, jack_nframes_t frames); public: JackPort(); virtual ~JackPort(); - void Allocate(int refnum, const char* port_name, JackPortFlags flags); + bool Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags); void Release(); const char* GetName() const; const char* GetShortName() const; diff --git a/common/JackPortType.cpp b/common/JackPortType.cpp new file mode 100644 index 00000000..47c7fff5 --- /dev/null +++ b/common/JackPortType.cpp @@ -0,0 +1,53 @@ +/* +Copyright (C) 2007 Dmitry Baikov + +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 "JackPortType.h" +#include +#include + +namespace Jack +{ + +static const JackPortType* port_types[] = { + &gAudioPortType, + &gMidiPortType, +}; + +enum { PORT_TYPES_MAX = sizeof(port_types)/sizeof(port_types[0]) }; + +int GetPortTypeId(const char* port_type) +{ + for (int i = 0; i < PORT_TYPES_MAX; ++i) { + const JackPortType* type = port_types[i]; + assert(type != 0); + if (strcmp(port_type, type->name) == 0) + return i; + } + return -1; +} + +const JackPortType* GetPortType(int type_id) +{ + assert(type_id >= 0 && type_id <= PORT_TYPES_MAX); + const JackPortType* type = port_types[type_id]; + assert(type != 0); + return type; +} + +} // namespace Jack diff --git a/common/JackPortType.h b/common/JackPortType.h new file mode 100644 index 00000000..a22c29a7 --- /dev/null +++ b/common/JackPortType.h @@ -0,0 +1,44 @@ +/* +Copyright (C) 2007 Dmitry Baikov + +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 __JackPortType__ +#define __JackPortType__ + +#include "types.h" +#include "JackConstants.h" +#include + +namespace Jack +{ + +struct JackPortType { + const char* name; + void (*init)(void* buffer, size_t buffer_size, jack_nframes_t nframes); + void (*mixdown)(void *mixbuffer, void** src_buffers, int src_count, jack_nframes_t nframes); +}; + +extern int GetPortTypeId(const char* port_type); +extern const JackPortType* GetPortType(int port_type_id); + +extern const JackPortType gAudioPortType; +extern const JackPortType gMidiPortType; + +} // namespace Jack + +#endif diff --git a/common/JackSocketClientChannel.cpp b/common/JackSocketClientChannel.cpp index 7ac31259..3b2da682 100644 --- a/common/JackSocketClientChannel.cpp +++ b/common/JackSocketClientChannel.cpp @@ -179,9 +179,9 @@ void JackSocketClientChannel::ClientDeactivate(int refnum, int* result) ServerSyncCall(&req, &res, result); } -void JackSocketClientChannel::PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) +void JackSocketClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) { - JackPortRegisterRequest req(refnum, name, "audio", flags, buffer_size); + JackPortRegisterRequest req(refnum, name, type, flags, buffer_size); JackPortRegisterResult res; ServerSyncCall(&req, &res, result); *port_index = res.fPortIndex; diff --git a/common/JackSocketClientChannel.h b/common/JackSocketClientChannel.h index 3c1b5212..66239b4a 100644 --- a/common/JackSocketClientChannel.h +++ b/common/JackSocketClientChannel.h @@ -66,7 +66,7 @@ class JackSocketClientChannel : public JackClientChannelInterface, public JackRu void ClientActivate(int refnum, int* result); void ClientDeactivate(int refnum, int* result); - void PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); + void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); void PortUnRegister(int refnum, jack_port_id_t port_index, int* result); void PortConnect(int refnum, const char* src, const char* dst, int* result); diff --git a/common/JackSocketServerChannel.cpp b/common/JackSocketServerChannel.cpp index 53ae3d55..8d6e76d2 100644 --- a/common/JackSocketServerChannel.cpp +++ b/common/JackSocketServerChannel.cpp @@ -207,7 +207,7 @@ int JackSocketServerChannel::HandleRequest(int fd) JackPortRegisterRequest req; JackPortRegisterResult res; if (req.Read(socket) == 0) - res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fFlags, req.fBufferSize, &res.fPortIndex); + res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex); res.Write(socket); break; } diff --git a/common/jack/midiport.h b/common/jack/midiport.h new file mode 100644 index 00000000..da574f8d --- /dev/null +++ b/common/jack/midiport.h @@ -0,0 +1,153 @@ +/* + Copyright (C) 2004 Ian Esten + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + +#ifndef __JACK_MIDIPORT_H +#define __JACK_MIDIPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +/** Type for raw event data contained in @ref jack_midi_event_t. */ +typedef unsigned char jack_midi_data_t; + + +/** A Jack MIDI event. */ +typedef struct _jack_midi_event +{ + jack_nframes_t time; /**< Sample index at which event is valid */ + size_t size; /**< Number of bytes of data in \a buffer */ + jack_midi_data_t *buffer; /**< Raw MIDI data */ +} jack_midi_event_t; + + +/* Get number of events in a port buffer. + * + * @param port_buffer Port buffer from which to retrieve event. + * @return number of events inside @a port_buffer + */ +jack_nframes_t +jack_midi_get_event_count(void* port_buffer); + + +/** Get a MIDI event from an event port buffer. + * + * Jack MIDI is normalised, the MIDI event returned by this function is + * guaranteed to be a complete MIDI event (the status byte will always be + * present, and no realtime events will interspered with the event). + * + * @param event Event structure to store retrieved event in. + * @param port_buffer Port buffer from which to retrieve event. + * @param event_index Index of event to retrieve. + * @return 0 on success, ENODATA if buffer is empty. + */ +int +jack_midi_event_get(jack_midi_event_t *event, + void *port_buffer, + jack_nframes_t event_index); + + +/** Clear an event buffer. + * + * This should be called at the beginning of each process cycle before calling + * @ref jack_midi_event_reserve or @ref jack_midi_event_write. This + * function may not be called on an input port's buffer. + * + * @param port_buffer Port buffer to clear (must be an output port buffer). + */ +void +jack_midi_clear_buffer(void *port_buffer); + + +/** Get the size of the largest event that can be stored by the port. + * + * This function returns the current space available, taking into account + * events already stored in the port. + * + * @param port_buffer Port buffer to check size of. + */ +size_t +jack_midi_max_event_size(void* port_buffer); + + +/** Allocate space for an event to be written to an event port buffer. + * + * Clients are to write the actual event data to be written starting at the + * pointer returned by this function. Clients must not write more than + * @a data_size bytes into this buffer. Clients must write normalised + * MIDI data to the port - no running status and no (1-byte) realtime + * messages interspersed with other messages (realtime messages are fine + * when they occur on their own, like other messages). + * + * @param port_buffer Buffer to write event to. + * @param time Sample offset of event. + * @param data_size Length of event's raw data in bytes. + * @return Pointer to the beginning of the reserved event's data buffer, or + * NULL on error (ie not enough space). + */ +jack_midi_data_t* +jack_midi_event_reserve(void *port_buffer, + jack_nframes_t time, + size_t data_size); + + +/** Write an event into an event port buffer. + * + * This function is simply a wrapper for @ref jack_midi_event_reserve + * which writes the event data into the space reserved in the buffer. + * The same restrictions on the MIDI data apply. + * + * @param port_buffer Buffer to write event to. + * @param time Sample offset of event. + * @param data Message data to be written. + * @param data_size Length of @a data in bytes. + * @return 0 on success, ENOBUFS if there's not enough space in buffer for event. + */ +int +jack_midi_event_write(void *port_buffer, + jack_nframes_t time, + const jack_midi_data_t *data, + size_t data_size); + + +/** Get the number of events that could not be written to @a port_buffer. + * + * This function returning a non-zero value implies @a port_buffer is full. + * Currently the only way this can happen is if events are lost on port mixdown. + * + * @param port_buffer Port to receive count for. + * @returns Number of events that could not be written to @a port_buffer. + */ +jack_nframes_t +jack_midi_get_lost_event_count(void *port_buffer); + + +#ifdef __cplusplus +} +#endif + + +#endif /* __JACK_MIDIPORT_H */ + + diff --git a/linux/Makefile b/linux/Makefile index 53bd15b9..e53910a7 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -30,12 +30,14 @@ LIB_LINUX := -lpthread -lrt -lasound objects_common_server_lib := JackActivationCount.o JackAPI.o JackAudioDriver.o JackClient.o JackConnectionManager.o \ JackDriver.o JackEngine.o JackEngineTiming.o JackError.o JackExternalClient.o JackFrameTimer.o \ JackFreewheelDriver.o JackGlobalsServer.o JackGraphManager.o JackInternalClient.o JackPort.o JackPosixSemaphore.o JackPosixThread.o JackFifo.o JackLoopbackDriver.o\ + JackPortType.o JackAudioPort.o JackMidiPort.o \ JackServer.o JackShmMem.o JackThreadedDriver.o shm.o JackSocket.o JackSocketServerChannel.o JackSocketNotifyChannel.o \ JackSocketServerNotifyChannel.o JackTime.o JackServerAPI.o JackGlobals.o JackDriverLoader.o internal_metro.o JackDebugClient.o \ JackTransportEngine.o JackServerGlobals.o JackServerLaunch.o timestamps.o objects_common_client_lib := JackActivationCount.o JackAPI.o JackClient.o JackConnectionManager.o ringbuffer.o JackServerLaunch.o\ JackError.o JackFrameTimer.o JackGlobalsClient.o JackGraphManager.o JackLibClient.o JackLibAPI.o JackPort.o JackPosixSemaphore.o JackFifo.o \ + JackPortType.o JackAudioPort.o JackMidiPort.o JackMidiAPI.o \ JackPosixThread.o JackShmMem.o shm.o JackSocket.o JackSocketClientChannel.o JackTime.o JackGlobals.o JackDebugClient.o JackTransportEngine.o timestamps.o diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 3863dbb4..61cc0c4d 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -1504,20 +1504,21 @@ JackAlsaDriver::alsa_driver_wait (alsa_driver_t *driver, int extra_fd, int *stat return avail - (avail % driver->frames_per_cycle); } -int JackAlsaDriver::SetBufferSize(jack_nframes_t nframes) +int JackAlsaDriver::SetBufferSize(jack_nframes_t buffer_size) { JackLog("JackAlsaDriver::SetBufferSize %ld\n", nframes); int res = alsa_driver_reset_parameters((alsa_driver_t *)fDriver, nframes, ((alsa_driver_t *)fDriver)->user_nperiods, ((alsa_driver_t *)fDriver)->frame_rate); - if (res == 0) // update fEngineControl and fGraphManager - JackAudioDriver::SetBufferSize(nframes); // never fails - else + if (res == 0) { // update fEngineControl and fGraphManager + JackAudioDriver::SetBufferSize(buffer_size); // never fails + } else { alsa_driver_reset_parameters((alsa_driver_t *)fDriver, fEngineControl->fBufferSize, ((alsa_driver_t *)fDriver)->user_nperiods, ((alsa_driver_t *)fDriver)->frame_rate); - + } + return res; } @@ -2087,7 +2088,7 @@ int JackAlsaDriver::Attach() for (int i = 0; i < fCaptureChannels; i++) { snprintf(buf, sizeof(buf) - 1, "%s:capture_%u", fClientControl->fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; } @@ -2102,7 +2103,7 @@ int JackAlsaDriver::Attach() for (int i = 0; i < fPlaybackChannels; i++) { snprintf(buf, sizeof(buf) - 1, "%s:playback_%u", fClientControl->fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags)) == NO_PORT) { jack_error("driver: cannot register port for %s", buf); return -1; } @@ -2112,19 +2113,19 @@ int JackAlsaDriver::Attach() fPlaybackPortList[i] = port_index; JackLog("JackAudioDriver::Attach fPlaybackPortList[i] %ld \n", port_index); - // Monitor ports - if (fWithMonitorPorts) { - JackLog("Create monitor port \n"); - snprintf(buf, sizeof(buf) - 1, "%s:monitor_%lu",fClientControl->fName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JackPortIsOutput)) == NO_PORT) { - jack_error ("ALSA: cannot register monitor port for %s", buf); - } else { - port = fGraphManager->GetPort(port_index); - port->SetLatency(alsa_driver->frames_per_cycle); - fMonitorPortList[i] = port_index; + // Monitor ports + if (fWithMonitorPorts) { + JackLog("Create monitor port \n"); + snprintf(buf, sizeof(buf) - 1, "%s:monitor_%lu",fClientControl->fName, i + 1); + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput)) == NO_PORT) { + jack_error ("ALSA: cannot register monitor port for %s", buf); + } else { + port = fGraphManager->GetPort(port_index); + port->SetLatency(alsa_driver->frames_per_cycle); + fMonitorPortList[i] = port_index; + } } } - } return 0; } diff --git a/macosx/JackCoreAudioDriver.cpp b/macosx/JackCoreAudioDriver.cpp index 456046b6..bef99867 100644 --- a/macosx/JackCoreAudioDriver.cpp +++ b/macosx/JackCoreAudioDriver.cpp @@ -816,7 +816,7 @@ int JackCoreAudioDriver::Attach() snprintf(buf, sizeof(buf) - 1, "%s:%s:out%u", fClientControl->fName, fCaptureDriverName, i + 1); } - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags)) == NO_PORT) { jack_error("Cannot register port for %s", buf); return -1; } @@ -853,7 +853,7 @@ int JackCoreAudioDriver::Attach() snprintf(buf, sizeof(buf) - 1, "%s:%s:in%u", fClientControl->fName, fPlaybackDriverName, i + 1); } - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, (JackPortFlags)port_flags)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, (JackPortFlags)port_flags)) == NO_PORT) { jack_error("Cannot register port for %s", buf); return -1; } @@ -877,7 +877,7 @@ int JackCoreAudioDriver::Attach() if (fWithMonitorPorts) { JackLog("Create monitor port \n"); snprintf(buf, sizeof(buf) - 1, "%s:%s:monitor_%u", fClientControl->fName, fPlaybackDriverName, i + 1); - if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JackPortIsOutput)) == NO_PORT) { + if ((port_index = fGraphManager->AllocatePort(fClientControl->fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput)) == NO_PORT) { jack_error("Cannot register monitor port for %s", buf); return -1; } else { @@ -937,7 +937,7 @@ int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) printError(err); return -1; } - + JackAudioDriver::SetBufferSize(buffer_size); // never fails // Input buffers do no change : prepare them only once diff --git a/macosx/JackMacEngineRPC.cpp b/macosx/JackMacEngineRPC.cpp index 117457d6..d1bd93ea 100644 --- a/macosx/JackMacEngineRPC.cpp +++ b/macosx/JackMacEngineRPC.cpp @@ -81,12 +81,12 @@ rpc_type server_rpc_jack_client_deactivate(mach_port_t private_port, int refnum, // Port management //----------------- -rpc_type server_rpc_jack_port_register(mach_port_t private_port, int refnum, client_port_name_t name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) +rpc_type server_rpc_jack_port_register(mach_port_t private_port, int refnum, client_port_name_t name, client_port_type_t type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) { JackLog("rpc_jack_port_register %ld %s\n", refnum, name); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); - *result = channel->GetEngine()->PortRegister(refnum, name, flags, buffer_size, port_index); + *result = channel->GetEngine()->PortRegister(refnum, name, type, flags, buffer_size, port_index); return KERN_SUCCESS; } diff --git a/macosx/JackMachClientChannel.cpp b/macosx/JackMachClientChannel.cpp index 1bcfdd19..f598ed16 100644 --- a/macosx/JackMachClientChannel.cpp +++ b/macosx/JackMachClientChannel.cpp @@ -169,9 +169,9 @@ void JackMachClientChannel::ClientDeactivate(int refnum, int* result) } } -void JackMachClientChannel::PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) +void JackMachClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) { - kern_return_t res = rpc_jack_port_register(fPrivatePort, refnum, (char*)name, flags, buffer_size, port_index, result); + kern_return_t res = rpc_jack_port_register(fPrivatePort, refnum, (char*)name, (char*)type, flags, buffer_size, port_index, result); if (res != KERN_SUCCESS) { *result = -1; jack_error("JackMachClientChannel::PortRegister err = %s", mach_error_string(res)); diff --git a/macosx/JackMachClientChannel.h b/macosx/JackMachClientChannel.h index a2610d3a..f1a0031f 100644 --- a/macosx/JackMachClientChannel.h +++ b/macosx/JackMachClientChannel.h @@ -63,7 +63,7 @@ class JackMachClientChannel : public JackClientChannelInterface, public JackRunn void ClientActivate(int refnum, int* result); void ClientDeactivate(int refnum, int* result); - void PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); + void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); void PortUnRegister(int refnum, jack_port_id_t port_index, int* result); void PortConnect(int refnum, const char* src, const char* dst, int* result); diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 377b2824..4bef5d0b 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -247,6 +247,8 @@ 4B699D9B097D421700A18468 /* JackCoreAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B395C9606AEF53800923527 /* JackCoreAudioDriver.cpp */; }; 4B699DA8097D421700A18468 /* JackDummyDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */; }; 4B699DAA097D421700A18468 /* JackDummyDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */; }; + 4B6B9EF60CD095930051EE5A /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B6B9EF70CD095970051EE5A /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73800CC60A7F001AFFD4 /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73810CC60A7F001AFFD4 /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C73820CC60A7F001AFFD4 /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -259,10 +261,22 @@ 4B6C73890CC60A85001AFFD4 /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C738A0CC60A85001AFFD4 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C738B0CC60A86001AFFD4 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B80D7E80BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; + 4B80D7E90BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; + 4B80D7EA0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; + 4B80D7EB0BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; + 4B80D7EC0BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; + 4B80D7ED0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4B978DED0A31D099009E2DD1 /* JackPortAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B978DEB0A31D099009E2DD1 /* JackPortAudioDriver.h */; }; 4B978DEE0A31D099009E2DD1 /* JackPortAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B978DEC0A31D099009E2DD1 /* JackPortAudioDriver.cpp */; }; 4BA692B30CBE4C2D00EAD520 /* ipload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692B20CBE4C2D00EAD520 /* ipload.c */; }; 4BA692D70CBE4CC600EAD520 /* ipunload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692D60CBE4CC600EAD520 /* ipunload.c */; }; + 4BAB95B80B9E20B800A0C723 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; + 4BAB95B90B9E20B800A0C723 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; + 4BAB95BA0B9E20B800A0C723 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; + 4BAB95BB0B9E20B800A0C723 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; + 4BAB95ED0B9E21A500A0C723 /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; + 4BAB95EE0B9E21A500A0C723 /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; 4BC216850A444BAD00BDA09F /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; 4BC216890A444BDE00BDA09F /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; 4BC2168E0A444BED00BDA09F /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; @@ -279,7 +293,6 @@ 4BF520540CB8D0E80037470E /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4BF520590CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BF5205A0CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4BF5205B0CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; }; 4BFA99AA0AAAF40C009E916C /* jdelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFA99A90AAAF40C009E916C /* jdelay.cpp */; }; /* End PBXBuildFile section */ @@ -504,6 +517,7 @@ 4B699D91097D421700A18468 /* synchroServerClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = synchroServerClient; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699DA1097D421700A18468 /* jack_coreaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_coreaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B699DB0097D421700A18468 /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B6B9EF50CD0958B0051EE5A /* midiport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = midiport.h; path = ../common/jack/midiport.h; sourceTree = SOURCE_ROOT; }; 4B6C73790CC60A6D001AFFD4 /* intclient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = intclient.h; path = ../common/jack/intclient.h; sourceTree = SOURCE_ROOT; }; 4B6C737A0CC60A6D001AFFD4 /* jack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = jack.h; path = ../common/jack/jack.h; sourceTree = SOURCE_ROOT; }; 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ringbuffer.h; path = ../common/jack/ringbuffer.h; sourceTree = SOURCE_ROOT; }; @@ -513,6 +527,9 @@ 4B6C737F0CC60A6D001AFFD4 /* types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../common/jack/types.h; sourceTree = SOURCE_ROOT; }; 4B799AD607899652003F3F15 /* JackMachPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachPort.cpp; sourceTree = ""; }; 4B799AD707899652003F3F15 /* JackMachPort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JackMachPort.h; sourceTree = ""; }; + 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackMidiPort.h; path = ../common/JackMidiPort.h; sourceTree = SOURCE_ROOT; }; + 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiPort.cpp; path = ../common/JackMidiPort.cpp; sourceTree = SOURCE_ROOT; }; + 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackMidiAPI.cpp; path = ../common/JackMidiAPI.cpp; sourceTree = SOURCE_ROOT; }; 4B869B3D08C8D21C001CF041 /* driver_interface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = driver_interface.h; path = ../common/driver_interface.h; sourceTree = SOURCE_ROOT; }; 4B869B3E08C8D21C001CF041 /* driver_parse.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = driver_parse.h; path = ../common/driver_parse.h; sourceTree = SOURCE_ROOT; }; 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDriverLoader.h; path = ../common/JackDriverLoader.h; sourceTree = SOURCE_ROOT; }; @@ -543,6 +560,9 @@ 4BA692B20CBE4C2D00EAD520 /* ipload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipload.c; path = "../example-clients/ipload.c"; sourceTree = SOURCE_ROOT; }; 4BA692D40CBE4C9000EAD520 /* jack_unload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_unload; sourceTree = BUILT_PRODUCTS_DIR; }; 4BA692D60CBE4CC600EAD520 /* ipunload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipunload.c; path = "../example-clients/ipunload.c"; sourceTree = SOURCE_ROOT; }; + 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortType.cpp; path = ../common/JackPortType.cpp; sourceTree = SOURCE_ROOT; }; + 4BAB95B70B9E20B800A0C723 /* JackPortType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortType.h; path = ../common/JackPortType.h; sourceTree = SOURCE_ROOT; }; + 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioPort.cpp; path = ../common/JackAudioPort.cpp; sourceTree = SOURCE_ROOT; }; 4BB371D40C1AD85A0050C1E4 /* JackNotification.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNotification.h; path = ../common/JackNotification.h; sourceTree = SOURCE_ROOT; }; 4BBD13CC08C71EB40079F7FF /* testSynchroServerClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroServerClient.cpp; path = ../tests/testSynchroServerClient.cpp; sourceTree = SOURCE_ROOT; }; 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackServerGlobals.cpp; path = ../common/JackServerGlobals.cpp; sourceTree = SOURCE_ROOT; }; @@ -962,6 +982,7 @@ 4B6C73780CC60A6D001AFFD4 /* jack */ = { isa = PBXGroup; children = ( + 4B6B9EF50CD0958B0051EE5A /* midiport.h */, 4B6C73790CC60A6D001AFFD4 /* intclient.h */, 4B6C737A0CC60A6D001AFFD4 /* jack.h */, 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */, @@ -1083,6 +1104,11 @@ 4BA550FA05E241F200569492 /* Ports */ = { isa = PBXGroup; children = ( + 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */, + 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */, + 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */, + 4BAB95B70B9E20B800A0C723 /* JackPortType.h */, + 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */, 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */, 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */, ); @@ -1145,6 +1171,7 @@ 4B98AE010931D30C0091932A /* JackDebugClient.h */, 4B98AE000931D30C0091932A /* JackDebugClient.cpp */, 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */, + 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */, 4BE50F650B01E96200C05E63 /* JackAPIWrapper.cpp */, 4B44FAE50C7598370033A72C /* JackServerLaunch.cpp */, 4BF520580CB8D1010037470E /* timestamps.h */, @@ -1289,6 +1316,9 @@ 4B6C73840CC60A80001AFFD4 /* thread.h in Headers */, 4B6C73850CC60A81001AFFD4 /* transport.h in Headers */, 4BE3225A0CC611EF00AFA640 /* types.h in Headers */, + 4BAB95B90B9E20B800A0C723 /* JackPortType.h in Headers */, + 4B80D7E80BA0D17400F035BB /* JackMidiPort.h in Headers */, + 4B6B9EF60CD095930051EE5A /* midiport.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1351,6 +1381,9 @@ 4B6C738A0CC60A85001AFFD4 /* thread.h in Headers */, 4B6C738B0CC60A86001AFFD4 /* transport.h in Headers */, 4BE3225B0CC611F500AFA640 /* types.h in Headers */, + 4BAB95BB0B9E20B800A0C723 /* JackPortType.h in Headers */, + 4B80D7EB0BA0D17400F035BB /* JackMidiPort.h in Headers */, + 4B6B9EF70CD095970051EE5A /* midiport.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1497,7 +1530,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4BF5205B0CB8D1010037470E /* timestamps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2244,6 +2276,10 @@ 4BD4B4E409BACEF300750C0F /* JackTransportEngine.cpp in Sources */, 4B44FAE70C7598370033A72C /* JackServerLaunch.cpp in Sources */, 4BF520530CB8D0E80037470E /* timestamps.c in Sources */, + 4BAB95B80B9E20B800A0C723 /* JackPortType.cpp in Sources */, + 4BAB95ED0B9E21A500A0C723 /* JackAudioPort.cpp in Sources */, + 4B80D7E90BA0D17400F035BB /* JackMidiPort.cpp in Sources */, + 4B80D7EA0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2296,6 +2332,10 @@ 4BC216890A444BDE00BDA09F /* JackServerGlobals.cpp in Sources */, 4B44FAE80C7598370033A72C /* JackServerLaunch.cpp in Sources */, 4BF520540CB8D0E80037470E /* timestamps.c in Sources */, + 4BAB95BA0B9E20B800A0C723 /* JackPortType.cpp in Sources */, + 4BAB95EE0B9E21A500A0C723 /* JackAudioPort.cpp in Sources */, + 4B80D7EC0BA0D17400F035BB /* JackMidiPort.cpp in Sources */, + 4B80D7ED0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/macosx/RPC/JackRPCClientServer.c b/macosx/RPC/JackRPCClientServer.c index 3fcd8493..cca58046 100644 --- a/macosx/RPC/JackRPCClientServer.c +++ b/macosx/RPC/JackRPCClientServer.c @@ -1,6 +1,6 @@ /* * IDENTIFICATION: - * stub generated Thu Oct 11 16:40:18 2007 + * stub generated Thu Oct 25 10:49:38 2007 * with a MiG generated Mon Sep 11 19:11:05 PDT 2006 by root@b09.apple.com * OPTIONS: */ diff --git a/macosx/RPC/JackRPCClientUser.c b/macosx/RPC/JackRPCClientUser.c index d8c7e1c1..4329ca9b 100644 --- a/macosx/RPC/JackRPCClientUser.c +++ b/macosx/RPC/JackRPCClientUser.c @@ -1,6 +1,6 @@ /* * IDENTIFICATION: - * stub generated Thu Oct 11 16:40:18 2007 + * stub generated Thu Oct 25 10:49:38 2007 * with a MiG generated Mon Sep 11 19:11:05 PDT 2006 by root@b09.apple.com * OPTIONS: */ diff --git a/macosx/RPC/JackRPCEngine.defs b/macosx/RPC/JackRPCEngine.defs index 5d7ff7a3..10caee8e 100644 --- a/macosx/RPC/JackRPCEngine.defs +++ b/macosx/RPC/JackRPCEngine.defs @@ -27,6 +27,7 @@ ServerPrefix server_; type client_name_t = c_string[128]; type client_port_name_t = c_string[128]; +type client_port_type_t = c_string[128]; type so_name_t = c_string[1024]; type objet_data_t = c_string[1024]; @@ -67,6 +68,7 @@ routine rpc_jack_port_register( server_port : mach_port_t; refnum : int; name : client_port_name_t; + port_type : client_port_type_t; flags : unsigned; buffer_size : unsigned; out port_index : unsigned; @@ -167,4 +169,4 @@ simpleroutine rpc_jack_client_rt_notify( value : int; waittime timeout : int); - \ No newline at end of file + diff --git a/macosx/RPC/JackRPCEngine.h b/macosx/RPC/JackRPCEngine.h index 80757534..cf677678 100644 --- a/macosx/RPC/JackRPCEngine.h +++ b/macosx/RPC/JackRPCEngine.h @@ -127,6 +127,7 @@ kern_return_t rpc_jack_port_register mach_port_t server_port, int refnum, client_port_name_t name, + client_port_type_t port_type, unsigned flags, unsigned buffer_size, unsigned *port_index, @@ -428,6 +429,7 @@ __END_DECLS NDR_record_t NDR; int refnum; client_port_name_t name; + client_port_type_t port_type; unsigned flags; unsigned buffer_size; } __Request__rpc_jack_port_register_t; diff --git a/macosx/RPC/JackRPCEngineServer.c b/macosx/RPC/JackRPCEngineServer.c index 4f9f3f9e..ce9e8b63 100644 --- a/macosx/RPC/JackRPCEngineServer.c +++ b/macosx/RPC/JackRPCEngineServer.c @@ -1,6 +1,6 @@ /* * IDENTIFICATION: - * stub generated Thu Oct 11 16:40:18 2007 + * stub generated Thu Oct 25 10:49:38 2007 * with a MiG generated Mon Sep 11 19:11:05 PDT 2006 by root@b09.apple.com * OPTIONS: */ @@ -174,6 +174,7 @@ NDR_record_t NDR; int refnum; client_port_name_t name; + client_port_type_t port_type; unsigned flags; unsigned buffer_size; } __Request__rpc_jack_port_register_t; @@ -1830,6 +1831,26 @@ mig_internal novalue _Xrpc_jack_client_deactivate #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined */ +#ifndef __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined +#if defined(__NDR_convert__int_rep__JackRPCEngine__client_port_type_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__int_rep__JackRPCEngine__client_port_type_t((client_port_type_t *)(a), f) +#elif defined(__NDR_convert__int_rep__client_port_type_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__int_rep__client_port_type_t((client_port_type_t *)(a), f) +#elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) +#elif defined(__NDR_convert__int_rep__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__int_rep__string(a, f, 128) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined */ + #ifndef __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined #if defined(__NDR_convert__int_rep__JackRPCEngine__unsigned__defined) #define __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined @@ -1910,6 +1931,26 @@ mig_internal novalue _Xrpc_jack_client_deactivate #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined */ +#ifndef __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined +#if defined(__NDR_convert__char_rep__JackRPCEngine__client_port_type_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__char_rep__JackRPCEngine__client_port_type_t((client_port_type_t *)(a), f) +#elif defined(__NDR_convert__char_rep__client_port_type_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__char_rep__client_port_type_t((client_port_type_t *)(a), f) +#elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) +#elif defined(__NDR_convert__char_rep__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__char_rep__string(a, f, 128) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined */ + #ifndef __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined #if defined(__NDR_convert__char_rep__JackRPCEngine__unsigned__defined) #define __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined @@ -1990,6 +2031,26 @@ mig_internal novalue _Xrpc_jack_client_deactivate #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined */ +#ifndef __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined +#if defined(__NDR_convert__float_rep__JackRPCEngine__client_port_type_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__float_rep__JackRPCEngine__client_port_type_t((client_port_type_t *)(a), f) +#elif defined(__NDR_convert__float_rep__client_port_type_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__float_rep__client_port_type_t((client_port_type_t *)(a), f) +#elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) +#elif defined(__NDR_convert__float_rep__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined +#define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(a, f) \ + __NDR_convert__float_rep__string(a, f, 128) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined */ + #ifndef __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined #if defined(__NDR_convert__float_rep__JackRPCEngine__unsigned__defined) #define __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined @@ -2043,6 +2104,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__Requ #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined) || \ + defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__buffer_size__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -2052,6 +2114,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__Requ #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined) __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name(&In0P->name, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__name__defined */ +#if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined) + __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type(&In0P->port_type, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__port_type__defined */ #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined) __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags(&In0P->flags, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_port_register_t__flags__defined */ @@ -2063,6 +2128,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__Requ #if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__refnum__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined) || \ + defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__buffer_size__defined) if (In0P->NDR.char_rep != NDR_record.char_rep) { @@ -2072,6 +2138,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__Requ #if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined) __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name(&In0P->name, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__name__defined */ +#if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined) + __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type(&In0P->port_type, In0P->NDR.char_rep); +#endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__port_type__defined */ #if defined(__NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined) __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags(&In0P->flags, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_port_register_t__flags__defined */ @@ -2083,6 +2152,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__Requ #if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__refnum__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined) || \ + defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__buffer_size__defined) if (In0P->NDR.float_rep != NDR_record.float_rep) { @@ -2092,6 +2162,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__Requ #if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined) __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name(&In0P->name, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__name__defined */ +#if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined) + __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type(&In0P->port_type, In0P->NDR.float_rep); +#endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__port_type__defined */ #if defined(__NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined) __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags(&In0P->flags, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_port_register_t__flags__defined */ @@ -2119,6 +2192,7 @@ kern_return_t server_rpc_jack_port_register mach_port_t server_port, int refnum, client_port_name_t name, + client_port_type_t port_type, unsigned flags, unsigned buffer_size, unsigned *port_index, @@ -2138,6 +2212,7 @@ mig_internal novalue _Xrpc_jack_port_register NDR_record_t NDR; int refnum; client_port_name_t name; + client_port_type_t port_type; unsigned flags; unsigned buffer_size; mach_msg_trailer_t trailer; @@ -2171,7 +2246,7 @@ mig_internal novalue _Xrpc_jack_port_register { MIG_RETURN_ERROR(OutP, check_result); } #endif /* defined(__MIG_check__Request__rpc_jack_port_register_t__defined) */ - OutP->RetCode = server_rpc_jack_port_register(In0P->Head.msgh_request_port, In0P->refnum, In0P->name, In0P->flags, In0P->buffer_size, &OutP->port_index, &OutP->result); + OutP->RetCode = server_rpc_jack_port_register(In0P->Head.msgh_request_port, In0P->refnum, In0P->name, In0P->port_type, In0P->flags, In0P->buffer_size, &OutP->port_index, &OutP->result); if (OutP->RetCode != KERN_SUCCESS) { MIG_RETURN_ERROR(OutP, OutP->RetCode); } @@ -6058,7 +6133,7 @@ const struct server_JackRPCEngine_subsystem { { (mig_impl_routine_t) 0, (mig_stub_routine_t) _Xrpc_jack_client_deactivate, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_deactivate_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_register, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_register_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_register, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_register_t)}, { (mig_impl_routine_t) 0, (mig_stub_routine_t) _Xrpc_jack_port_unregister, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_unregister_t)}, { (mig_impl_routine_t) 0, diff --git a/macosx/RPC/JackRPCEngineUser.c b/macosx/RPC/JackRPCEngineUser.c index 882ce287..85ba3c5b 100644 --- a/macosx/RPC/JackRPCEngineUser.c +++ b/macosx/RPC/JackRPCEngineUser.c @@ -1,6 +1,6 @@ /* * IDENTIFICATION: - * stub generated Thu Oct 11 16:40:18 2007 + * stub generated Thu Oct 25 10:49:38 2007 * with a MiG generated Mon Sep 11 19:11:05 PDT 2006 by root@b09.apple.com * OPTIONS: */ @@ -2017,6 +2017,7 @@ mig_external kern_return_t rpc_jack_port_register mach_port_t server_port, int refnum, client_port_name_t name, + client_port_type_t port_type, unsigned flags, unsigned buffer_size, unsigned *port_index, @@ -2033,6 +2034,7 @@ mig_external kern_return_t rpc_jack_port_register NDR_record_t NDR; int refnum; client_port_name_t name; + client_port_type_t port_type; unsigned flags; unsigned buffer_size; } Request; @@ -2098,6 +2100,8 @@ mig_external kern_return_t rpc_jack_port_register (void) mig_strncpy(InP->name, name, 128); + (void) mig_strncpy(InP->port_type, port_type, 128); + InP->flags = flags; InP->buffer_size = buffer_size; diff --git a/macosx/RPC/Jackdefs.h b/macosx/RPC/Jackdefs.h index ef8ff68c..5636c37e 100644 --- a/macosx/RPC/Jackdefs.h +++ b/macosx/RPC/Jackdefs.h @@ -1,6 +1,24 @@ +/* +Copyright (C) 2004-2006 Grame +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. + +*/ typedef char client_name_t[64]; typedef char client_port_name_t[256]; +typedef char client_port_type_t[128]; typedef char so_name_t[256]; -typedef char objet_data_t[256]; \ No newline at end of file +typedef char objet_data_t[256]; diff --git a/windows/JackPortAudioDriver.cpp b/windows/JackPortAudioDriver.cpp index d12e9706..0162318e 100644 --- a/windows/JackPortAudioDriver.cpp +++ b/windows/JackPortAudioDriver.cpp @@ -436,12 +436,14 @@ int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size) paNoFlag, // Clipping is on... Render, this); + if (err != paNoError) { jack_error("Pa_OpenStream error = %s\n", Pa_GetErrorText(err)); return -1; } else { - return JackAudioDriver::SetBufferSize(buffer_size); // never fails; - } + // Only done when success + return JackAudioDriver::SetBufferSize(buffer_size); // never fails + } } } // end of namespace diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index 6e9d435b..0192f214 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -182,9 +182,9 @@ void JackWinNamedPipeClientChannel::ClientDeactivate(int refnum, int* result) ServerSyncCall(&req, &res, result); } -void JackWinNamedPipeClientChannel::PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) +void JackWinNamedPipeClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) { - JackPortRegisterRequest req(refnum, name, "audio", flags, buffer_size); + JackPortRegisterRequest req(refnum, name, type, flags, buffer_size); JackPortRegisterResult res; ServerSyncCall(&req, &res, result); *port_index = res.fPortIndex; diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h index de006161..7a7654e3 100644 --- a/windows/JackWinNamedPipeClientChannel.h +++ b/windows/JackWinNamedPipeClientChannel.h @@ -65,7 +65,7 @@ class JackWinNamedPipeClientChannel : public JackClientChannelInterface, public void ClientActivate(int refnum, int* result); void ClientDeactivate(int refnum, int* result); - void PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); + void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result); void PortUnRegister(int refnum, jack_port_id_t port_index, int* result); void PortConnect(int refnum, const char* src, const char* dst, int* result); diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index d297189c..50d27644 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -164,7 +164,7 @@ int JackClientPipeThread::HandleRequest() JackPortRegisterRequest req; JackPortRegisterResult res; if (req.Read(fPipe) == 0) - res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fFlags, req.fBufferSize, &res.fPortIndex); + res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex); res.Write(fPipe); break; } diff --git a/windows/libjackdmp.dsp b/windows/libjackdmp.dsp index ba3222d8..59b1159d 100644 --- a/windows/libjackdmp.dsp +++ b/windows/libjackdmp.dsp @@ -111,6 +111,10 @@ SOURCE=..\common\JackAudioDriver.cpp # End Source File # Begin Source File +SOURCE=..\common\JackAudioPort.cpp +# End Source File +# Begin Source File + SOURCE=..\common\JackClient.cpp # End Source File # Begin Source File @@ -171,10 +175,22 @@ SOURCE=..\common\JackLoopbackDriver.cpp # End Source File # Begin Source File +SOURCE=..\common\JackMidiAPI.cpp +# End Source File +# Begin Source File + +SOURCE=..\common\JackMidiPort.cpp +# End Source File +# Begin Source File + SOURCE=..\common\JackPort.cpp # End Source File # Begin Source File +SOURCE=..\common\JackPortType.cpp +# End Source File +# Begin Source File + SOURCE=..\common\JackServer.cpp # End Source File # Begin Source File @@ -245,6 +261,10 @@ SOURCE=..\common\shm.c # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\common\JackMidiPort.h +# End Source File # End Group # Begin Group "Resource Files" diff --git a/windows/libjackmp.dsp b/windows/libjackmp.dsp index f8209a6d..7acd457a 100644 --- a/windows/libjackmp.dsp +++ b/windows/libjackmp.dsp @@ -99,6 +99,10 @@ SOURCE=..\common\JackAPI.cpp # End Source File # Begin Source File +SOURCE=..\common\JackAudioPort.cpp +# End Source File +# Begin Source File + SOURCE=..\common\JackClient.cpp # End Source File # Begin Source File @@ -135,10 +139,22 @@ SOURCE=..\common\JackLibClient.cpp # End Source File # Begin Source File +SOURCE=..\common\JackMidiAPI.cpp +# End Source File +# Begin Source File + +SOURCE=..\common\JackMidiPort.cpp +# End Source File +# Begin Source File + SOURCE=..\common\JackPort.cpp # End Source File # Begin Source File +SOURCE=..\common\JackPortType.cpp +# End Source File +# Begin Source File + SOURCE=..\common\JackShmMem.cpp # End Source File # Begin Source File