diff --git a/ChangeLog b/ChangeLog index 77cb2eb4..8dfeca7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,17 +25,155 @@ Paul Davis Jackdmp changes log --------------------------- -2009-07-22 Stephane Letz +2009-11-18 Stephane Letz + + * Sync JackCoreAudioAdapter code with JackCoreAudioDriver. + +2009-11-17 Stephane Letz + + * In JackCoreAudio driver, clock drift compensation in aggregated devices working. + * In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). + +2009-11-16 Stephane Letz + + * In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. + +2009-11-14 Stephane Letz + + * Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. + +2009-11-13 Stephane Letz + + * Better memory allocation error checking in ringbuffer.c, weak import improvements. + * Memory allocation error checking for jack_client_new and jack_client_open (server and client side). + * Memory allocation error checking in server for RPC. + * Simplify server temporary mode : now use a JackTemporaryException. + * Lock/Unlock shared memory segments (to test...). + +2009-11-12 Stephane Letz + + * Better memory allocation error checking on client (library) side. + +2009-11-11 Stephane Letz + + * Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. + +2009-11-10 Stephane Letz - * Version 1.9.4 started. - * Solaris boomer backend now working in capture or playback only mode. - * Fix control.h for proper compilation on Solaris. + * Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. +2009-11-09 Stephane Letz + + * Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. + +2009-11-07 Stephane Letz + + * Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). + * Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. + +2009-11-06 Stephane Letz + + * Correctly save and restore RT mode state in freewheel mode. + * Correct freewheel code on client side. + +2009-11-05 Stephane Letz + + * No reason to make jack_on_shutdown deprecated, so revert the incorrect change. + * Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. + +2009-10-30 Stephane Letz + + * In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. + * In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. + * Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fix...) + * Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. + * JACK_SCHED_POLICY switched to SCHED_FIFO. + * Now can aggregate device that are themselves AD. + +2009-10-29 Stephane Letz + + * In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). + +2009-10-28 Stephane Letz + + * In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). + * In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. + +2009-10-27 Stephane Letz + + * Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. + +2009-10-26 Stephane Letz + + * Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. + * Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. + +2009-10-25 Stephane Letz + + * Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. + * Aggregate device code added to JackCoreAudioAdapter. + +2009-10-23 Stephane Letz + + * Correct JackProcessSync::LockedTimedWait. + * Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. + * Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. + * jack_verbose moved to JackGlobals class. + +2009-10-22 Stephane Letz + + * Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. + +2009-10-20 Stephane Letz + + * Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. + * CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ) + +2009-10-17 Stephane Letz + + * Correct server temporary mode : now set a global and quit after server/client message handling is finished. + +2009-10-15 Stephane Letz + + * Change CoreAudio notification thread setup for OSX Snow Leopard. + +2009-09-18 Stephane Letz + + * Simplify transport in NetJack2: master only can control transport. + +2009-09-15 Stephane Letz + + * Correct CPU timing in JackNetDriver, now take cycle begin time after Read. + * Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. + +2009-08-28 Stephane Letz + + * Correct monitor port naming in JackAudioDriver and JackCoreAudioDriver. + * Big endian bug fix in memops.c (http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=11_be24bit.patch;att=1;bug=486308) + +2009-07-31 Stephane Letz + + * Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. + +2009-07-29 Stephane Letz + + * Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). + +2009-07-28 Stephane Letz + + * Fix CopyAndConvertIn for Solaris backends. + +2009-07-22 Stephane Letz + + * Version 1.9.4 started. + * Solaris boomer backend now working in capture or playback only mode. + * Fix control.h for proper compilation on Solaris. + 2009-07-17 Stephane Letz - * Loopback backend reborn as a dynamically loadable separated backend. + * Loopback backend reborn as a dynamically loadable separated backend. * -L parameter for loopback backend activated again in jackd. - + 2009-07-17 Stephane Letz * Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. @@ -312,12 +450,12 @@ Paul Davis 2009-01-05 Stephane Letz - * Synchronize jack2 public headers with jack1 ones. + * Synchronize jack2 public headers with JACK1 ones. * Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. 2008-12-18 Stephane Letz - * For ALSA driver, synchronize with latest jack1 memops functions. + * For ALSA driver, synchronize with latest JACK1 memops functions. * Use memops functions in JackOSSDriver. * Use memops functions in JackOSSAdapter. @@ -351,13 +489,13 @@ Paul Davis 2008-11-27 Stephane Letz * Add timing profiling code in JackOSSDriver. - * Report ringbuffer.c fixes from jack1. + * Report ringbuffer.c fixes from JACK1. 2008-11-21 Stephane Letz - * Report ringbuffer.c fixes from jack1. - * Better isolation of server and clients system resources to allow starting the server in several user account at the same time. - * Correct ressource cleanup in case of driver open failure. + * Report ringbuffer.c fixes from JACK1. + * Better isolation of server and clients system resources to allow starting the server in several user account at the same time. + * Correct ressource cleanup in case of driver open failure. 2008-11-19 Stephane Letz diff --git a/README b/README index 88278c31..d9f58484 100644 --- a/README +++ b/README @@ -213,6 +213,7 @@ Note : To experiment with the -S option, jackdmp must be launched in a console. 1.9.1 : Fix jackctl_server_unload_internal. Filter SIGPIPE to avoid having client get a SIGPIPE when trying to access a died server. Libjack shutdown handler does not "deactivate" (fActive = false) the client anymore, so that jack_deactivate correctly does the job later on. Better isolation of server and clients system resources to allow starting the server in several user account at the same time. Report ringbuffer.c fixes from jack1. Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown). Use JACK_DRIVER_DIR variable in internal clients loader. For ALSA driver, synchronize with latest jack1 memops functions. Synchronize jack2 public headers with jack1 ones. Implement jack_client_real_time_priority and jack_client_max_real_time_priority API. Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117. Cleanup server starting code for clients directly linked with libjackserver.so. JackMessageBuffer was using thread "Stop" scheme in destructor, now use the safer thread "Kill" way. Synchronize ALSA backend code with JACK1 one. Set default mode to 'slow' in JackNetDriver and JackNetAdapter. Simplify audio packet order verification. Fix JackNetInterface::SetNetBufferSize for socket buffer size computation and JackNetMasterInterface::DataRecv if synch packet is received, various cleanup. Better recovery of network overload situations, now "resynchronize" by skipping cycles.". Support for BIG_ENDIAN machines in NetJack2. Support for BIG_ENDIAN machines in NetJack2 for MIDI ports. Support for "-h" option in internal clients to print the parameters. In NetJack2, fix a bug when capture or playback only channels are used. Add a JACK_INTERNAL_DIR environment variable to be used for internal clients. Add a resample quality parameter in audioadapter. Now correctly return an error if JackServer::SetBufferSize could not change the buffer size (and was just restoring the current one). Use PRIu32 kind of macro in JackAlsaDriver again. Add a resample quality parameter in netadapter. 1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). 1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend. +1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver. This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer... diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index d609a915..97e58833 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -72,6 +72,8 @@ extern "C" EXPORT int jack_is_realtime (jack_client_t *client); EXPORT void jack_on_shutdown (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg); + EXPORT void jack_on_info_shutdown (jack_client_t *client, + JackInfoShutdownCallback shutdown_callback, void *arg); EXPORT int jack_set_process_callback (jack_client_t *client, JackProcessCallback process_callback, void *arg); @@ -288,15 +290,23 @@ EXPORT void jack_set_info_function (print_function func) EXPORT jack_client_t* jack_client_new(const char* client_name) { - assert(JackGlobals::fOpenMutex); - JackGlobals::fOpenMutex->Lock(); - jack_error("jack_client_new: deprecated"); - int options = JackUseExactName; - if (getenv("JACK_START_SERVER") == NULL) - options |= JackNoStartServer; - jack_client_t* res = jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL); - JackGlobals::fOpenMutex->Unlock(); - return res; + try { + assert(JackGlobals::fOpenMutex); + JackGlobals::fOpenMutex->Lock(); + jack_error("jack_client_new: deprecated"); + int options = JackUseExactName; + if (getenv("JACK_START_SERVER") == NULL) + options |= JackNoStartServer; + jack_client_t* res = jack_client_open_aux(client_name, (jack_options_t)options, NULL, NULL); + JackGlobals::fOpenMutex->Unlock(); + return res; + } catch (std::bad_alloc& e) { + jack_error("Memory allocation error..."); + return NULL; + } catch (...) { + jack_error("Unknown error..."); + return NULL; + } } EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) @@ -819,6 +829,19 @@ EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback cal } } +EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg) +{ +#ifdef __CLIENTDEBUG__ + JackLibGlobals::CheckContext(); +#endif + JackClient* client = (JackClient*)ext_client; + if (client == NULL) { + jack_error("jack_on_info_shutdown called with a NULL client"); + } else { + client->OnInfoShutdown(callback, arg); + } +} + EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg) { #ifdef __CLIENTDEBUG__ @@ -1928,5 +1951,7 @@ jack_get_version_string() EXPORT void jack_free(void* ptr) { - free(ptr); + if (ptr) { + free(ptr); + } } diff --git a/common/JackArgParser.cpp b/common/JackArgParser.cpp index fcccaa23..e9b8f6f9 100644 --- a/common/JackArgParser.cpp +++ b/common/JackArgParser.cpp @@ -128,6 +128,10 @@ namespace Jack { return -1; //else allocate and fill it argv = (char**)calloc (fArgv.size(), sizeof(char*)); + if (argv == NULL) + { + return -1; + } for ( unsigned int i = 0; i < fArgv.size(); i++ ) { argv[i] = (char*)calloc(fArgv[i].length(), sizeof(char)); diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index 3dbc2b67..dff17818 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -230,10 +230,18 @@ namespace Jack // Finer estimation of the position in the ringbuffer int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0; - double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); + + double ratio = 1; + + // TODO : done like this just to avoid crash when input only or output only... + if (fCaptureChannels > 0) + ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); + else if (fPlaybackChannels > 0) + ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames); #ifdef JACK_MONITOR - fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); + if (fCaptureRingBuffer[0] != NULL) + fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); #endif // Push/pull from ringbuffer diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 505db38e..3bcae9e9 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -139,12 +139,13 @@ int JackAudioDriver::Attach() // Monitor ports if (fWithMonitorPorts) { jack_log("Create monitor port "); - snprintf(name, sizeof(name) - 1, "%s:%s:monitor_%u", fAliasName, fPlaybackDriverName, i + 1); + snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register monitor port for %s", name); return -1; } else { port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); port->SetLatency(fEngineControl->fBufferSize); fMonitorPortList[i] = port_index; } diff --git a/common/JackChannel.h b/common/JackChannel.h index 654887ed..655e2bcf 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -82,7 +82,7 @@ class JackClientChannelInterface virtual void ClientClose(int refnum, int* result) {} - virtual void ClientActivate(int refnum, int state, int* result) + virtual void ClientActivate(int refnum, int is_real_time, int* result) {} virtual void ClientDeactivate(int refnum, int* result) {} diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 75beefbc..e6469267 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -49,6 +49,7 @@ JackClient::JackClient(JackSynchro* table):fThread(this) fGraphOrder = NULL; fXrun = NULL; fShutdown = NULL; + fInfoShutdown = NULL; fInit = NULL; fBufferSize = NULL; fClientRegistration = NULL; @@ -63,6 +64,7 @@ JackClient::JackClient(JackSynchro* table):fThread(this) fGraphOrderArg = NULL; fXrunArg = NULL; fShutdownArg = NULL; + fInfoShutdownArg = NULL; fInitArg = NULL; fBufferSizeArg = NULL; fFreewheelArg = NULL; @@ -132,12 +134,12 @@ void JackClient::SetupDriverSync(bool freewheel) \brief Notification received from the server. */ -int JackClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { return 0; } -int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int res = 0; @@ -145,11 +147,11 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, switch (notify) { case kAddClient: - res = ClientNotifyImp(refnum, name, notify, sync, value1, value2); + res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2); break; case kRemoveClient: - res = ClientNotifyImp(refnum, name, notify, sync, value1, value2); + res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2); break; case kActivateClient: @@ -168,84 +170,107 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, case kAddClient: jack_log("JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name); - if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) // Don't call the callback for the registering client itself + if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself fClientRegistration(name, 1, fClientRegistrationArg); + } break; case kRemoveClient: jack_log("JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName, name); - if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) // Don't call the callback for the registering client itself + if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself fClientRegistration(name, 0, fClientRegistrationArg); + } break; case kBufferSizeCallback: jack_log("JackClient::kBufferSizeCallback buffer_size = %ld", value1); - if (fBufferSize) + if (fBufferSize) { res = fBufferSize(value1, fBufferSizeArg); + } break; case kSampleRateCallback: jack_log("JackClient::kSampleRateCallback sample_rate = %ld", value1); - if (fSampleRate) + if (fSampleRate) { res = fSampleRate(value1, fSampleRateArg); + } break; case kGraphOrderCallback: jack_log("JackClient::kGraphOrderCallback"); - if (fGraphOrder) + if (fGraphOrder) { res = fGraphOrder(fGraphOrderArg); + } break; case kStartFreewheelCallback: jack_log("JackClient::kStartFreewheel"); SetupDriverSync(true); - fThread.DropRealTime(); - if (fFreewheel) + fThread.DropRealTime(); // Always done (JACK server in RT mode or not...) + if (fFreewheel) { fFreewheel(1, fFreewheelArg); + } break; case kStopFreewheelCallback: jack_log("JackClient::kStopFreewheel"); SetupDriverSync(false); - if (fFreewheel) + if (fFreewheel) { fFreewheel(0, fFreewheelArg); - fThread.AcquireRealTime(); + } + if (GetEngineControl()->fRealTime) { + fThread.AcquireRealTime(); + } break; case kPortRegistrationOnCallback: jack_log("JackClient::kPortRegistrationOn port_index = %ld", value1); - if (fPortRegistration) + if (fPortRegistration) { fPortRegistration(value1, 1, fPortRegistrationArg); + } break; case kPortRegistrationOffCallback: jack_log("JackClient::kPortRegistrationOff port_index = %ld ", value1); - if (fPortRegistration) + if (fPortRegistration) { fPortRegistration(value1, 0, fPortRegistrationArg); + } break; case kPortConnectCallback: jack_log("JackClient::kPortConnectCallback src = %ld dst = %ld", value1, value2); - if (fPortConnect) + if (fPortConnect) { fPortConnect(value1, value2, 1, fPortConnectArg); + } break; case kPortDisconnectCallback: jack_log("JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1, value2); - if (fPortConnect) + if (fPortConnect) { fPortConnect(value1, value2, 0, fPortConnectArg); + } break; case kPortRenameCallback: jack_log("JackClient::kPortRenameCallback port = %ld"); - if (fPortRename) + if (fPortRename) { fPortRename(value1, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg); + } break; case kXRunCallback: jack_log("JackClient::kXRunCallback"); - if (fXrun) + if (fXrun) { res = fXrun(fXrunArg); + } + break; + + case kShutDownCallback: + jack_log("JackClient::kShutDownCallback"); + if (fInfoShutdown) { + fInfoShutdown((jack_status_t)value1, message, fInfoShutdownArg); + fInfoShutdown = NULL; + } break; } } @@ -444,7 +469,7 @@ inline void JackClient::End() jack_log("JackClient::Execute end name = %s", GetClientControl()->fName); // Hum... not sure about this, the following "close" code is called in the RT thread... int result; - fThread.DropRealTime(); + fThread.DropSelfRealTime(); GetClientControl()->fActive = false; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); fThread.Terminate(); @@ -455,7 +480,7 @@ inline void JackClient::Error() jack_error("JackClient::Execute error name = %s", GetClientControl()->fName); // Hum... not sure about this, the following "close" code is called in the RT thread... int result; - fThread.DropRealTime(); + fThread.DropSelfRealTime(); GetClientControl()->fActive = false; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); ShutDown(); @@ -582,7 +607,10 @@ void JackClient::ShutDown() jack_log("ShutDown"); JackGlobals::fServerRunning = false; - if (fShutdown) { + if (fInfoShutdown) { + fInfoShutdown(JackFailure, "JACK server has been closed", fInfoShutdownArg); + fInfoShutdown = NULL; + } else if (fShutdown) { fShutdown(fShutdownArg); fShutdown = NULL; } @@ -772,6 +800,17 @@ void JackClient::OnShutdown(JackShutdownCallback callback, void *arg) fShutdown = callback; } } + +void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) +{ + if (IsActive()) { + jack_error("You cannot set callbacks on an active client"); + } else { + GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL); + fInfoShutdownArg = arg; + fInfoShutdown = callback; + } +} int JackClient::SetProcessCallback(JackProcessCallback callback, void *arg) { @@ -850,6 +889,9 @@ int JackClient::SetSampleRateCallback(JackSampleRateCallback callback, void *arg GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL); fSampleRateArg = arg; fSampleRate = callback; + // Now invoke it + if (callback) + callback(GetEngineControl()->fSampleRate, arg); return 0; } } @@ -946,14 +988,7 @@ char* JackClient::GetInternalClientName(int ref) char name_res[JACK_CLIENT_NAME_SIZE + 1]; int result = -1; fChannel->GetInternalClientName(GetClientControl()->fRefNum, ref, name_res, &result); - - if (result < 0) { - return NULL; - } else { - char* name = (char*)malloc(strlen(name_res)); - strcpy(name, name_res); - return name; - } + return (result < 0) ? NULL : strdup(name_res); } int JackClient::InternalClientHandle(const char* client_name, jack_status_t* status) diff --git a/common/JackClient.h b/common/JackClient.h index 73ee17fc..215098a0 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -54,6 +54,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface JackGraphOrderCallback fGraphOrder; JackXRunCallback fXrun; JackShutdownCallback fShutdown; + JackInfoShutdownCallback fInfoShutdown; JackThreadInitCallback fInit; JackBufferSizeCallback fBufferSize; JackSampleRateCallback fSampleRate; @@ -70,6 +71,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface void* fGraphOrderArg; void* fXrunArg; void* fShutdownArg; + void* fInfoShutdownArg; void* fInitArg; void* fBufferSizeArg; void* fSampleRateArg; @@ -95,7 +97,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface void CallSyncCallback(); void CallTimebaseCallback(); - virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value); + virtual int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value); inline void DummyCycle(); inline void ExecuteThread(); @@ -123,7 +125,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface virtual JackEngineControl* GetEngineControl() const = 0; // Notifications - virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual int Activate(); virtual int Deactivate(); @@ -159,6 +161,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface // Callbacks virtual void OnShutdown(JackShutdownCallback callback, void *arg); + virtual void OnInfoShutdown(JackInfoShutdownCallback callback, void *arg); virtual int SetProcessCallback(JackProcessCallback callback, void* arg); virtual int SetXRunCallback(JackXRunCallback callback, void* arg); virtual int SetInitCallback(JackThreadInitCallback callback, void* arg); diff --git a/common/JackClientInterface.h b/common/JackClientInterface.h index 1794328c..bd94ed38 100644 --- a/common/JackClientInterface.h +++ b/common/JackClientInterface.h @@ -44,7 +44,7 @@ class SERVER_EXPORT JackClientInterface virtual int Close() = 0; - virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) = 0; + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) = 0; virtual JackClientControl* GetClientControl() const = 0; }; diff --git a/common/JackConstants.h b/common/JackConstants.h index dd792e4d..c7227139 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -32,15 +32,16 @@ #define JACK_PORT_TYPE_SIZE 32 #define JACK_CLIENT_NAME_SIZE 64 +#define JACK_MESSAGE_SIZE 256 #ifndef PORT_NUM -#define PORT_NUM 1024 +#define PORT_NUM 2048 #endif #define DRIVER_PORT_NUM 256 #ifndef PORT_NUM_FOR_CLIENT -#define PORT_NUM_FOR_CLIENT 512 +#define PORT_NUM_FOR_CLIENT 768 #endif #define FIRST_AVAILABLE_PORT 1 diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index fd69b1fc..165f2a51 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -624,6 +624,11 @@ get_realtime_priority_constraint() //jack_info("realtime priority range is (%d,%d)", min, max); constraint_ptr = (jack_driver_param_constraint_desc_t *)calloc(1, sizeof(jack_driver_param_value_enum_t)); + if (constraint_ptr == NULL) + { + jack_error("Cannot allocate memory for jack_driver_param_constraint_desc_t structure."); + return NULL; + } constraint_ptr->flags = JACK_CONSTRAINT_FLAG_RANGE; constraint_ptr->constraint.range.min.i = min; diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index 74566c5e..a2a61d8d 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -139,10 +139,10 @@ JackEngineControl* JackDebugClient::GetEngineControl() const \brief Notification received from the server. */ -int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { CheckClient(); - return fClient->ClientNotify( refnum, name, notify, sync, value1, value2); + return fClient->ClientNotify( refnum, name, notify, sync, message, value1, value2); } int JackDebugClient::Activate() @@ -416,6 +416,12 @@ void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg) fClient->OnShutdown(callback, arg); } +void JackDebugClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) +{ + CheckClient(); + fClient->OnInfoShutdown(callback, arg); +} + int JackDebugClient::TimeCallback(jack_nframes_t nframes, void *arg) { JackDebugClient* client = (JackDebugClient*)arg; diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h index 430c9610..0bb21b20 100644 --- a/common/JackDebugClient.h +++ b/common/JackDebugClient.h @@ -75,7 +75,7 @@ class JackDebugClient : public JackClient virtual JackEngineControl* GetEngineControl() const; // Notifications - int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); int Activate(); int Deactivate(); @@ -110,6 +110,7 @@ class JackDebugClient : public JackClient // Callbacks void OnShutdown(JackShutdownCallback callback, void *arg); + void OnInfoShutdown(JackInfoShutdownCallback callback, void *arg); int SetProcessCallback(JackProcessCallback callback, void* arg); int SetXRunCallback(JackXRunCallback callback, void* arg); int SetInitCallback(JackThreadInitCallback callback, void* arg); diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 9fde4917..bab5db0f 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -167,11 +167,15 @@ int JackDriver::Open(jack_nframes_t buffer_size, int JackDriver::Close() { - jack_log("JackDriver::Close"); - fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync - fClientControl.fActive = false; - fEngineControl->fDriverNum--; - return fEngine->ClientInternalClose(fClientControl.fRefNum, false); + if (fClientControl.fRefNum > 0) { + jack_log("JackDriver::Close"); + fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync + fClientControl.fActive = false; + fEngineControl->fDriverNum--; + return fEngine->ClientInternalClose(fClientControl.fRefNum, false); + } else { + return -1; + } } /*! @@ -190,7 +194,7 @@ void JackDriver::SetupDriverSync(int ref, bool freewheel) } } -int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { switch (notify) { @@ -250,6 +254,11 @@ void JackDriver::NotifySampleRate(jack_nframes_t sample_rate) fEngine->NotifySampleRate(sample_rate); fEngineControl->InitFrameTime(); } + +void JackDriver::NotifyFailure(int code, const char* reason) +{ + fEngine->NotifyFailure(code, reason); +} void JackDriver::SetMaster(bool onoff) { diff --git a/common/JackDriver.h b/common/JackDriver.h index 6b80dc33..83f7e250 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -140,6 +140,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); // XRun notification sent by the driver void NotifyBufferSize(jack_nframes_t buffer_size); // BufferSize notification sent by the driver void NotifySampleRate(jack_nframes_t sample_rate); // SampleRate notification sent by the driver + void NotifyFailure(int code, const char* reason); // Failure notification sent by the driver public: @@ -199,7 +200,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetSampleRate(jack_nframes_t sample_rate); - virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 52c4aeed..428d3ab0 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -62,7 +62,7 @@ SERVER_EXPORT void jack_print_driver_options (jack_driver_desc_t* desc, FILE* fi fprintf (file, "\t-%c, --%s \t%s (default: %s)\n", desc->params[i].character, desc->params[i].name, - desc->params[i].short_desc, + desc->params[i].long_desc, arg_default); } } diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index f4a4913d..049543f0 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -121,9 +121,7 @@ void JackEngine::ReleaseRefnum(int ref) // last client and temporay case: quit the server jack_log("JackEngine::ReleaseRefnum server quit"); fEngineControl->fTemporary = false; -#ifndef WIN32 - exit(0); -#endif + throw JackTemporaryException(); } } } @@ -207,7 +205,7 @@ void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions // Notifications //--------------- -void JackEngine::NotifyClient(int refnum, int event, int sync, int value1, int value2) +void JackEngine::NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2) { JackClientInterface* client = fClientTable[refnum]; @@ -215,20 +213,20 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, int value1, int v if (!client) { jack_log("JackEngine::NotifyClient: client not available anymore"); } else if (client->GetClientControl()->fCallback[event]) { - if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value1, value2) < 0) + if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); } else { jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); } } -void JackEngine::NotifyClients(int event, int sync, int value1, int value2) +void JackEngine::NotifyClients(int event, int sync, const char* message, int value1, int value2) { for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client) { if (client->GetClientControl()->fCallback[event]) { - if (client->ClientNotify(i, client->GetClientControl()->fName, event, sync, value1, value2) < 0) + if (client->ClientNotify(i, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); } else { jack_log("JackEngine::NotifyClients: no callback for event = %ld", event); @@ -244,11 +242,11 @@ int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* nam for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* old_client = fClientTable[i]; if (old_client) { - if (old_client->ClientNotify(refnum, name, kAddClient, true, 0, 0) < 0) { + if (old_client->ClientNotify(refnum, name, kAddClient, true, "", 0, 0) < 0) { jack_error("NotifyAddClient old_client fails name = %s", old_client->GetClientControl()->fName); return -1; } - if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, kAddClient, true, 0, 0) < 0) { + if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, kAddClient, true, "", 0, 0) < 0) { jack_error("NotifyAddClient new_client fails name = %s", name); return -1; } @@ -264,7 +262,7 @@ void JackEngine::NotifyRemoveClient(const char* name, int refnum) for (int i = 0; i < CLIENT_NUM; i++) { JackClientInterface* client = fClientTable[i]; if (client) { - client->ClientNotify(refnum, name, kRemoveClient, true, 0, 0); + client->ClientNotify(refnum, name, kRemoveClient, true, "",0, 0); } } } @@ -281,51 +279,64 @@ void JackEngine::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) void JackEngine::NotifyXRun(int refnum) { if (refnum == ALL_CLIENTS) { - NotifyClients(kXRunCallback, false, 0, 0); + NotifyClients(kXRunCallback, false, "", 0, 0); } else { - NotifyClient(refnum, kXRunCallback, false, 0, 0); + NotifyClient(refnum, kXRunCallback, false, "", 0, 0); } } void JackEngine::NotifyGraphReorder() { - NotifyClients(kGraphOrderCallback, false, 0, 0); + NotifyClients(kGraphOrderCallback, false, "", 0, 0); } void JackEngine::NotifyBufferSize(jack_nframes_t buffer_size) { - NotifyClients(kBufferSizeCallback, true, buffer_size, 0); + NotifyClients(kBufferSizeCallback, true, "", buffer_size, 0); } void JackEngine::NotifySampleRate(jack_nframes_t sample_rate) { - NotifyClients(kSampleRateCallback, true, sample_rate, 0); + NotifyClients(kSampleRateCallback, true, "", sample_rate, 0); } +void JackEngine::NotifyFailure(int code, const char* reason) +{ + NotifyClients(kShutDownCallback, false, reason, code, 0); +} + void JackEngine::NotifyFreewheel(bool onoff) { - fEngineControl->fRealTime = !onoff; - NotifyClients((onoff ? kStartFreewheelCallback : kStopFreewheelCallback), true, 0, 0); + if (onoff) { + // Save RT state + fEngineControl->fSavedRealTime = fEngineControl->fRealTime; + fEngineControl->fRealTime = false; + } else { + // Restore RT state + fEngineControl->fRealTime = fEngineControl->fSavedRealTime; + fEngineControl->fSavedRealTime = false; + } + NotifyClients((onoff ? kStartFreewheelCallback : kStopFreewheelCallback), true, "", 0, 0); } void JackEngine::NotifyPortRegistation(jack_port_id_t port_index, bool onoff) { - NotifyClients((onoff ? kPortRegistrationOnCallback : kPortRegistrationOffCallback), false, port_index, 0); + NotifyClients((onoff ? kPortRegistrationOnCallback : kPortRegistrationOffCallback), false, "", port_index, 0); } void JackEngine::NotifyPortRename(jack_port_id_t port) { - NotifyClients(kPortRenameCallback, false, port, 0); + NotifyClients(kPortRenameCallback, false, "", port, 0); } void JackEngine::NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff) { - NotifyClients((onoff ? kPortConnectCallback : kPortDisconnectCallback), false, src, dst); + NotifyClients((onoff ? kPortConnectCallback : kPortDisconnectCallback), false, "", src, dst); } void JackEngine::NotifyActivate(int refnum) { - NotifyClient(refnum, kActivateClient, true, 0, 0); + NotifyClient(refnum, kActivateClient, true, "", 0, 0); } //---------------------------- @@ -483,7 +494,7 @@ int JackEngine::GetClientRefNum(const char* name) // Used for external clients int JackEngine::ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { - jack_log("JackEngine::ClientOpen: name = %s ", name); + jack_log("JackEngine::ClientExternalOpen: name = %s ", name); int refnum = AllocateRefnum(); if (refnum < 0) { @@ -535,7 +546,7 @@ error: // Used for server driver clients int JackEngine::ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) { - jack_log("JackEngine::ClientInternalNew: name = %s", name); + jack_log("JackEngine::ClientInternalOpen: name = %s", name); int refnum = AllocateRefnum(); if (refnum < 0) { @@ -640,14 +651,14 @@ int JackEngine::ClientCloseAux(int refnum, JackClientInterface* client, bool wai return 0; } -int JackEngine::ClientActivate(int refnum, bool state) +int JackEngine::ClientActivate(int refnum, bool is_real_time) { AssertRefnum(refnum); JackClientInterface* client = fClientTable[refnum]; assert(fClientTable[refnum]); jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); - if (state) + if (is_real_time) fGraphManager->Activate(refnum); // Wait for graph state change to be effective diff --git a/common/JackEngine.h b/common/JackEngine.h index c425f143..b4292e10 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -65,8 +65,9 @@ class SERVER_EXPORT JackEngine int AllocateRefnum(); void ReleaseRefnum(int ref); - void NotifyClient(int refnum, int event, int sync, int value1, int value2); - void NotifyClients(int event, int sync, int value1, int value2); + void NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2); + void NotifyClients(int event, int sync, const char* message, int value1, int value2); + void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); void NotifyPortRename(jack_port_id_t src); @@ -90,7 +91,7 @@ class SERVER_EXPORT JackEngine int ClientExternalClose(int refnum); int ClientInternalClose(int refnum, bool wait); - int ClientActivate(int refnum, bool state); + int ClientActivate(int refnum, bool is_real_time); int ClientDeactivate(int refnum); int GetClientPID(const char* name); @@ -118,6 +119,7 @@ class SERVER_EXPORT JackEngine // Notifications void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); + void NotifyFailure(int code, const char* reason); void NotifyXRun(int refnum); void NotifyGraphReorder(); void NotifyBufferSize(jack_nframes_t buffer_size); diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 41c9c5b8..326e3b7f 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -58,6 +58,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem float fXrunDelayedUsecs; bool fTimeOut; bool fRealTime; + bool fSavedRealTime; // RT state saved and restored during Freewheel mode int fServerPriority; int fClientPriority; int fMaxClientPriority; @@ -100,6 +101,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem fTimeOut = (timeout > 0); fTimeOutUsecs = timeout * 1000; fRealTime = rt; + fSavedRealTime = false; fServerPriority = priority; fClientPriority = (rt) ? priority - 5 : 0; fMaxClientPriority = (rt) ? priority - 1 : 0; diff --git a/common/JackError.cpp b/common/JackError.cpp index aad72327..3705c35c 100644 --- a/common/JackError.cpp +++ b/common/JackError.cpp @@ -25,8 +25,6 @@ #include "JackGlobals.h" #include "JackMessageBuffer.h" -int jack_verbose = 0; - using namespace Jack; void change_thread_log_function(jack_log_function_t log_function) @@ -110,7 +108,7 @@ SERVER_EXPORT void jack_info(const char *fmt, ...) SERVER_EXPORT void jack_log(const char *fmt,...) { - if (jack_verbose) { + if (JackGlobals::fVerbose) { va_list ap; va_start(ap, fmt); jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); diff --git a/common/JackError.h b/common/JackError.h index fca6ec30..403c55ae 100644 --- a/common/JackError.h +++ b/common/JackError.h @@ -58,8 +58,6 @@ extern "C" void jack_log_function(int level, const char *message); SERVER_EXPORT void set_threaded_log_function(); - - extern int jack_verbose; #ifdef __cplusplus } diff --git a/common/JackException.h b/common/JackException.h index af899b8a..3270f20a 100644 --- a/common/JackException.h +++ b/common/JackException.h @@ -58,7 +58,25 @@ class SERVER_EXPORT JackException : public std::runtime_error { }; /*! -\brief Exception possibly thrown by Net Slaves. + \brief Exception thrown by JackEngine in temporary mode. + */ + +class SERVER_EXPORT JackTemporaryException : public JackException { + + public: + + JackTemporaryException(const std::string& msg) : JackException(msg) + {} + JackTemporaryException(char* msg) : JackException(msg) + {} + JackTemporaryException(const char* msg) : JackException(msg) + {} + JackTemporaryException() : JackException("") + {} +}; + +/*! +\brief Exception possibly thrown by Net slaves. */ class SERVER_EXPORT JackNetException : public JackException { diff --git a/common/JackExternalClient.cpp b/common/JackExternalClient.cpp index c86f1d17..4d56557b 100644 --- a/common/JackExternalClient.cpp +++ b/common/JackExternalClient.cpp @@ -33,11 +33,11 @@ JackExternalClient::JackExternalClient(): fClientControl(NULL) JackExternalClient::~JackExternalClient() {} -int JackExternalClient::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackExternalClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int result = -1; jack_log("JackExternalClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify); - fChannel.ClientNotify(refnum, name, notify, sync, value1, value2, &result); + fChannel.ClientNotify(refnum, name, notify, sync, message, value1, value2, &result); return result; } diff --git a/common/JackExternalClient.h b/common/JackExternalClient.h index daafb199..29e0f7d6 100644 --- a/common/JackExternalClient.h +++ b/common/JackExternalClient.h @@ -49,7 +49,7 @@ class JackExternalClient : public JackClientInterface int Open(const char* name, int pid, int refnum, int* shared_client); int Close(); - int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); JackClientControl* GetClientControl() const; }; diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index 599523db..c8c40545 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { +bool JackGlobals::fVerbose = 0; + jack_tls_key JackGlobals::fRealTime; static bool gKeyRealtimeInitialized = jack_tls_allocate_key(&JackGlobals::fRealTime); diff --git a/common/JackGlobals.h b/common/JackGlobals.h index f5516f73..7586708e 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -// Globals used for client management on server or libray side. +// Globals used for client management on server or library side. struct JackGlobals { static jack_tls_key fRealTime; @@ -34,10 +34,10 @@ struct JackGlobals { static JackMutex* fOpenMutex; static bool fServerRunning; static JackClient* fClientTable[]; + static bool fVerbose; #ifndef WIN32 static jack_thread_creator_t fJackThreadCreator; #endif - }; // Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index f6aae030..d16becd6 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -135,8 +135,8 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff JackConnectionManager* manager = ReadCurrentState(); JackPort* port = GetPort(port_index); + // This happens when a port has just been unregistered and is still used by the RT code if (!port->IsUsed()) { - // This happens when a port has just been unregistered and is still used by the RT code. jack_log("JackGraphManager::GetBuffer : port = %ld is released state", port_index); return GetBuffer(0); // port_index 0 is not used } @@ -149,14 +149,29 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff // Input port jack_int_t len = manager->Connections(port_index); - if (len == 0) { // No connections: return a zero-filled buffer + // No connections : return a zero-filled buffer + if (len == 0) { 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 - + + // One connection + } else if (len == 1) { + jack_port_id_t src_index = manager->GetPort(port_index, 0); + + // Ports in same client : copy the buffer + if (GetPort(src_index)->GetRefNum() == port->GetRefNum()) { + void* buffers[1]; + buffers[0] = GetBuffer(src_index, buffer_size); + port->MixBuffers(buffers, 1, buffer_size); + return port->GetBuffer(); + // Otherwise, use zero-copy mode, just pass the buffer of the connected (output) port. + } else { + return GetBuffer(src_index, buffer_size); + } + + // Multiple connections : mix all buffers + } else { + const jack_int_t* connections = manager->GetConnections(port_index); void* buffers[CONNECTION_NUM_FOR_PORT]; jack_port_id_t src_index; @@ -167,7 +182,6 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff buffers[i] = GetBuffer(src_index, buffer_size); } - JackPort* port = GetPort(port_index); port->MixBuffers(buffers, i, buffer_size); return port->GetBuffer(); } @@ -688,6 +702,9 @@ const char** JackGraphManager::GetConnections(jack_port_id_t port_index) { const char** res = (const char**)malloc(sizeof(char*) * CONNECTION_NUM_FOR_PORT); UInt16 cur_index, next_index; + + if (!res) + return NULL; do { cur_index = GetCurrentIndex(); @@ -768,6 +785,9 @@ const char** JackGraphManager::GetPorts(const char* port_name_pattern, const cha { const char** res = (const char**)malloc(sizeof(char*) * PORT_NUM); UInt16 cur_index, next_index; + + if (!res) + return NULL; do { cur_index = GetCurrentIndex(); diff --git a/common/JackInternalClientChannel.h b/common/JackInternalClientChannel.h index 59eaa8c9..93130ca5 100644 --- a/common/JackInternalClientChannel.h +++ b/common/JackInternalClientChannel.h @@ -63,9 +63,9 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface *result = fEngine->ClientInternalClose(refnum, true); } - void ClientActivate(int refnum, int state, int* result) + void ClientActivate(int refnum, int is_real_time, int* result) { - *result = fEngine->ClientActivate(refnum, state); + *result = fEngine->ClientActivate(refnum, is_real_time); } void ClientDeactivate(int refnum, int* result) { diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp index be6522f0..b2cce06f 100644 --- a/common/JackLibAPI.cpp +++ b/common/JackLibAPI.cpp @@ -111,14 +111,22 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { - assert(JackGlobals::fOpenMutex); - JackGlobals::fOpenMutex->Lock(); - va_list ap; - va_start(ap, status); - jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); - va_end(ap); - JackGlobals::fOpenMutex->Unlock(); - return res; + try { + assert(JackGlobals::fOpenMutex); + JackGlobals::fOpenMutex->Lock(); + va_list ap; + va_start(ap, status); + jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); + va_end(ap); + JackGlobals::fOpenMutex->Unlock(); + return res; + } catch(std::bad_alloc& e) { + jack_error("Memory allocation error..."); + return NULL; + } catch (...) { + jack_error("Unknown error..."); + return NULL; + } } EXPORT int jack_client_close(jack_client_t* ext_client) diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp index ff6055e5..4c92e9e3 100644 --- a/common/JackLibClient.cpp +++ b/common/JackLibClient.cpp @@ -99,7 +99,7 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_options_ JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName); JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName); fClientControl.SetShmIndex(shared_client, fServerName); - jack_verbose = GetEngineControl()->fVerbose; + JackGlobals::fVerbose = GetEngineControl()->fVerbose; } catch (int n) { jack_error("Map shared memory segments exception %d", n); goto error; @@ -128,7 +128,7 @@ error: // Notifications received from the server // TODO this should be done once for all clients in the process, when a shared notification channel // will be shared by all clients... -int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { int res = 0; diff --git a/common/JackLibClient.h b/common/JackLibClient.h index 3ad9e3c9..0621ed15 100644 --- a/common/JackLibClient.h +++ b/common/JackLibClient.h @@ -46,7 +46,7 @@ class JackLibClient : public JackClient int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status); - int ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value2); + int ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); JackGraphManager* GetGraphManager() const; JackEngineControl* GetEngineControl() const; diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index 3dd75135..51fc6ce0 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -22,10 +22,35 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackEngine.h" #include "JackMutex.h" +#include "JackTools.h" +#include "JackException.h" namespace Jack { +#define TRY_CALL \ + try { \ + +#define CATCH_EXCEPTION_RETURN \ + } catch(std::bad_alloc& e) { \ + jack_error("Memory allocation error..."); \ + return -1; \ + } catch(JackTemporaryException& e) { \ + jack_error("JackTemporaryException : now quits..."); \ + JackTools::KillServer(); \ + return -1; \ + } catch (...) { \ + jack_error("Unknown error..."); \ + return -1; \ + } \ + +#define CATCH_ENGINE_EXCEPTION \ + } catch(std::bad_alloc& e) { \ + jack_error("Memory allocation error..."); \ + } catch (...) { \ + jack_error("Unknown error..."); \ + } \ + /*! \brief Locked Engine, access to methods is serialized using a mutex. */ @@ -47,108 +72,146 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble int Open() { // No lock needed + TRY_CALL return fEngine.Open(); + CATCH_EXCEPTION_RETURN } int Close() { // No lock needed + TRY_CALL return fEngine.Close(); + CATCH_EXCEPTION_RETURN } // Client management int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) { + TRY_CALL JackLock lock(this); return fEngine.ClientCheck(name, name_res, protocol, options, status); + CATCH_EXCEPTION_RETURN } int ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) { + TRY_CALL JackLock lock(this); return fEngine.ClientExternalOpen(name, pid, ref, shared_engine, shared_client, shared_graph_manager); + CATCH_EXCEPTION_RETURN } int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) { + TRY_CALL JackLock lock(this); return fEngine.ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait); + CATCH_EXCEPTION_RETURN } int ClientExternalClose(int refnum) { + TRY_CALL JackLock lock(this); return fEngine.ClientExternalClose(refnum); + CATCH_EXCEPTION_RETURN } int ClientInternalClose(int refnum, bool wait) { + TRY_CALL JackLock lock(this); return fEngine.ClientInternalClose(refnum, wait); + CATCH_EXCEPTION_RETURN } - int ClientActivate(int refnum, bool state) + int ClientActivate(int refnum, bool is_real_time) { + TRY_CALL JackLock lock(this); - return fEngine.ClientActivate(refnum, state); + return fEngine.ClientActivate(refnum, is_real_time); + CATCH_EXCEPTION_RETURN } int ClientDeactivate(int refnum) { + TRY_CALL JackLock lock(this); return fEngine.ClientDeactivate(refnum); + CATCH_EXCEPTION_RETURN } // Internal client management int GetInternalClientName(int int_ref, char* name_res) { + TRY_CALL JackLock lock(this); return fEngine.GetInternalClientName(int_ref, name_res); + CATCH_EXCEPTION_RETURN } int InternalClientHandle(const char* client_name, int* status, int* int_ref) { + TRY_CALL JackLock lock(this); return fEngine.InternalClientHandle(client_name, status, int_ref); + CATCH_EXCEPTION_RETURN } int InternalClientUnload(int refnum, int* status) { + TRY_CALL JackLock lock(this); return fEngine.InternalClientUnload(refnum, status); + CATCH_EXCEPTION_RETURN } // Port management int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port) { + TRY_CALL JackLock lock(this); return fEngine.PortRegister(refnum, name, type, flags, buffer_size, port); + CATCH_EXCEPTION_RETURN } int PortUnRegister(int refnum, jack_port_id_t port) { + TRY_CALL JackLock lock(this); return fEngine.PortUnRegister(refnum, port); + CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, const char* src, const char* dst) { + TRY_CALL JackLock lock(this); return fEngine.PortConnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, const char* src, const char* dst) { + TRY_CALL JackLock lock(this); return fEngine.PortDisconnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { + TRY_CALL JackLock lock(this); return fEngine.PortConnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) { + TRY_CALL JackLock lock(this); return fEngine.PortDisconnect(refnum, src, dst); + CATCH_EXCEPTION_RETURN } - + int PortRename(int refnum, jack_port_id_t port, const char* name) { + TRY_CALL JackLock lock(this); return fEngine.PortRename(refnum, port, name); + CATCH_EXCEPTION_RETURN } // Graph @@ -167,42 +230,64 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble void NotifyXRun(int refnum) { + TRY_CALL JackLock lock(this); fEngine.NotifyXRun(refnum); + CATCH_ENGINE_EXCEPTION } void NotifyGraphReorder() { + TRY_CALL JackLock lock(this); fEngine.NotifyGraphReorder(); + CATCH_ENGINE_EXCEPTION } void NotifyBufferSize(jack_nframes_t buffer_size) { + TRY_CALL JackLock lock(this); fEngine.NotifyBufferSize(buffer_size); + CATCH_ENGINE_EXCEPTION } void NotifySampleRate(jack_nframes_t sample_rate) { + TRY_CALL JackLock lock(this); fEngine.NotifySampleRate(sample_rate); + CATCH_ENGINE_EXCEPTION } void NotifyFreewheel(bool onoff) { + TRY_CALL JackLock lock(this); fEngine.NotifyFreewheel(onoff); + CATCH_ENGINE_EXCEPTION } - + + void NotifyFailure(int code, const char* reason) + { + TRY_CALL + JackLock lock(this); + fEngine.NotifyFailure(code, reason); + CATCH_ENGINE_EXCEPTION + } + int GetClientPID(const char* name) { + TRY_CALL JackLock lock(this); return fEngine.GetClientPID(name); + CATCH_EXCEPTION_RETURN } - + int GetClientRefNum(const char* name) { + TRY_CALL JackLock lock(this); return fEngine.GetClientRefNum(name); + CATCH_EXCEPTION_RETURN } - + }; } // end of namespace diff --git a/common/JackMessageBuffer.cpp b/common/JackMessageBuffer.cpp index 18e4d52f..8dacfe67 100644 --- a/common/JackMessageBuffer.cpp +++ b/common/JackMessageBuffer.cpp @@ -29,18 +29,24 @@ namespace Jack JackMessageBuffer* JackMessageBuffer::fInstance = NULL; JackMessageBuffer::JackMessageBuffer() - :fThread(this),fInBuffer(0),fOutBuffer(0),fOverruns(0) + :fThread(this),fInBuffer(0),fOutBuffer(0),fOverruns(0),fRunning(false) +{} + +JackMessageBuffer::~JackMessageBuffer() +{} + +void JackMessageBuffer::Start() { fRunning = true; fThread.StartSync(); } -JackMessageBuffer::~JackMessageBuffer() +void JackMessageBuffer::Stop() { if (fOverruns > 0) { jack_error("WARNING: %d message buffer overruns!", fOverruns); } else { - jack_info("no message buffer overruns"); + jack_log("no message buffer overruns"); } fGuard.Lock(); fRunning = false; @@ -49,7 +55,7 @@ JackMessageBuffer::~JackMessageBuffer() fThread.Stop(); Flush(); } - + void JackMessageBuffer::Flush() { while (fOutBuffer != fInBuffer) { @@ -86,12 +92,14 @@ void JackMessageBuffer::Create() { if (fInstance == NULL) { fInstance = new JackMessageBuffer(); + fInstance->Start(); } } void JackMessageBuffer::Destroy() { if (fInstance != NULL) { + fInstance->Stop(); delete fInstance; fInstance = NULL; } @@ -100,8 +108,7 @@ void JackMessageBuffer::Destroy() void JackMessageBufferAdd(int level, const char *message) { if (Jack::JackMessageBuffer::fInstance == NULL) { - /* Unable to print message with realtime safety. - * Complain and print it anyway. */ + /* Unable to print message with realtime safety. Complain and print it anyway. */ jack_log_function(LOG_LEVEL_ERROR, "messagebuffer not initialized, skip message"); } else { Jack::JackMessageBuffer::fInstance->AddMessage(level, message); diff --git a/common/JackMessageBuffer.h b/common/JackMessageBuffer.h index 23bb12a6..5e3472a5 100644 --- a/common/JackMessageBuffer.h +++ b/common/JackMessageBuffer.h @@ -66,10 +66,13 @@ class JackMessageBuffer : public JackRunnableInterface bool fRunning; void Flush(); + + void Start(); + void Stop(); public: - JackMessageBuffer(); + JackMessageBuffer(); ~JackMessageBuffer(); // JackRunnableInterface interface diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 931f7651..5532f01e 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -228,8 +228,8 @@ namespace Jack // Will do "something" on OSX only... fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) { - jack_error("AcquireRealTime error"); + if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) { + jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } @@ -251,7 +251,7 @@ namespace Jack e.PrintMessage(); jack_info("NetAdapter is restarted."); Reset(); - fThread.DropRealTime(); + fThread.DropSelfRealTime(); fThread.SetStatus(JackThread::kIniting); if (Init()) { fThread.SetStatus(JackThread::kRunning); diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 641c95c4..5f5af5db 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -53,6 +53,7 @@ namespace Jack fMidiPlaybackPortList = NULL; #ifdef JACK_MONITOR fNetTimeMon = NULL; + fRcvSyncUst = 0; #endif } @@ -208,7 +209,7 @@ namespace Jack JackDriver::NotifySampleRate ( fParams.fSampleRate ); //transport engine parametering - fEngineControl->fTransport.SetNetworkSync ( true ); + fEngineControl->fTransport.SetNetworkSync ( fParams.fTransportSync ); return true; } @@ -418,6 +419,7 @@ namespace Jack break; case JackTransportRolling : + //fEngineControl->fTransport.SetCommand ( TransportCommandStart ); fEngineControl->fTransport.SetState ( JackTransportRolling ); jack_info ( "Master is rolling." ); break; @@ -427,6 +429,7 @@ namespace Jack void JackNetDriver::EncodeTransportData() { + /* Desactivated //is there a timebase master change ? int refnum; bool conditional; @@ -449,12 +452,14 @@ namespace Jack } else fReturnTransportData.fTimebaseMaster = NO_CHANGE; - + */ + //update transport state and position fReturnTransportData.fState = fEngineControl->fTransport.Query ( &fReturnTransportData.fPosition ); - + //is it a new state (that the master need to know...) ? - fReturnTransportData.fNewState = ( ( fReturnTransportData.fState != fLastTransportState ) && + fReturnTransportData.fNewState = (( fReturnTransportData.fState == JackTransportNetStarting) && + ( fReturnTransportData.fState != fLastTransportState ) && ( fReturnTransportData.fState != fSendTransportData.fState ) ); if ( fReturnTransportData.fNewState ) jack_info ( "Sending '%s'.", GetTransportState ( fReturnTransportData.fState ) ); @@ -481,22 +486,27 @@ namespace Jack if ( SyncRecv() == SOCKET_ERROR ) return 0; - //take the time at the beginning of the cycle - JackDriver::CycleTakeBeginTime(); +#ifdef JACK_MONITOR + // For timing + fRcvSyncUst = GetMicroSeconds(); +#endif //decode sync //if there is an error, don't return -1, it will skip Write() and the network error probably won't be identified DecodeSyncPacket(); #ifdef JACK_MONITOR - fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif //audio, midi or sync if driver is late if ( DataRecv() == SOCKET_ERROR ) return SOCKET_ERROR; + //take the time at the beginning of the cycle + JackDriver::CycleTakeBeginTime(); + #ifdef JACK_MONITOR - fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif return 0; @@ -514,7 +524,7 @@ namespace Jack fNetAudioPlaybackBuffer->SetBuffer ( audio_port_index, GetOutputBuffer ( audio_port_index ) ); #ifdef JACK_MONITOR - fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif //sync @@ -525,7 +535,7 @@ namespace Jack return SOCKET_ERROR; #ifdef JACK_MONITOR - fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->Add ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif //send data @@ -533,7 +543,7 @@ namespace Jack return SOCKET_ERROR; #ifdef JACK_MONITOR - fNetTimeMon->AddLast ( ( ( float ) ( GetMicroSeconds() - JackDriver::fBeginDateUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); + fNetTimeMon->AddLast ( ( ( float ) ( GetMicroSeconds() - fRcvSyncUst ) / ( float ) fEngineControl->fPeriodUsecs ) * 100.f ); #endif return 0; diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index d8fb0bb2..af137b43 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -40,15 +40,16 @@ namespace Jack //jack data jack_port_id_t* fMidiCapturePortList; jack_port_id_t* fMidiPlaybackPortList; - + //transport int fLastTransportState; int fLastTimebaseMaster; //monitoring -#ifdef JACK_MONITOR + #ifdef JACK_MONITOR JackGnuPlotMonitor* fNetTimeMon; -#endif + jack_time_t fRcvSyncUst; + #endif bool Initialize(); void FreeAll(); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index b4e45853..b42d970e 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -305,6 +305,7 @@ namespace Jack else jack_info ( "'%s' isn't the timebase master anymore.", fParams.fName ); break; + case TIMEBASEMASTER : timebase = jack_set_timebase_callback ( fJackClient, 0, SetTimebaseCallback, this ); if ( timebase < 0 ) @@ -312,6 +313,7 @@ namespace Jack else jack_info ( "'%s' is the new timebase master.", fParams.fName ); break; + case CONDITIONAL_TIMEBASEMASTER : timebase = jack_set_timebase_callback ( fJackClient, 1, SetTimebaseCallback, this ); if ( timebase != EBUSY ) @@ -334,15 +336,18 @@ namespace Jack jack_transport_stop ( fJackClient ); jack_info ( "'%s' stops transport.", fParams.fName ); break; + case JackTransportStarting : if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) == EINVAL ) jack_error ( "Can't set new position." ); jack_transport_start ( fJackClient ); - jack_info ( "'%s' starts transport frame = %d frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); + jack_info ( "'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); break; + case JackTransportNetStarting : jack_info ( "'%s' is ready to roll..", fParams.fName ); break; + case JackTransportRolling : jack_info ( "'%s' is rolling.", fParams.fName ); break; diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp new file mode 100644 index 00000000..bc0160bc --- /dev/null +++ b/common/JackNetOneDriver.cpp @@ -0,0 +1,1143 @@ +/* +Copyright (C) 2001 Paul Davis +Copyright (C) 2008 Romain Moret at 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. +*/ + +//#define HAVE_CELT 1 + +#ifdef WIN32 +#include +#endif + +#include "JackNetOneDriver.h" +#include "JackEngineControl.h" +#include "JackGraphManager.h" +#include "JackWaitThreadedDriver.h" +#include "JackTools.h" +#include "driver_interface.h" + +#include "netjack.h" +#include "netjack_packet.h" + +#if HAVE_SAMPLERATE +#include "samplerate.h" +#endif + +#if HAVE_CELT +#include "celt/celt.h" +#endif + +#define MIN(x,y) ((x)<(y) ? (x) : (y)) + +using namespace std; + +namespace Jack +{ + JackNetOneDriver::JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, + int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, + int sample_rate, int period_size, int resample_factor, + const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, + int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ) + : JackAudioDriver ( name, alias, engine, table ) + { + jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port ); + +#ifdef WIN32 + WSADATA wsa; + int rc = WSAStartup(MAKEWORD(2,0),&wsa); +#endif + + netjack_init( & (this->netj), + NULL, // client + name, + capture_ports, + playback_ports, + midi_input_ports, + midi_output_ports, + sample_rate, + period_size, + port, + transport_sync, + resample_factor, + 0, + bitdepth, + use_autoconfig, + latency, + redundancy, + dont_htonl_floats, + always_deadline, + jitter_val); + } + + JackNetOneDriver::~JackNetOneDriver() + { + // No destructor yet. + } + +//open, close, attach and detach------------------------------------------------------ + int JackNetOneDriver::Open ( jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing, + int inchannels, int outchannels, bool monitor, + const char* capture_driver_name, const char* playback_driver_name, + jack_nframes_t capture_latency, jack_nframes_t playback_latency ) + { + if ( JackAudioDriver::Open ( buffer_size, + samplerate, + capturing, + playing, + inchannels, + outchannels, + monitor, + capture_driver_name, + playback_driver_name, + capture_latency, + playback_latency ) == 0 ) + { + fEngineControl->fPeriod = 0; + fEngineControl->fComputation = 500 * 1000; + fEngineControl->fConstraint = 500 * 1000; + return 0; + } + else + { + jack_error( "open fail" ); + return -1; + } + } + + int JackNetOneDriver::Close() + { + FreePorts(); + netjack_release( &netj ); + return JackDriver::Close(); + } + + int JackNetOneDriver::Attach() + { + return 0; + } + + int JackNetOneDriver::Detach() + { + return 0; + } + + int JackNetOneDriver::AllocPorts() + { + jack_port_id_t port_id; + char buf[64]; + unsigned int chn; + int port_flags; + + + //if (netj.handle_transport_sync) + // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); + + port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + + for (chn = 0; chn < netj.capture_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); + + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, + static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.capture_ports = + jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); + + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); +#else + celt_int32_t lookahead; + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); +#endif + celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj.codec_latency = 2*lookahead; +#endif + } else { +#if HAVE_SAMPLERATE + netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); +#endif + } + } + for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); + + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, + static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.capture_ports = + jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id); + } + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + for (chn = 0; chn < netj.playback_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); + + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, + static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.playback_ports = + jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); +#endif + } + } + for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); + + if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, + static_cast ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT ) + { + jack_error ( "driver: cannot register port for %s", buf ); + return -1; + } + //port = fGraphManager->GetPort ( port_id ); + + netj.playback_ports = + jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); + } + return 0; + } + +//init and restart-------------------------------------------------------------------- + bool JackNetOneDriver::Initialize() + { + jack_log ( "JackNetOneDriver::Init()" ); + + if( global_packcache != NULL ) { + FreePorts(); + netjack_release( &netj ); + } + + //display some additional infos + jack_info ( "NetOne driver started" ); + if( netjack_startup( &netj ) ) { + return false; + } + + //register jack ports + if ( AllocPorts() != 0 ) + { + jack_error ( "Can't allocate ports." ); + return false; + } + + + //monitor + //driver parametering + JackAudioDriver::SetBufferSize ( netj.period_size ); + JackAudioDriver::SetSampleRate ( netj.sample_rate ); + + JackDriver::NotifyBufferSize ( netj.period_size ); + JackDriver::NotifySampleRate ( netj.sample_rate ); + + //transport engine parametering + fEngineControl->fTransport.SetNetworkSync ( true ); + return true; + } + + +//jack ports and buffers-------------------------------------------------------------- + +//driver processes-------------------------------------------------------------------- + int JackNetOneDriver::Read() + { + int delay; + delay = netjack_wait( &netj ); + if( delay ) { + NotifyXRun(fBeginDateUst, (float) delay); + jack_error( "netxruns... duration: %dms", delay/1000 ); + } + + if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) + JackTools::ThrowJackNetException(); + + //netjack_read( &netj, netj.period_size ); + JackDriver::CycleTakeBeginTime(); + + jack_position_t local_trans_pos; + jack_transport_state_t local_trans_state; + + unsigned int *packet_buf, *packet_bufX; + + if( ! netj.packet_data_valid ) { + jack_log( "data not valid" ); + render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + return 0; + } + packet_buf = netj.rx_buf; + + jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; + + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + + netj.reply_port = pkthdr->reply_port; + netj.latency = pkthdr->latency; + + // Special handling for latency=0 + if( netj.latency == 0 ) + netj.resync_threshold = 0; + else + netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); + + // check whether, we should handle the transport sync stuff, or leave trnasports untouched. + if (netj.handle_transport_sync) { +#if 1 + unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); + + // read local transport info.... + //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); + + local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); + + // Now check if we have to start or stop local transport to sync to remote... + switch (pkthdr->transport_state) { + case JackTransportStarting: + // the master transport is starting... so we set our reply to the sync_callback; + if (local_trans_state == JackTransportStopped) { + fEngineControl->fTransport.SetCommand ( TransportCommandStart ); + //jack_transport_start(netj.client); + //last_transport_state = JackTransportStopped; + netj.sync_state = 0; + jack_info("locally stopped... starting..."); + } + + if (local_trans_pos.frame != compensated_tranport_pos) + { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = compensated_tranport_pos + 2*netj.period_size; + new_pos.valid = (jack_position_bits_t) 0; + + + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, compensated_tranport_pos); + //last_transport_state = JackTransportRolling; + netj.sync_state = 0; + jack_info("starting locate to %d", compensated_tranport_pos ); + } + break; + case JackTransportStopped: + netj.sync_state = 1; + if (local_trans_pos.frame != (pkthdr->transport_frame)) { + jack_position_t new_pos = local_trans_pos; + new_pos.frame = pkthdr->transport_frame; + new_pos.valid = (jack_position_bits_t)0; + fEngineControl->fTransport.RequestNewPos ( &new_pos ); + //jack_transport_locate(netj.client, (pkthdr->transport_frame)); + jack_info("transport is stopped locate to %d", pkthdr->transport_frame); + } + if (local_trans_state != JackTransportStopped) + //jack_transport_stop(netj.client); + fEngineControl->fTransport.SetCommand ( TransportCommandStop ); + break; + case JackTransportRolling: + netj.sync_state = 1; +// if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { +// jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); +// jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); +// } + if (local_trans_state != JackTransportRolling) + fEngineControl->fTransport.SetState ( JackTransportRolling ); + + break; + + case JackTransportLooping: + break; + } +#endif + } + + render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + packet_cache_release_packet(global_packcache, netj.expected_framecnt ); + return 0; + } + + int JackNetOneDriver::Write() + { + int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); + uint32_t *packet_buf, *packet_bufX; + + int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); + jacknet_packet_header *pkthdr; + + packet_buf = (uint32_t *) alloca(packet_size); + pkthdr = (jacknet_packet_header *)packet_buf; + + if( netj.running_free ) { + return 0; + } + + // offset packet_bufX by the packetheader. + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + + pkthdr->sync_state = syncstate;; + pkthdr->latency = netj.time_to_deadline; + //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); + pkthdr->framecnt = netj.expected_framecnt; + + + render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); + + packet_header_hton(pkthdr); + if (netj.srcaddress_valid) + { + unsigned int r; + +#ifdef __APPLE__ + static const int flag = 0; +#else + static const int flag = 0; +#endif + + if (netj.reply_port) + netj.syncsource_address.sin_port = htons(netj.reply_port); + + for( r=0; rdata; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + } + netj.capture_ports = NULL; + + node = netj.playback_ports; + while( node != NULL ) { + JSList *this_node = node; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + fGraphManager->ReleasePort( fClientControl.fRefNum, port_id ); + } + netj.playback_ports = NULL; + + if( netj.bitdepth == CELT_MODE ) { +#if HAVE_CELT + node = netj.playback_srcs; + while( node != NULL ) { + JSList *this_node = node; + CELTEncoder *enc = (CELTEncoder *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + celt_encoder_destroy( enc ); + } + netj.playback_srcs = NULL; + + node = netj.capture_srcs; + while( node != NULL ) { + JSList *this_node = node; + CELTDecoder *dec = (CELTDecoder *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + celt_decoder_destroy( dec ); + } + netj.capture_srcs = NULL; +#endif + } else { +#if HAVE_SAMPLERATE + node = netj.playback_srcs; + while( node != NULL ) { + JSList *this_node = node; + SRC_STATE *state = (SRC_STATE *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + src_delete( state ); + } + netj.playback_srcs = NULL; + + node = netj.capture_srcs; + while( node != NULL ) { + JSList *this_node = node; + SRC_STATE *state = (SRC_STATE *) node->data; + node = jack_slist_remove_link( node, this_node ); + jack_slist_free_1( this_node ); + src_delete( state ); + } + netj.capture_srcs = NULL; +#endif + } +} +//Render functions-------------------------------------------------------------------- + +// render functions for float +void +JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ + uint32_t chn = 0; + JSList *node = capture_ports; +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *)packet_payload; + + if( !packet_payload ) + return; + + while (node != NULL) + { + unsigned int i; + int_float_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); + + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + + const char *porttype = port->GetType(); + + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_down != nframes) + { + SRC_STATE *src_state = (SRC_STATE *)src_node->data; + for (i = 0; i < net_period_down; i++) + { + packet_bufX[i] = ntohl (packet_bufX[i]); + } + + src.data_in = (float *) packet_bufX; + src.input_frames = net_period_down; + + src.data_out = buf; + src.output_frames = nframes; + + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } + else +#endif + { + if( dont_htonl_floats ) + { + memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); + } + else + { + for (i = 0; i < net_period_down; i++) + { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; + } + } + } + } + else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down; + uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) +{ + uint32_t chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *) packet_payload; + + while (node != NULL) + { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + unsigned int i; + int_float_t val; + jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); + + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + + const char *porttype = port->GetType(); + + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, resample if necessary + +#if HAVE_SAMPLERATE + if (net_period_up != nframes) { + SRC_STATE *src_state = (SRC_STATE *) src_node->data; + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = (float *) packet_bufX; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) + { + packet_bufX[i] = htonl (packet_bufX[i]); + } + src_node = jack_slist_next (src_node); + } + else +#endif + { + if( dont_htonl_floats ) + { + memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); + } + else + { + for (i = 0; i < net_period_up; i++) + { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; + } + } + } + } + else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +#if HAVE_CELT +// render functions for celt. +void +JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + uint32_t chn = 0; + JSList *node = capture_ports; + JSList *src_node = capture_srcs; + + unsigned char *packet_bufX = (unsigned char *)packet_payload; + + while (node != NULL) + { + jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data; + JackPort *port = fGraphManager->GetPort( port_id ); + + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + + const char *portname = port->GetType(); + + + if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, decode celt data. + + CELTDecoder *decoder = (CELTDecoder *)src_node->data; + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); + + src_node = jack_slist_next (src_node); + } + else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + if( packet_payload ) + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + uint32_t chn = 0; + JSList *node = playback_ports; + JSList *src_node = playback_srcs; + + unsigned char *packet_bufX = (unsigned char *)packet_payload; + + while (node != NULL) + { + jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data; + JackPort *port = fGraphManager->GetPort( port_id ); + + jack_default_audio_sample_t* buf = + (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize); + + const char *portname = port->GetType(); + + if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) + { + // audio port, encode celt data. + + int encoded_bytes; + float *floatbuf = (float *)alloca (sizeof(float) * nframes ); + memcpy( floatbuf, buf, nframes*sizeof(float) ); + CELTEncoder *encoder = (CELTEncoder *)src_node->data; + encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); + if( encoded_bytes != (int)net_period_up ) + jack_error( "something in celt changed. netjack needs to be changed to handle this." ); + src_node = jack_slist_next( src_node ); + } + else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +#endif +/* Wrapper functions with bitdepth argument... */ +void +JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ +#if HAVE_CELT + if (bitdepth == CELT_MODE) + render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); + else +#endif + render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); +} + +void +JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) +{ +#if HAVE_CELT + if (bitdepth == CELT_MODE) + render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); + else +#endif + render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); +} + + + +//driver loader----------------------------------------------------------------------- + +#ifdef __cplusplus + extern "C" + { +#endif + SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor () + { + jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) ); + jack_driver_param_desc_t * params; + + strcpy ( desc->name, "netone" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 + strcpy ( desc->desc, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 + + desc->nparams = 18; + params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); + + int i = 0; + strcpy (params[i].name, "audio-ins"); + params[i].character = 'i'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "audio-outs"); + params[i].character = 'o'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 2U; + strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-ins"); + params[i].character = 'I'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "midi-outs"); + params[i].character = 'O'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "rate"); + params[i].character = 'r'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 48000U; + strcpy (params[i].short_desc, "Sample rate"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "period"); + params[i].character = 'p'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1024U; + strcpy (params[i].short_desc, "Frames per period"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "num-periods"); + params[i].character = 'n'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 5U; + strcpy (params[i].short_desc, + "Network latency setting in no. of periods"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "listen-port"); + params[i].character = 'l'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 3000U; + strcpy (params[i].short_desc, + "The socket port we are listening on for sync packets"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "factor"); + params[i].character = 'f'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Factor for sample rate reduction"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "upstream-factor"); + params[i].character = 'u'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Factor for sample rate reduction on the upstream"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "celt"); + params[i].character = 'c'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "sets celt encoding and number of kbits per channel"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "bit-depth"); + params[i].character = 'b'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "transport-sync"); + params[i].character = 't'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Whether to slave the transport to the master transport"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "autoconf"); + params[i].character = 'a'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Whether to use Autoconfig, or just start."); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "redundancy"); + params[i].character = 'R'; + params[i].type = JackDriverParamUInt; + params[i].value.ui = 1U; + strcpy (params[i].short_desc, + "Send packets N times"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "native-endian"); + params[i].character = 'e'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "Dont convert samples to network byte order."); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "jitterval"); + params[i].character = 'J'; + params[i].type = JackDriverParamInt; + params[i].value.i = 0; + strcpy (params[i].short_desc, + "attempted jitterbuffer microseconds on master"); + strcpy (params[i].long_desc, params[i].short_desc); + + i++; + strcpy (params[i].name, "always-deadline"); + params[i].character = 'D'; + params[i].type = JackDriverParamBool; + params[i].value.ui = 0U; + strcpy (params[i].short_desc, + "always use deadline"); + strcpy (params[i].long_desc, params[i].short_desc); + + desc->params = params; + + return desc; + } + + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) + { + jack_nframes_t sample_rate = 48000; + jack_nframes_t resample_factor = 1; + jack_nframes_t period_size = 1024; + unsigned int capture_ports = 2; + unsigned int playback_ports = 2; + unsigned int capture_ports_midi = 1; + unsigned int playback_ports_midi = 1; + unsigned int listen_port = 3000; + unsigned int resample_factor_up = 0; + unsigned int bitdepth = 0; + unsigned int handle_transport_sync = 1; + unsigned int use_autoconfig = 1; + unsigned int latency = 5; + unsigned int redundancy = 1; + unsigned int mtu = 1400; + int dont_htonl_floats = 0; + int always_deadline = 0; + int jitter_val = 0; + const JSList * node; + const jack_driver_param_t * param; + + + + for ( node = params; node; node = jack_slist_next ( node ) ) + { + param = ( const jack_driver_param_t* ) node->data; + switch ( param->character ) + { + case 'i': + capture_ports = param->value.ui; + break; + + case 'o': + playback_ports = param->value.ui; + break; + + case 'I': + capture_ports_midi = param->value.ui; + break; + + case 'O': + playback_ports_midi = param->value.ui; + break; + + case 'r': + sample_rate = param->value.ui; + break; + + case 'p': + period_size = param->value.ui; + break; + + case 'l': + listen_port = param->value.ui; + break; + + case 'f': + #if HAVE_SAMPLERATE + resample_factor = param->value.ui; + #else + jack_error( "not built with libsamplerate support" ); + return NULL; + #endif + break; + + case 'u': + #if HAVE_SAMPLERATE + resample_factor_up = param->value.ui; + #else + jack_error( "not built with libsamplerate support" ); + return NULL; + #endif + break; + + case 'b': + bitdepth = param->value.ui; + break; + + case 'c': + #if HAVE_CELT + bitdepth = CELT_MODE; + resample_factor = param->value.ui; + #else + jack_error( "not built with celt support" ); + return NULL; + #endif + break; + + case 't': + handle_transport_sync = param->value.ui; + break; + + case 'a': + use_autoconfig = param->value.ui; + break; + + case 'n': + latency = param->value.ui; + break; + + case 'R': + redundancy = param->value.ui; + break; + + case 'H': + dont_htonl_floats = param->value.ui; + break; + + case 'J': + jitter_val = param->value.i; + break; + + case 'D': + always_deadline = param->value.ui; + break; + } + } + + try + { + + Jack::JackDriverClientInterface* driver = + new Jack::JackWaitThreadedDriver ( + new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, + capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, + sample_rate, period_size, resample_factor, + "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, + dont_htonl_floats, always_deadline, jitter_val ) ); + + if ( driver->Open ( period_size, sample_rate, 1, 1, capture_ports, playback_ports, + 0, "from_master_", "to_master_", 0, 0 ) == 0 ) + { + return driver; + } + else + { + delete driver; + return NULL; + } + + } + catch ( ... ) + { + return NULL; + } + } + +#ifdef __cplusplus + } +#endif +} diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h new file mode 100644 index 00000000..b288c91f --- /dev/null +++ b/common/JackNetOneDriver.h @@ -0,0 +1,96 @@ +/* +Copyright (C) 2001 Paul Davis +Copyright (C) 2008 Romain Moret at 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. + +*/ + +#ifndef __JackNetDriver__ +#define __JackNetDriver__ + +#include "JackAudioDriver.h" +#include "netjack.h" +#include "netjack_packet.h" + +namespace Jack +{ + /** + \Brief This class describes the Net Backend + */ + + class JackNetOneDriver : public JackAudioDriver + { + private: + netjack_driver_state_t netj; + +void +render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); +void +render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); +#ifdef HAVE_CELT +void +render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes); +void +render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up); +#endif +void +render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats); +void +render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats); + + public: + JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, + int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports, + int sample_rate, int period_size, int resample_factor, + const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, + int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val ); + ~JackNetOneDriver(); + + int Open ( jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing, + int inchannels, int outchannels, bool monitor, const char* capture_driver_name, + const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency ); + + int Close(); + int Attach(); + int Detach(); + + int Read(); + int Write(); + + bool Initialize(); + int AllocPorts(); + void FreePorts(); + + // BufferSize can't be changed + bool IsFixedBufferSize() + { + return true; + } + + int SetBufferSize ( jack_nframes_t buffer_size ) + { + return -1; + } + + int SetSampleRate ( jack_nframes_t sample_rate ) + { + return -1; + } + + }; +} + +#endif diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp index 0d63f33d..81e2404f 100644 --- a/common/JackNetTool.cpp +++ b/common/JackNetTool.cpp @@ -417,6 +417,7 @@ namespace Jack dst_params->fPosition.usecs = htonl(src_params->fPosition.usecs); dst_params->fPosition.frame_rate = htonl(src_params->fPosition.frame_rate); dst_params->fPosition.frame = htonl(src_params->fPosition.frame); + dst_params->fPosition.valid = (jack_position_bits_t)htonl((uint32_t)src_params->fPosition.valid); dst_params->fPosition.bar = htonl(src_params->fPosition.bar); dst_params->fPosition.beat = htonl(src_params->fPosition.beat); dst_params->fPosition.tick = htonl(src_params->fPosition.tick); @@ -442,6 +443,7 @@ namespace Jack dst_params->fPosition.usecs = ntohl(src_params->fPosition.usecs); dst_params->fPosition.frame_rate = ntohl(src_params->fPosition.frame_rate); dst_params->fPosition.frame = ntohl(src_params->fPosition.frame); + dst_params->fPosition.valid = (jack_position_bits_t)ntohl((uint32_t)src_params->fPosition.valid); dst_params->fPosition.bar = ntohl(src_params->fPosition.bar); dst_params->fPosition.beat = ntohl(src_params->fPosition.beat); dst_params->fPosition.tick = ntohl(src_params->fPosition.tick); diff --git a/common/JackNotification.h b/common/JackNotification.h index 0667c1d5..43611a4f 100644 --- a/common/JackNotification.h +++ b/common/JackNotification.h @@ -43,6 +43,7 @@ enum NotificationType { kPortDisconnectCallback = 12, kPortRenameCallback = 13, kRealTimeCallback = 14, + kShutDownCallback = 15, kMaxNotification }; diff --git a/common/JackRequest.h b/common/JackRequest.h index e6243b7b..d366f69e 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -297,25 +297,25 @@ struct JackActivateRequest : public JackRequest { int fRefNum; - int fState; + int fIsRealTime; JackActivateRequest() {} - JackActivateRequest(int refnum, int state) - : JackRequest(JackRequest::kActivateClient), fRefNum(refnum), fState(state) + JackActivateRequest(int refnum, int is_real_time) + : JackRequest(JackRequest::kActivateClient), fRefNum(refnum), fIsRealTime(is_real_time) {} int Read(JackChannelTransaction* trans) { CheckRes(trans->Read(&fRefNum, sizeof(int))); - return trans->Read(&fState, sizeof(int)); + return trans->Read(&fIsRealTime, sizeof(int)); } int Write(JackChannelTransaction* trans) { CheckRes(JackRequest::Write(trans)); CheckRes(trans->Write(&fRefNum, sizeof(int))); - return trans->Write(&fState, sizeof(int)); + return trans->Write(&fIsRealTime, sizeof(int)); } } POST_PACKED_STRUCTURE; @@ -1079,13 +1079,15 @@ struct JackClientNotification int fValue1; int fValue2; int fSync; + char fMessage[JACK_MESSAGE_SIZE + 1]; JackClientNotification(): fNotify(-1), fValue1(-1), fValue2(-1) {} - JackClientNotification(const char* name, int refnum, int notify, int sync, int value1, int value2) + JackClientNotification(const char* name, int refnum, int notify, int sync, const char* message, int value1, int value2) : fRefNum(refnum), fNotify(notify), fValue1(value1), fValue2(value2), fSync(sync) { snprintf(fName, sizeof(fName), "%s", name); + snprintf(fMessage, sizeof(fMessage), "%s", message); } int Read(JackChannelTransaction* trans) @@ -1096,6 +1098,7 @@ struct JackClientNotification CheckRes(trans->Read(&fValue1, sizeof(int))); CheckRes(trans->Read(&fValue2, sizeof(int))); CheckRes(trans->Read(&fSync, sizeof(int))); + CheckRes(trans->Read(&fMessage, JACK_MESSAGE_SIZE + 1)); return 0; } @@ -1107,6 +1110,7 @@ struct JackClientNotification CheckRes(trans->Write(&fValue1, sizeof(int))); CheckRes(trans->Write(&fValue2, sizeof(int))); CheckRes(trans->Write(&fSync, sizeof(int))); + CheckRes(trans->Write(&fMessage, JACK_MESSAGE_SIZE + 1)); return 0; } diff --git a/common/JackRestartThreadedDriver.cpp b/common/JackRestartThreadedDriver.cpp index 125b1697..faf9eb33 100644 --- a/common/JackRestartThreadedDriver.cpp +++ b/common/JackRestartThreadedDriver.cpp @@ -36,7 +36,7 @@ bool JackRestartThreadedDriver::Execute() } catch (JackNetException& e) { e.PrintMessage(); jack_log("Driver is restarted"); - fThread.DropRealTime(); + fThread.DropSelfRealTime(); // Thread in kIniting status again... fThread.SetStatus(JackThread::kIniting); if (Init()) { diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 961266e9..4794a1f3 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -55,7 +55,7 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr fFreewheel = false; JackServerGlobals::fInstance = this; // Unique instance JackServerGlobals::fUserCount = 1; // One user - jack_verbose = verbose; + JackGlobals::fVerbose = verbose; } JackServer::~JackServer() @@ -78,7 +78,7 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) goto fail_close1; } - if (fEngine->Open() != 0) { + if (fEngine->Open() < 0) { jack_error("Cannot open engine"); goto fail_close2; } @@ -88,12 +88,12 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) goto fail_close3; } - if (fFreewheelDriver->Open() != 0) { // before engine open + if (fFreewheelDriver->Open() < 0) { // before engine open jack_error("Cannot open driver"); goto fail_close4; } - if (fAudioDriver->Attach() != 0) { + if (fAudioDriver->Attach() < 0) { jack_error("Cannot attach audio driver"); goto fail_close5; } @@ -168,7 +168,10 @@ int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const int JackServer::Start() { jack_log("JackServer::Start"); - return fAudioDriver->Start(); + if (fAudioDriver->Start() < 0) { + return -1; + } + return fChannel.Start(); } int JackServer::Stop() diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index 1fe4d1c1..e8e6c021 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -105,14 +105,22 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { - assert(JackGlobals::fOpenMutex); - JackGlobals::fOpenMutex->Lock(); - va_list ap; - va_start(ap, status); - jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); - va_end(ap); - JackGlobals::fOpenMutex->Unlock(); - return res; + try { + assert(JackGlobals::fOpenMutex); + JackGlobals::fOpenMutex->Lock(); + va_list ap; + va_start(ap, status); + jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap); + va_end(ap); + JackGlobals::fOpenMutex->Unlock(); + return res; + } catch(std::bad_alloc& e) { + jack_error("Memory allocation error..."); + return NULL; + } catch (...) { + jack_error("Unknown error..."); + return NULL; + } } EXPORT int jack_client_close(jack_client_t* ext_client) diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index b0402522..5db04050 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -46,7 +46,7 @@ struct SERVER_EXPORT JackServerGlobals static bool Init(); static void Destroy(); - static int Start (const char* server_name, + static int Start(const char* server_name, jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, diff --git a/common/JackShmMem.cpp b/common/JackShmMem.cpp index 5d68b86e..90d42e7b 100644 --- a/common/JackShmMem.cpp +++ b/common/JackShmMem.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2008 Grame +Copyright (C) 2004-2009 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 @@ -32,6 +32,12 @@ size_t JackMem::gSize = 0; JackShmMem::JackShmMem() { JackShmMemAble::Init(); + LockMemory(); +} + +JackShmMem::~JackShmMem() +{ + UnlockMemory(); } void JackShmMemAble::Init() @@ -96,8 +102,9 @@ void JackShmMem::operator delete(void* p, size_t size) void JackShmMem::operator delete(void* obj) { - if (obj) + if (obj) { JackShmMem::operator delete(obj, 0); + } } void LockMemoryImp(void* ptr, size_t size) diff --git a/common/JackShmMem.h b/common/JackShmMem.h index 5976c96d..0a00daa5 100644 --- a/common/JackShmMem.h +++ b/common/JackShmMem.h @@ -1,6 +1,6 @@ /* Copyright (C) 2001 Paul Davis -Copyright (C) 2004-2008 Grame +Copyright (C) 2004-2009 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 @@ -129,9 +129,8 @@ class SERVER_EXPORT JackShmMem : public JackShmMemAble protected: JackShmMem(); - ~JackShmMem() - {} - + ~JackShmMem(); + public: void* operator new(size_t size); @@ -162,9 +161,9 @@ class JackShmReadWritePtr throw - 1; fInfo.index = index; if (jack_attach_shm(&fInfo)) { - //jack_error("cannot attach shared memory segment", strerror(errno)); throw - 2; } + GetShmAddress()->LockMemory(); } } @@ -185,9 +184,10 @@ class JackShmReadWritePtr { if (fInfo.index >= 0) { jack_log("JackShmReadWritePtr::~JackShmReadWritePtr %ld", fInfo.index); + GetShmAddress()->UnlockMemory(); jack_release_shm(&fInfo); fInfo.index = -1; - } + } } T* operator->() const @@ -242,15 +242,15 @@ class JackShmReadWritePtr1 throw - 1; fInfo.index = index; if (jack_attach_shm(&fInfo)) { - //jack_error("cannot attach shared memory segment", strerror(errno)); throw - 2; } /* - nobody else needs to access this shared memory any more, so - destroy it. because we have our own attachment to it, it won't - vanish till we exit (and release it). - */ + nobody else needs to access this shared memory any more, so + destroy it. because we have our own attachment to it, it won't + vanish till we exit (and release it). + */ jack_destroy_shm(&fInfo); + GetShmAddress()->LockMemory(); } } @@ -271,6 +271,7 @@ class JackShmReadWritePtr1 { if (fInfo.index >= 0) { jack_log("JackShmReadWritePtr1::~JackShmReadWritePtr1 %ld", fInfo.index); + GetShmAddress()->UnlockMemory(); jack_release_shm(&fInfo); fInfo.index = -1; } @@ -328,9 +329,9 @@ class JackShmReadPtr throw - 1; fInfo.index = index; if (jack_attach_shm_read(&fInfo)) { - //jack_error("cannot attach shared memory segment", strerror(errno)); throw - 2; } + GetShmAddress()->LockMemory(); } } @@ -351,6 +352,7 @@ class JackShmReadPtr { if (fInfo.index >= 0) { jack_log("JackShmPtrRead::~JackShmPtrRead %ld", fInfo.index); + GetShmAddress()->UnlockMemory(); jack_release_shm(&fInfo); fInfo.index = -1; } diff --git a/common/JackThread.h b/common/JackThread.h index 56c62419..9517a303 100644 --- a/common/JackThread.h +++ b/common/JackThread.h @@ -96,9 +96,14 @@ class SERVER_EXPORT JackThreadInterface int Stop(); void Terminate(); - int AcquireRealTime(); - int AcquireRealTime(int priority); - int DropRealTime(); + int AcquireRealTime(); // Used when called from another thread + int AcquireSelfRealTime(); // Used when called from thread itself + + int AcquireRealTime(int priority); // Used when called from another thread + int AcquireSelfRealTime(int priority); // Used when called from thread itself + + int DropRealTime(); // Used when called from another thread + int DropSelfRealTime(); // Used when called from thread itself pthread_t GetThreadID(); diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 0ab139eb..52e49197 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -137,9 +137,9 @@ std::list JackThreadedDriver::GetSlaves() return fDriver->GetSlaves(); } -int JackThreadedDriver::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2) +int JackThreadedDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { - return fDriver->ClientNotify(refnum, name, notify, sync, value1, value2); + return fDriver->ClientNotify(refnum, name, notify, sync, message, value1, value2); } JackClientControl* JackThreadedDriver::GetClientControl() const @@ -215,8 +215,8 @@ bool JackThreadedDriver::Init() // Will do "something" on OSX only... GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { - jack_error("AcquireRealTime error"); + if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { + jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h index 5949472d..f7bbf2d0 100644 --- a/common/JackThreadedDriver.h +++ b/common/JackThreadedDriver.h @@ -94,7 +94,7 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi virtual std::list GetSlaves(); virtual int ProcessSlaves(); - virtual int ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2); + virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); virtual JackClientControl* GetClientControl() const; virtual bool IsRealTime() const; diff --git a/common/JackTools.cpp b/common/JackTools.cpp index cc8c67c3..a7a7020e 100644 --- a/common/JackTools.cpp +++ b/common/JackTools.cpp @@ -33,10 +33,24 @@ using namespace std; namespace Jack { + void JackTools::KillServer() + { +#ifdef WIN32 + exit(1); +#else + kill(GetPID(), SIGINT); +#endif + } + + void JackTools::ThrowJackNetException() + { + throw JackNetException(); + } + #define DEFAULT_TMP_DIR "/tmp" char* jack_tmpdir = (char*)DEFAULT_TMP_DIR; - int JackTools::GetPID() + int JackTools::GetPID() { #ifdef WIN32 return _getpid(); @@ -45,7 +59,7 @@ namespace Jack { #endif } - int JackTools::GetUID() + int JackTools::GetUID() { #ifdef WIN32 return _getpid(); @@ -55,7 +69,7 @@ namespace Jack { #endif } - const char* JackTools::DefaultServerName() + const char* JackTools::DefaultServerName() { const char* server_name; if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL) @@ -66,25 +80,25 @@ namespace Jack { /* returns the name of the per-user subdirectory of jack_tmpdir */ #ifdef WIN32 - char* JackTools::UserDir() + char* JackTools::UserDir() { return ""; } - char* JackTools::ServerDir(const char* server_name, char* server_dir) + char* JackTools::ServerDir(const char* server_name, char* server_dir) { return ""; } void JackTools::CleanupFiles(const char* server_name) {} - int JackTools::GetTmpdir() + int JackTools::GetTmpdir() { return 0; } #else - char* JackTools::UserDir() + char* JackTools::UserDir() { static char user_dir[JACK_PATH_MAX + 1] = ""; @@ -101,7 +115,7 @@ namespace Jack { } /* returns the name of the per-server subdirectory of jack_user_dir() */ - char* JackTools::ServerDir(const char* server_name, char* server_dir) + char* JackTools::ServerDir(const char* server_name, char* server_dir) { /* format the path name into the suppled server_dir char array, * assuming that server_dir is at least as large as JACK_PATH_MAX + 1 */ @@ -110,7 +124,7 @@ namespace Jack { return server_dir; } - void JackTools::CleanupFiles(const char* server_name) + void JackTools::CleanupFiles(const char* server_name) { DIR* dir; struct dirent *dirent; @@ -169,7 +183,7 @@ namespace Jack { } } - int JackTools::GetTmpdir() + int JackTools::GetTmpdir() { FILE* in; size_t len; @@ -201,7 +215,7 @@ namespace Jack { } #endif - void JackTools::RewriteName(const char* name, char* new_name) + void JackTools::RewriteName(const char* name, char* new_name) { size_t i; for (i = 0; i < strlen(name); i++) { @@ -212,7 +226,7 @@ namespace Jack { } new_name[i] = '\0'; } - + #ifdef WIN32 void BuildClientPath(char* path_to_so, int path_len, const char* so_name) @@ -251,7 +265,7 @@ void PrintLoadError(const char* so_name) #else -void PrintLoadError(const char* so_name) +void PrintLoadError(const char* so_name) { jack_log("error loading %s err = %s", so_name, dlerror()); } @@ -264,7 +278,7 @@ void BuildClientPath(char* path_to_so, int path_len, const char* so_name) internal_dir = ADDON_DIR; } } - + snprintf(path_to_so, path_len, "%s/%s.so", internal_dir, so_name); } diff --git a/common/JackTools.h b/common/JackTools.h index 820f91ba..5960fed8 100644 --- a/common/JackTools.h +++ b/common/JackTools.h @@ -36,6 +36,7 @@ #include "driver_interface.h" #include "JackCompilerDeps.h" #include "JackError.h" +#include "JackException.h" #include #include @@ -55,12 +56,16 @@ namespace Jack static int GetPID(); static int GetUID(); + static void KillServer(); + static char* UserDir(); static char* ServerDir ( const char* server_name, char* server_dir ); static const char* DefaultServerName(); static void CleanupFiles ( const char* server_name ); static int GetTmpdir(); static void RewriteName ( const char* name, char* new_name ); + + static void ThrowJackNetException(); }; /*! @@ -201,10 +206,10 @@ namespace Jack return 0; } }; - + void BuildClientPath(char* path_to_so, int path_len, const char* so_name); void PrintLoadError(const char* so_name); - + } #endif diff --git a/common/JackTransportEngine.cpp b/common/JackTransportEngine.cpp index 418d1180..19168eea 100644 --- a/common/JackTransportEngine.cpp +++ b/common/JackTransportEngine.cpp @@ -38,7 +38,8 @@ JackTransportEngine::JackTransportEngine(): JackAtomicArrayStatefPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); - if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { - jack_error("AcquireRealTime error"); + if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { + jack_error("AcquireSelfRealTime error"); } else { set_threaded_log_function(); } @@ -63,7 +63,7 @@ bool JackWaitThreadedDriver::Execute() } catch (JackNetException& e) { e.PrintMessage(); jack_info("Driver is restarted"); - fThread.DropRealTime(); + fThread.DropSelfRealTime(); // Thread in kIniting status again... fThread.SetStatus(JackThread::kIniting); if (Init()) { diff --git a/common/JackWeakAPI.cpp b/common/JackWeakAPI.cpp index 4888a92a..81e21d35 100644 --- a/common/JackWeakAPI.cpp +++ b/common/JackWeakAPI.cpp @@ -21,7 +21,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Completed from Julien Pommier (PianoTeq : http://www.pianoteq.com/) code. */ -#include "jack.h" +#include +#include +#include #include #include #include @@ -32,6 +34,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. (similar to what relaytool is trying to do, but more portably..) */ +typedef void (*print_function)(const char *); +typedef void *(*thread_routine)(void*); + using std::cerr; int libjack_is_present = 0; // public symbol, similar to what relaytool does. @@ -40,7 +45,12 @@ static void *libjack_handle = 0; static void __attribute__((constructor)) tryload_libjack() { if (getenv("SKIP_LIBJACK") == 0) { // just in case libjack is causing troubles.. + #ifdef __APPLE__ + libjack_handle = dlopen("libjack.0.dylib", RTLD_LAZY); + #else libjack_handle = dlopen("libjack.so.0", RTLD_LAZY); + #endif + } libjack_is_present = (libjack_handle != 0); } @@ -65,7 +75,7 @@ void *load_jack_function(const char *fn_name) static fn_name##_ptr_t fn = 0; \ if (fn == 0) { fn = (fn_name##_ptr_t)load_jack_function(#fn_name); } \ if (fn) return (*fn)arguments; \ - else return 0; \ + else return (return_type)-1; \ } #define DECL_VOID_FUNCTION(fn_name, arguments_types, arguments) \ @@ -81,7 +91,7 @@ DECL_FUNCTION(const char *, jack_get_version_string, (), ()); DECL_FUNCTION(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), (client_name, options, status)); DECL_FUNCTION(int, jack_client_close, (jack_client_t *client), (client)); -DECL_FUNCTION(int, jack_client_new, (const char *client_name), (client_name)); +DECL_FUNCTION(jack_client_t *, jack_client_new, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_client_name_size, (), ()); DECL_FUNCTION(char*, jack_get_client_name, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, @@ -89,7 +99,8 @@ DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, const char *load_init), (client_name, load_name, load_init)); DECL_VOID_FUNCTION(jack_internal_client_close, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_is_realtime, (jack_client_t *client), (client)); -DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, function, arg)); +DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, shutdown_callback, arg)); +DECL_VOID_FUNCTION(jack_on_info_shutdown, (jack_client_t* client, JackInfoShutdownCallback shutdown_callback, void* arg), (client, shutdown_callback, arg)); DECL_FUNCTION(int, jack_set_process_callback, (jack_client_t *client, JackProcessCallback process_callback, void *arg), (client, process_callback, arg)); @@ -97,7 +108,7 @@ DECL_FUNCTION(jack_nframes_t, jack_thread_wait, (jack_client_t *client, int stat // DECL_FUNCTION(jack_nframes_t, jack_cycle_wait, (jack_client_t *client), (client)); -DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, , int status), (client, status)); +DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, int status), (client, status)); DECL_FUNCTION(int, jack_set_process_thread, (jack_client_t *client, JackThreadCallback fun, void *arg), (client, fun, arg)); @@ -149,94 +160,102 @@ DECL_FUNCTION(int, jack_port_is_mine, (const jack_client_t *client, const jack_p DECL_FUNCTION(int, jack_port_connected, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_connected_to, (const jack_port_t *port, const char *port_name), (port, port_name)); DECL_FUNCTION(const char**, jack_port_get_connections, (const jack_port_t *port), (port)); -DECL_FUNCTION(const char**, jack_port_get_all_connections, (const jack_port_t *port), (port)); +DECL_FUNCTION(const char**, jack_port_get_all_connections, (const jack_client_t *client,const jack_port_t *port), (client, port)); DECL_FUNCTION(int, jack_port_tie, (jack_port_t *src, jack_port_t *dst), (src, dst)); DECL_FUNCTION(int, jack_port_untie, (jack_port_t *port), (port)); -DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port)); -DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t *), (jack_port_t *port)); -DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t *), (jack_nframes_t)); -DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t*), (jack_port_t* port)); -DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t*)); - -DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port), (const char *port_name)); -DECL_FUNCTION(int, jack_port_set_alias, (jack_port_t *port), (const char *alias)); -DECL_FUNCTION(int, jack_port_unset_alias, (jack_port_t *port), (const char *alias)); -DECL_FUNCTION(int, jack_port_get_aliases, (const jack_port_t *port), (char* const aliases[2])); -DECL_FUNCTION(int, jack_port_request_monitor, (jack_port_t *port), (int onoff)); -DECL_FUNCTION(int, jack_port_request_monitor_by_name, (jack_client_t *client), (const char *port_name), (int onoff)); -DECL_FUNCTION(int, jack_port_ensure_monitor, (jack_port_t *port), (int onoff)); -DECL_FUNCTION(int, jack_port_monitoring_input, (jack_port_t *port)); -DECL_FUNCTION(int, jack_connect, (jack_client_t *), (const char *source_port), (const char *destination_port)); -DECL_FUNCTION(int, jack_disconnect, (jack_client_t *), (const char *source_port), (const char *destination_port)); -DECL_FUNCTION(int, jack_port_disconnect, (jack_client_t *), (jack_port_t *)); -DECL_FUNCTION(int, jack_port_name_size,(void)); -DECL_FUNCTION(int, jack_port_type_size,(void)); +DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port), (port)); +DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t * client, jack_port_t *port), (client, port)); +DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t * port, jack_nframes_t frames), (port, frames)); +DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t* client, jack_port_t* port), (client, port)); +DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t* client),(client)); + +DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port, const char *port_name), (port, port_name)); +DECL_FUNCTION(int, jack_port_set_alias, (jack_port_t *port, const char *alias), (port, alias)); +DECL_FUNCTION(int, jack_port_unset_alias, (jack_port_t *port, const char *alias), (port, alias)); +DECL_FUNCTION(int, jack_port_get_aliases, (const jack_port_t *port, char* const aliases[2]), (port,aliases)); +DECL_FUNCTION(int, jack_port_request_monitor, (jack_port_t *port, int onoff), (port, onoff)); +DECL_FUNCTION(int, jack_port_request_monitor_by_name, (jack_client_t *client, const char *port_name, int onoff), (client, port_name, onoff)); +DECL_FUNCTION(int, jack_port_ensure_monitor, (jack_port_t *port, int onoff), (port, onoff)); +DECL_FUNCTION(int, jack_port_monitoring_input, (jack_port_t *port) ,(port)); +DECL_FUNCTION(int, jack_connect, (jack_client_t * client, const char *source_port, const char *destination_port), (client, source_port, destination_port)); +DECL_FUNCTION(int, jack_disconnect, (jack_client_t * client, const char *source_port, const char *destination_port), (client, source_port, destination_port)); +DECL_FUNCTION(int, jack_port_disconnect, (jack_client_t * client, jack_port_t * port), (client, port)); +DECL_FUNCTION(int, jack_port_name_size,(),()); +DECL_FUNCTION(int, jack_port_type_size,(),()); DECL_FUNCTION(jack_nframes_t, jack_get_sample_rate, (jack_client_t *client), (client)); DECL_FUNCTION(jack_nframes_t, jack_get_buffer_size, (jack_client_t *client), (client)); DECL_FUNCTION(const char**, jack_get_ports, (jack_client_t *client, const char *port_name_pattern, const char * type_name_pattern, unsigned long flags), (client, port_name_pattern, type_name_pattern, flags)); -DECL_FUNCTION(jack_port_t *, jack_port_by_name, (jack_client_t *), (const char *port_name)); -DECL_FUNCTION(jack_port_t *, jack_port_by_id, (jack_client_t *client), (jack_port_id_t port_id)); - -DECL_FUNCTION(int, jack_engine_takeover_timebase, (jack_client_t *)); -DECL_FUNCTION(jack_nframes_t, jack_frames_since_cycle_start, (const jack_client_t *)); -DECL_FUNCTION(jack_time_t, jack_get_time()); -DECL_FUNCTION(jack_nframes_t, jack_time_to_frames, (const jack_client_t *client), (jack_time_t time)); -DECL_FUNCTION(jack_time_t, jack_frames_to_time, (const jack_client_t *client), (jack_nframes_t frames)); -DECL_FUNCTION(jack_nframes_t, jack_frame_time, (const jack_client_t *)); -DECL_FUNCTION(jack_nframes_t, jack_last_frame_time, (const jack_client_t *client)); -DECL_FUNCTION(float, jack_cpu_load, (jack_client_t *client)); -DECL_FUNCTION(pthread_t, jack_client_thread_id, (jack_client_t *)); -DECL_VOID_FUNCTION(jack_set_error_function, (print_function)); -DECL_VOID_FUNCTION(jack_set_info_function, (print_function)); - -DECL_FUNCTION(float, jack_get_max_delayed_usecs, (jack_client_t *client)); -DECL_FUNCTION(float, jack_get_xrun_delayed_usecs, (jack_client_t *client)); -DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs, (jack_client_t *client)); - -DECL_FUNCTION(int, jack_release_timebase, (jack_client_t *client)); -DECL_FUNCTION(int, jack_set_sync_callback, (jack_client_t *client, (JackSyncCallback sync_callback), (void *arg)); -DECL_FUNCTION(int, jack_set_sync_timeout, (jack_client_t *client), (jack_time_t timeout)); -DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client), (int conditional), (JackTimebaseCallback timebase_callback), (void *arg)); -DECL_FUNCTION(int, jack_transport_locate, (jack_client_t *client), (jack_nframes_t frame)); -DECL_FUNCTION(jack_transport_state_t, jack_transport_query, (const jack_client_t *client), (jack_position_t *pos)); -DECL_FUNCTION(jack_nframes_t, jack_get_current_transport_frame, (const jack_client_t *client)); -DECL_FUNCTION(int, jack_transport_reposition, (jack_client_t *client), (jack_position_t *pos)); -DECL_VOID_FUNCTION(jack_transport_start, (jack_client_t *client)); -DECL_VOID_FUNCTION(jack_transport_stop, (jack_client_t *client)); -DECL_VOID_FUNCTION(jack_get_transport_info, (jack_client_t *client), (jack_transport_info_t *tinfo)); -DECL_VOID_FUNCTION(jack_set_transport_info, (jack_client_t *client), (jack_transport_info_t *tinfo)); - -DECL_FUNCTION(int, jack_client_real_time_priority, (jack_client_t*)); -DECL_FUNCTION(int, jack_client_max_real_time_priority, (jack_client_t*)); -DECL_FUNCTION(int, jack_acquire_real_time_scheduling, (pthread_t thread), (int priority)); -DECL_FUNCTION(int, jack_client_create_thread, (jack_client_t* client), - (pthread_t *thread), - (int priority), - (int realtime), // boolean - (thread_routine routine), - (void *arg)); -DECL_FUNCTION(int, jack_drop_real_time_scheduling, (pthread_t thread)); - -DECL_FUNCTION(int, jack_client_stop_thread, (jack_client_t* client), (pthread_t thread)); -DECL_FUNCTION(int, jack_client_kill_thread, (jack_client_t* client), (pthread_t thread)); +DECL_FUNCTION(jack_port_t *, jack_port_by_name, (jack_client_t * client, const char *port_name), (client, port_name)); +DECL_FUNCTION(jack_port_t *, jack_port_by_id, (jack_client_t *client, jack_port_id_t port_id), (client, port_id)); + +DECL_FUNCTION(int, jack_engine_takeover_timebase, (jack_client_t * client), (client)); +DECL_FUNCTION(jack_nframes_t, jack_frames_since_cycle_start, (const jack_client_t * client), (client)); +DECL_FUNCTION(jack_time_t, jack_get_time, (), ()); +DECL_FUNCTION(jack_nframes_t, jack_time_to_frames, (const jack_client_t *client, jack_time_t time), (client, time)); +DECL_FUNCTION(jack_time_t, jack_frames_to_time, (const jack_client_t *client, jack_nframes_t frames), (client, frames)); +DECL_FUNCTION(jack_nframes_t, jack_frame_time, (const jack_client_t *client), (client)); +DECL_FUNCTION(jack_nframes_t, jack_last_frame_time, (const jack_client_t *client), (client)); +DECL_FUNCTION(float, jack_cpu_load, (jack_client_t *client), (client)); +DECL_FUNCTION(pthread_t, jack_client_thread_id, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_set_error_function, (print_function fun), (fun)); +DECL_VOID_FUNCTION(jack_set_info_function, (print_function fun), (fun)); + +DECL_FUNCTION(float, jack_get_max_delayed_usecs, (jack_client_t *client), (client)); +DECL_FUNCTION(float, jack_get_xrun_delayed_usecs, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_reset_max_delayed_usecs, (jack_client_t *client), (client)); + +DECL_FUNCTION(int, jack_release_timebase, (jack_client_t *client), (client)); +DECL_FUNCTION(int, jack_set_sync_callback, (jack_client_t *client, JackSyncCallback sync_callback, void *arg), (client, sync_callback, arg)); +DECL_FUNCTION(int, jack_set_sync_timeout, (jack_client_t *client, jack_time_t timeout), (client, timeout)); +DECL_FUNCTION(int, jack_set_timebase_callback, (jack_client_t *client, + int conditional, + JackTimebaseCallback timebase_callback, + void *arg), (client, conditional, timebase_callback, arg)); +DECL_FUNCTION(int, jack_transport_locate, (jack_client_t *client, jack_nframes_t frame), (client, frame)); +DECL_FUNCTION(jack_transport_state_t, jack_transport_query, (const jack_client_t *client, jack_position_t *pos), (client, pos)); +DECL_FUNCTION(jack_nframes_t, jack_get_current_transport_frame, (const jack_client_t *client), (client)); +DECL_FUNCTION(int, jack_transport_reposition, (jack_client_t *client, jack_position_t *pos), (client, pos)); +DECL_VOID_FUNCTION(jack_transport_start, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_transport_stop, (jack_client_t *client), (client)); +DECL_VOID_FUNCTION(jack_get_transport_info, (jack_client_t *client, jack_transport_info_t *tinfo), (client,tinfo)); +DECL_VOID_FUNCTION(jack_set_transport_info, (jack_client_t *client, jack_transport_info_t *tinfo), (client,tinfo)); + +DECL_FUNCTION(int, jack_client_real_time_priority, (jack_client_t* client), (client)); +DECL_FUNCTION(int, jack_client_max_real_time_priority, (jack_client_t* client), (client)); +DECL_FUNCTION(int, jack_acquire_real_time_scheduling, (pthread_t thread, int priority), (thread, priority)); +DECL_FUNCTION(int, jack_client_create_thread, (jack_client_t* client, + pthread_t *thread, + int priority, + int realtime, // boolean + thread_routine routine, + void *arg), (client, thread, priority, realtime, routine, arg)); +DECL_FUNCTION(int, jack_drop_real_time_scheduling, (pthread_t thread), (thread)); + +DECL_FUNCTION(int, jack_client_stop_thread, (jack_client_t* client, pthread_t thread), (client, thread)); +DECL_FUNCTION(int, jack_client_kill_thread, (jack_client_t* client, pthread_t thread), (client, thread)); #ifndef WIN32 -DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc)); +DECL_VOID_FUNCTION(jack_set_thread_creator, (jack_thread_creator_t jtc), (jtc)); #endif -DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, (jack_intclient_t intclient)); -DECL_FUNCTION(jack_intclient_t, jack_internal_client_handle, (jack_client_t *client), (const char *client_name), (jack_status_t *status)); -DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client), (const char *client_name), (jack_options_t options), (jack_status_t *status), ...)); - -DECL_FUNCTION(jack_status_t, jack_internal_client_unload, (jack_client_t *client), jack_intclient_t intclient)); -DECL_VOID_FUNCTION(jack_free, (void* ptr)); +DECL_FUNCTION(char *, jack_get_internal_client_name, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); +DECL_FUNCTION(jack_intclient_t, jack_internal_client_handle, (jack_client_t *client, const char *client_name, jack_status_t *status), (client, client_name, status)); +/* +DECL_FUNCTION(jack_intclient_t, jack_internal_client_load, (jack_client_t *client, + const char *client_name, + jack_options_t options, + jack_status_t *status + , ...), (client, client_name, options, status, ...)); +*/ +DECL_FUNCTION(jack_status_t, jack_internal_client_unload, (jack_client_t *client, jack_intclient_t intclient), (client, intclient)); +DECL_VOID_FUNCTION(jack_free, (void* ptr), (ptr)); // MIDI -DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer)); -DECL_FUNCTION(int jack_midi_event_get(jack_midi_event_t* event, void* port_buffer, jack_nframes_t event_index); -DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer)); -DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer)); -DECL_FUNCTION(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer), (jack_nframes_t time), (size_t data_size)); -DECL_FUNCTIO(int jack_midi_event_write, (void* port_buffer), (jack_nframes_t time), (const jack_midi_data_t* data), (size_t data_size)); -DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer)); +DECL_FUNCTION(jack_nframes_t, jack_midi_get_event_count, (void* port_buffer), (port_buffer)); +DECL_FUNCTION(int, jack_midi_event_get, (jack_midi_event_t* event, void* port_buffer, jack_nframes_t event_index), (event, port_buffer, event_index)) ; +DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer), (port_buffer)); +DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer), (port_buffer)); +DECL_FUNCTION(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer, jack_nframes_t time, size_t data_size), (port_buffer, time, data_size)); +DECL_FUNCTION(int, jack_midi_event_write, (void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size), (port_buffer, time, data, data_size)); +DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer), (port_buffer)); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 7ac86e5c..a3b2a170 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -94,7 +94,9 @@ static void copyright(FILE* file) static void usage(FILE* file) { fprintf(file, "\n" - "usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n" + "usage: jackdmp [ --no-realtime OR -r ]\n" + " [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n" + " (the two previous arguments are mutually exclusive. The default is --realtime)\n" " [ --name OR -n server-name ]\n" " [ --timeout OR -t client-timeout-in-msecs ]\n" " [ --loopback OR -L loopback-port-number ]\n" @@ -103,15 +105,26 @@ static void usage(FILE* file) #ifdef __linux__ " [ --clocksource OR -c [ c(ycle) | h(pet) | s(ystem) ]\n" #endif - " [ --replace-registry OR -r ]\n" + " [ --replace-registry ]\n" " [ --silent OR -s ]\n" " [ --sync OR -S ]\n" " [ --temporary OR -T ]\n" " [ --version OR -V ]\n" - " -d audio-driver [ ... driver args ... ]\n" - " where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n" - " jackdmp -d driver --help\n" - " to display options for each driver\n\n"); + " -d backend [ ... backend args ... ]\n" +#ifdef __APPLE__ + " Available backends may include: coreaudio, dummy or net.\n\n" +#endif +#ifdef WIN32 + " Available backends may include: portaudio, dummy or net.\n\n" +#endif +#ifdef __linux__ + " Available backends may include: alsa, dummy, freebob, firewire, net, oss or sun.\n\n" +#endif +#if defined(__sun__) || defined(sun) + " Available backends may include: boomer, oss, dummy or net.\n\n" +#endif + " jackdmp -d backend --help\n" + " to display options for each backend\n\n"); } // To put in the control.h interface?? @@ -163,12 +176,14 @@ int main(int argc, char* argv[]) jackctl_driver_t * audio_driver_ctl; jackctl_driver_t * midi_driver_ctl; jackctl_driver_t * loopback_driver_ctl; + int replace_registry = 0; + const char *options = "-d:X:P:uvshVrRL:STFl:t:mn:p:" + "a:" #ifdef __linux__ - const char *options = "-d:X:P:uvrshVRSTFl:t:mn:p:c:a:L:"; -#else - const char *options = "-d:X:P:uvrshVRSTFl:t:mn:p:a:L:"; + "c:" #endif + ; struct option long_options[] = { #ifdef __linux__ @@ -184,7 +199,8 @@ int main(int argc, char* argv[]) { "name", 0, 0, 'n' }, { "unlock", 0, 0, 'u' }, { "realtime", 0, 0, 'R' }, - { "replace-registry", 0, 0, 'r' }, + { "no-realtime", 0, 0, 'r' }, + { "replace-registry", 0, &replace_registry, 0 }, { "loopback", 0, 0, 'L' }, { "realtime-priority", 1, 0, 'P' }, { "timeout", 1, 0, 't' }, @@ -225,8 +241,16 @@ int main(int argc, char* argv[]) fprintf(stderr, "Failed to create server object\n"); return -1; } - + server_parameters = jackctl_server_get_parameters(server_ctl); + + // Default setting + param = jackctl_get_parameter(server_parameters, "realtime"); + if (param != NULL) { + value.b = true; + jackctl_parameter_set_value(param, &value); + } + opterr = 0; while (!seen_audio_driver && (opt = getopt_long(argc, argv, options, @@ -248,7 +272,7 @@ int main(int argc, char* argv[]) jackctl_parameter_set_value(param, &value); } else { usage(stdout); - goto fail_free; + goto fail_free1; } } break; @@ -269,7 +293,7 @@ int main(int argc, char* argv[]) jackctl_parameter_set_value(param, &value); } else { usage(stdout); - goto fail_free; + goto fail_free1; } } break; @@ -336,11 +360,11 @@ int main(int argc, char* argv[]) jackctl_parameter_set_value(param, &value); } break; - + case 'r': - param = jackctl_get_parameter(server_parameters, "replace-registry"); + param = jackctl_get_parameter(server_parameters, "realtime"); if (param != NULL) { - value.b = true; + value.b = false; jackctl_parameter_set_value(param, &value); } break; @@ -379,10 +403,17 @@ int main(int argc, char* argv[]) case 'h': usage(stdout); - goto fail_free; + goto fail_free1; } } - + + // Long option with no letter so treated separately + param = jackctl_get_parameter(server_parameters, "replace-registry"); + if (param != NULL) { + value.b = replace_registry; + jackctl_parameter_set_value(param, &value); + } + if (show_version) { printf( "jackdmp version " VERSION " tmpdir " jack_server_dir @@ -393,14 +424,14 @@ int main(int argc, char* argv[]) if (!seen_audio_driver) { usage(stderr); - goto fail_free; + goto fail_free1; } // Audio driver audio_driver_ctl = jackctl_server_get_driver(server_ctl, audio_driver_name); if (audio_driver_ctl == NULL) { fprintf(stderr, "Unkown driver \"%s\"\n", audio_driver_name); - goto fail_free; + goto fail_free1; } if (optind < argc) { @@ -412,7 +443,7 @@ int main(int argc, char* argv[]) if (audio_driver_nargs == 0) { fprintf(stderr, "No driver specified ... hmm. JACK won't do" " anything when run like this.\n"); - goto fail_free; + goto fail_free1; } audio_driver_args = (char **) malloc(sizeof(char *) * audio_driver_nargs); @@ -423,13 +454,13 @@ int main(int argc, char* argv[]) } if (jackctl_parse_driver_params(audio_driver_ctl, audio_driver_nargs, audio_driver_args)) { - goto fail_free; + goto fail_free1; } // Start server if (!jackctl_server_start(server_ctl, audio_driver_ctl)) { fprintf(stderr, "Failed to start server\n"); - goto fail_free; + goto fail_free1; } // MIDI driver @@ -438,7 +469,7 @@ int main(int argc, char* argv[]) midi_driver_ctl = jackctl_server_get_driver(server_ctl, midi_driver_name); if (midi_driver_ctl == NULL) { fprintf(stderr, "Unkown driver \"%s\"\n", midi_driver_name); - goto fail_free; + goto fail_free2; } jackctl_server_add_slave(server_ctl, midi_driver_ctl); @@ -466,10 +497,18 @@ int main(int argc, char* argv[]) if (!jackctl_server_stop(server_ctl)) fprintf(stderr, "Cannot stop server...\n"); + + jackctl_server_destroy(server_ctl); + notify_server_stop(server_name); + return 0; -fail_free: - +fail_free1: + jackctl_server_destroy(server_ctl); + return -1; + +fail_free2: + jackctl_server_stop(server_ctl); jackctl_server_destroy(server_ctl); notify_server_stop(server_name); - return 1; + return -1; } diff --git a/common/jack/jack.h b/common/jack/jack.h index 5dc6290e..a5dc3aec 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -34,6 +34,25 @@ extern "C" * Note: More documentation can be found in jack/types.h. */ +/************************************************************* + * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function + * added to the JACK API after the 0.116.2 release. + *************************************************************/ + +#ifndef JACK_WEAK_EXPORT +#ifdef __GNUC__ +/* JACK_WEAK_EXPORT needs to be a macro which + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of + the symbol it used with. For this to work full may + require linker arguments in the client as well. +*/ +#define JACK_WEAK_EXPORT __attribute__((weak)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + /** * @defgroup ClientFunctions Creating & manipulating clients * @{ @@ -294,10 +313,41 @@ int jack_set_thread_init_callback (jack_client_t *client, * NOTE: clients do not need to call this. It exists only * to help more complex clients understand what is going * on. It should be called before jack_client_activate(). + * + * NOTE: if a client calls this AND jack_on_info_shutdown(), then + * the event of a client thread shutdown, the callback + * passed to this function will not be called, and the one passed to + * jack_on_info_shutdown() will. */ void jack_on_shutdown (jack_client_t *client, - JackShutdownCallback shutdown_callback, void *arg); + JackShutdownCallback shutdown_callback, void *arg) JACK_WEAK_EXPORT; +/** + * @param client pointer to JACK client structure. + * @param function The jack_info_shutdown function pointer. + * @param arg The arguments for the jack_info_shutdown function. + * + * Register a function (and argument) to be called if and when the + * JACK server shuts down the client thread. The function must + * be written as if it were an asynchonrous POSIX signal + * handler --- use only async-safe functions, and remember that it + * is executed from another thread. A typical function might + * set a flag or write to a pipe so that the rest of the + * application knows that the JACK client thread has shut + * down. + * + * NOTE: clients do not need to call this. It exists only + * to help more complex clients understand what is going + * on. It should be called before jack_client_activate(). + * + * NOTE: if a client calls this AND jack_on_info_shutdown(), then + * the event of a client thread shutdown, the callback + * passed to this function will not be called, and the one passed to + * jack_on_info_shutdown() will. + */ +void jack_on_info_shutdown (jack_client_t *client, + JackInfoShutdownCallback shutdown_callback, void *arg); + /** * Tell the Jack server to call @a process_callback whenever there is * work be done, passing @a arg as the second argument. diff --git a/common/jack/jslist.h b/common/jack/jslist.h index 18773708..3ec0ce92 100644 --- a/common/jack/jslist.h +++ b/common/jack/jslist.h @@ -48,8 +48,10 @@ jack_slist_alloc (void) JSList *new_list; new_list = (JSList*)malloc(sizeof(JSList)); - new_list->data = NULL; - new_list->next = NULL; + if (new_list) { + new_list->data = NULL; + new_list->next = NULL; + } return new_list; } @@ -61,8 +63,10 @@ jack_slist_prepend (JSList* list, void* data) JSList *new_list; new_list = (JSList*)malloc(sizeof(JSList)); - new_list->data = data; - new_list->next = list; + if (new_list) { + new_list->data = data; + new_list->next = list; + } return new_list; } diff --git a/common/jack/types.h b/common/jack/types.h index fa65ce5c..fd71ceac 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -419,7 +419,17 @@ enum JackStatus { /** * Client's protocol version does not match */ - JackVersionError = 0x400 + JackVersionError = 0x400, + + /** + * Backend error + */ + JackBackendError = 0x800, + + /** + * Client zombified failure + */ + JackClientZombie = 0x1000 }; /** @@ -644,4 +654,19 @@ typedef struct { } jack_transport_info_t; +/** + * Prototype for the client supplied function that is called + * whenever jackd is shutdown. Note that after server shutdown, + * the client pointer is *not* deallocated by libjack, + * the application is responsible to properly use jack_client_close() + * to release client ressources. Warning: jack_client_close() cannot be + * safely used inside the shutdown callback and has to be called outside of + * the callback context. + + * @param code a status word, formed by OR-ing together the relevant @ref JackStatus bits. + * @param reason a string describing the shutdown reason (backend failure, server crash... etc...) + * @param arg pointer to a client supplied structure + */ +typedef void (*JackInfoShutdownCallback)(jack_status_t code, const char* reason, void *arg); + #endif /* __jack_types_h__ */ diff --git a/common/memops.c b/common/memops.c index 7112d40e..8ef4f099 100644 --- a/common/memops.c +++ b/common/memops.c @@ -37,6 +37,9 @@ #if defined (__SSE2__) && !defined (__sun__) #include +#ifdef __SSE4_1__ +#include +#endif #endif /* Notes about these *_SCALING values. @@ -285,6 +288,12 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne __m128i y = _mm_cvttps_epi32(clipped); __m128i shifted = _mm_slli_epi32(y, 8); +#ifdef __SSE4_1__ + *(int32_t*)dst = _mm_extract_epi32(shifted, 0); + *(int32_t*)(dst+dst_skip) = _mm_extract_epi32(shifted, 1); + *(int32_t*)(dst+2*dst_skip) = _mm_extract_epi32(shifted, 2); + *(int32_t*)(dst+3*dst_skip) = _mm_extract_epi32(shifted, 3); +#else __m128i shuffled1 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(0, 3, 2, 1)); __m128i shuffled2 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(1, 0, 3, 2)); __m128i shuffled3 = _mm_shuffle_epi32(shifted, _MM_SHUFFLE(2, 1, 0, 3)); @@ -294,6 +303,7 @@ void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigne _mm_store_ss((float*)(dst+dst_skip), (__m128)shuffled1); _mm_store_ss((float*)(dst+2*dst_skip), (__m128)shuffled2); _mm_store_ss((float*)(dst+3*dst_skip), (__m128)shuffled3); +#endif dst += 4*dst_skip; src+= 4; @@ -421,6 +431,12 @@ void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned l __m128 samples = _mm_loadu_ps(src); __m128i converted = float_24_sse(samples); +#ifdef __SSE4_1__ + z[0] = _mm_extract_epi32(converted, 0); + z[1] = _mm_extract_epi32(converted, 1); + z[2] = _mm_extract_epi32(converted, 2); + z[3] = _mm_extract_epi32(converted, 3); +#else __m128i shuffled1 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(0, 3, 2, 1)); __m128i shuffled2 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(1, 0, 3, 2)); __m128i shuffled3 = _mm_shuffle_epi32(converted, _MM_SHUFFLE(2, 1, 0, 3)); @@ -431,13 +447,11 @@ void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned l _mm_store_ss((float*)z+3, (__m128)shuffled3); for (i = 0; i != 4; ++i) { -#if __BYTE_ORDER == __LITTLE_ENDIAN memcpy (dst, z+i, 3); -#elif __BYTE_ORDER == __BIG_ENDIAN - memcpy (dst, (float*)((char *)&z + 1)+i, 3); -#endif dst += dst_skip; } +#endif + nsamples -= 4; src += 4; } @@ -481,7 +495,7 @@ void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned x <<= 8; x |= (unsigned char)(src[0]); /* correct sign bit and the rest of the top byte */ - if (src[0] & 0x80) { + if (src[2] & 0x80) { x |= 0xff << 24; } #endif @@ -500,17 +514,10 @@ void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned l while (nsamples >= 4) { int x0, x1, x2, x3; -#if __BYTE_ORDER == __LITTLE_ENDIAN memcpy((char*)&x0 + 1, src, 3); memcpy((char*)&x1 + 1, src+src_skip, 3); memcpy((char*)&x2 + 1, src+2*src_skip, 3); memcpy((char*)&x3 + 1, src+3*src_skip, 3); -#elif __BYTE_ORDER == __BIG_ENDIAN - memcpy(&x0, src, 3); - memcpy(&x1, src+src_skip, 3); - memcpy(&x2, src+2*src_skip, 3); - memcpy(&x3, src+3*src_skip, 3); -#endif src += 4 * src_skip; const __m128i block_i = _mm_set_epi32(x3, x2, x1, x0); diff --git a/common/netjack.c b/common/netjack.c new file mode 100644 index 00000000..eb5f36b7 --- /dev/null +++ b/common/netjack.c @@ -0,0 +1,746 @@ + +/* -*- mode: c; c-file-style: "linux"; -*- */ +/* +NetJack Abstraction. + +Copyright (C) 2008 Pieter Palmers +Copyright (C) 2006 Torben Hohn +Copyright (C) 2003 Robert Ham +Copyright (C) 2001 Paul Davis + +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. + +$Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ +*/ + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "jack/jslist.h" + +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif + +#include "netjack.h" + +//#include "config.h" + +#if HAVE_SAMPLERATE +#include +#endif + +#if HAVE_CELT +#include +#endif + +#include "netjack.h" +#include "netjack_packet.h" + +// JACK2 +#include "jack/control.h" + +#define MIN(x,y) ((x)<(y) ? (x) : (y)) + +static int sync_state = 1; +static jack_transport_state_t last_transport_state; + +static int +net_driver_sync_cb(jack_transport_state_t state, jack_position_t *pos, void *data) +{ + int retval = sync_state; + + if (state == JackTransportStarting && last_transport_state != JackTransportStarting) { + retval = 0; + } +// if (state == JackTransportStarting) +// jack_info("Starting sync_state = %d", sync_state); + last_transport_state = state; + return retval; +} + +int netjack_wait( netjack_driver_state_t *netj ) +{ + int we_have_the_expected_frame = 0; + jack_nframes_t next_frame_avail; + jack_time_t packet_recv_time_stamp; + jacknet_packet_header *pkthdr; + + if( !netj->next_deadline_valid ) { + netj->next_deadline = jack_get_time() + netj->deadline_offset; + netj->next_deadline_valid = 1; + } + + // Increment expected frame here. + + if( netj->expected_framecnt_valid ) { + netj->expected_framecnt += 1; + } else { + // starting up.... lets look into the packetcache, and fetch the highest packet. + packet_cache_drain_socket( global_packcache, netj->sockfd ); + if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail ) ) { + netj->expected_framecnt = next_frame_avail; + netj->expected_framecnt_valid = 1; + } else { + // no packets there... start normally. + netj->expected_framecnt = 0; + netj->expected_framecnt_valid = 1; + } + + } + + //jack_log( "expect %d", netj->expected_framecnt ); + // Now check if required packet is already in the cache. + // then poll (have deadline calculated) + // then drain socket, rinse and repeat. + while(1) { + if( packet_cache_get_next_available_framecnt( global_packcache, netj->expected_framecnt, &next_frame_avail) ) { + if( next_frame_avail == netj->expected_framecnt ) { + we_have_the_expected_frame = 1; + if( !netj->always_deadline ) + break; + } + } + if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) { + break; + } + + packet_cache_drain_socket( global_packcache, netj->sockfd ); + } + + // check if we know who to send our packets too. + if (!netj->srcaddress_valid) + if( global_packcache->master_address_valid ) { + memcpy (&(netj->syncsource_address), &(global_packcache->master_address), sizeof( struct sockaddr_in ) ); + netj->srcaddress_valid = 1; + } + + // XXX: switching mode unconditionally is stupid. + // if we were running free perhaps we like to behave differently + // ie. fastforward one packet etc. + // well... this is the first packet we see. hmm.... dunno ;S + // it works... so... + netj->running_free = 0; + + //if( !we_have_the_expected_frame ) + // jack_error( "netxrun... %d", netj->expected_framecnt ); + + if( we_have_the_expected_frame ) { + + jack_time_t now = jack_get_time(); + if( now < netj->next_deadline ) + netj->time_to_deadline = netj->next_deadline - now; + else + netj->time_to_deadline = 0; + + packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + netj->deadline_goodness = (int)pkthdr->sync_state; + netj->packet_data_valid = 1; + + int want_deadline; + if( netj->jitter_val != 0 ) + want_deadline = netj->jitter_val; + else if( netj->latency < 4 ) + want_deadline = -netj->period_usecs/2; + else + want_deadline = (netj->period_usecs/4+10*(int)netj->period_usecs*netj->latency/100); + + if( netj->deadline_goodness != MASTER_FREEWHEELS ) { + if( netj->deadline_goodness < want_deadline ) { + netj->deadline_offset -= netj->period_usecs/100; + //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); + } + if( netj->deadline_goodness > want_deadline ) { + netj->deadline_offset += netj->period_usecs/100; + //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); + } + } + if( netj->deadline_offset < (netj->period_usecs*70/100) ) { + jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); + netj->deadline_offset = (netj->period_usecs*90/100); + } + + netj->next_deadline = jack_get_time() + netj->deadline_offset; + } else { + netj->time_to_deadline = 0; + netj->next_deadline = jack_get_time() + netj->deadline_offset; + // bah... the packet is not there. + // either + // - it got lost. + // - its late + // - sync source is not sending anymore. + + // lets check if we have the next packets, we will just run a cycle without data. + // in that case. + + if( packet_cache_get_next_available_framecnt( global_packcache, netj->expected_framecnt, &next_frame_avail) ) + { + jack_nframes_t offset = next_frame_avail - netj->expected_framecnt; + + //XXX: hmm... i need to remember why resync_threshold wasnt right. + //if( offset < netj->resync_threshold ) + if( offset < 10 ) { + // ok. dont do nothing. we will run without data. + // this seems to be one or 2 lost packets. + // + // this can also be reordered packet jitter. + // (maybe this is not happening in real live) + // but it happens in netem. + + netj->packet_data_valid = 0; + + // I also found this happening, when the packet queue, is too full. + // but wtf ? use a smaller latency. this link can handle that ;S + if( packet_cache_get_fill( global_packcache, netj->expected_framecnt ) > 80.0 ) + netj->next_deadline -= netj->period_usecs/2; + + + } else { + // the diff is too high. but we have a packet in the future. + // lets resync. + netj->expected_framecnt = next_frame_avail; + packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + //netj->deadline_goodness = 0; + netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset; + netj->next_deadline_valid = 0; + netj->packet_data_valid = 1; + } + + } else { + // no packets in buffer. + netj->packet_data_valid = 0; + + //printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets ); + if( netj->num_lost_packets < 5 ) { + // ok. No Packet in queue. The packet was either lost, + // or we are running too fast. + // + // Adjusting the deadline unconditionally resulted in + // too many xruns on master. + // But we need to adjust for the case we are running too fast. + // So lets check if the last packet is there now. + // + // It would not be in the queue anymore, if it had been + // retrieved. This might break for redundancy, but + // i will make the packet cache drop redundant packets, + // that have already been retreived. + // + if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail) ) { + if( next_frame_avail == (netj->expected_framecnt - 1) ) { + // Ok. the last packet is there now. + // and it had not been retrieved. + // + // TODO: We are still dropping 2 packets. + // perhaps we can adjust the deadline + // when (num_packets lost == 0) + + // This might still be too much. + netj->next_deadline += netj->period_usecs; + } + } + } else if( (netj->num_lost_packets <= 100) ) { + // lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast. + netj->next_deadline += netj->period_usecs*netj->latency/8; + } else { + + // But now we can check for any new frame available. + // + if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail) ) { + netj->expected_framecnt = next_frame_avail; + packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + netj->deadline_goodness = pkthdr->sync_state; + netj->next_deadline_valid = 0; + netj->packet_data_valid = 1; + netj->running_free = 0; + jack_info( "resync after freerun... %d", netj->expected_framecnt ); + } else { + if( netj->num_lost_packets == 101 ) { + jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt ); + } + + netj->running_free = 1; + + // when we really dont see packets. + // reset source address. and open possibility for new master. + // maybe dsl reconnect. Also restart of netsource without fix + // reply address changes port. + if (netj->num_lost_packets > 200 ) { + netj->srcaddress_valid = 0; + packet_cache_reset_master_address( global_packcache ); + } + } + } + } + } + + int retval = 0; + + if( !netj->packet_data_valid ) { + netj->num_lost_packets += 1; + if( netj->num_lost_packets == 1 ) + retval = netj->period_usecs; + } else { + if( (netj->num_lost_packets>1) && !netj->running_free ) + retval = (netj->num_lost_packets-1) * netj->period_usecs; + + netj->num_lost_packets = 0; + } + + return retval; +} + +void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ) +{ + int tx_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up + sizeof(jacknet_packet_header); + unsigned int *packet_buf, *packet_bufX; + + packet_buf = alloca( tx_size); + jacknet_packet_header *tx_pkthdr = (jacknet_packet_header *)packet_buf; + jacknet_packet_header *rx_pkthdr = (jacknet_packet_header *)netj->rx_buf; + + //framecnt = rx_pkthdr->framecnt; + + netj->reply_port = rx_pkthdr->reply_port; + + // offset packet_bufX by the packetheader. + packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); + + tx_pkthdr->sync_state = syncstate; + tx_pkthdr->framecnt = netj->expected_framecnt; + + // memset 0 the payload. + int payload_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up; + memset(packet_bufX, 0, payload_size); + + packet_header_hton(tx_pkthdr); + if (netj->srcaddress_valid) + { + int r; + if (netj->reply_port) + netj->syncsource_address.sin_port = htons(netj->reply_port); + + for( r=0; rredundancy; r++ ) + netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size, + 0, (struct sockaddr*)&(netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu); + } +} + + +void netjack_attach( netjack_driver_state_t *netj ) +{ + //puts ("net_driver_attach"); + jack_port_t * port; + char buf[32]; + unsigned int chn; + int port_flags; + + + if (netj->handle_transport_sync) + jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL); + + port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + + for (chn = 0; chn < netj->capture_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); + + port = jack_port_register (netj->client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + if (!port) { + jack_error ("NET: cannot register port for %s", buf); + break; + } + + netj->capture_ports = + jack_slist_append (netj->capture_ports, port); + + if( netj->bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + celt_int32 lookahead; + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); +#else + celt_int32_t lookahead; + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( celt_mode ) ); +#endif + celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj->codec_latency = 2*lookahead; +#endif + } else { +#if HAVE_SAMPLERATE + netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL)); +#endif + } + } + for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1); + + port = jack_port_register (netj->client, buf, + JACK_DEFAULT_MIDI_TYPE, + port_flags, 0); + if (!port) { + jack_error ("NET: cannot register port for %s", buf); + break; + } + + netj->capture_ports = + jack_slist_append (netj->capture_ports, port); + } + + port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; + + for (chn = 0; chn < netj->playback_channels_audio; chn++) { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); + + port = jack_port_register (netj->client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) { + jack_error ("NET: cannot register port for %s", buf); + break; + } + + netj->playback_ports = + jack_slist_append (netj->playback_ports, port); + if( netj->bitdepth == CELT_MODE ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL)); +#endif + } + } + for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); + + port = jack_port_register (netj->client, buf, + JACK_DEFAULT_MIDI_TYPE, + port_flags, 0); + + if (!port) { + jack_error ("NET: cannot register port for %s", buf); + break; + } + + netj->playback_ports = + jack_slist_append (netj->playback_ports, port); + } + + jack_activate (netj->client); +} + + +void netjack_detach( netjack_driver_state_t *netj ) +{ + JSList * node; + + + for (node = netj->capture_ports; node; node = jack_slist_next (node)) + jack_port_unregister (netj->client, + ((jack_port_t *) node->data)); + + jack_slist_free (netj->capture_ports); + netj->capture_ports = NULL; + + for (node = netj->playback_ports; node; node = jack_slist_next (node)) + jack_port_unregister (netj->client, + ((jack_port_t *) node->data)); + + jack_slist_free (netj->playback_ports); + netj->playback_ports = NULL; +} + + +netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, + jack_client_t * client, + const char *name, + unsigned int capture_ports, + unsigned int playback_ports, + unsigned int capture_ports_midi, + unsigned int playback_ports_midi, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned int listen_port, + unsigned int transport_sync, + unsigned int resample_factor, + unsigned int resample_factor_up, + unsigned int bitdepth, + unsigned int use_autoconfig, + unsigned int latency, + unsigned int redundancy, + int dont_htonl_floats, + int always_deadline, + int jitter_val ) +{ + + // Fill in netj values. + // might be subject to autoconfig... + // so dont calculate anything with them... + + + netj->sample_rate = sample_rate; + netj->period_size = period_size; + netj->dont_htonl_floats = dont_htonl_floats; + + netj->listen_port = listen_port; + + netj->capture_channels = capture_ports + capture_ports_midi; + netj->capture_channels_audio = capture_ports; + netj->capture_channels_midi = capture_ports_midi; + netj->capture_ports = NULL; + netj->playback_channels = playback_ports + playback_ports_midi; + netj->playback_channels_audio = playback_ports; + netj->playback_channels_midi = playback_ports_midi; + netj->playback_ports = NULL; + netj->codec_latency = 0; + + netj->handle_transport_sync = transport_sync; + netj->mtu = 1400; + netj->latency = latency; + netj->redundancy = redundancy; + netj->use_autoconfig = use_autoconfig; + netj->always_deadline = always_deadline; + + + netj->client = client; + + + if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE)) + { + jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth); + return NULL; + } + netj->bitdepth = bitdepth; + + + if (resample_factor_up == 0) + resample_factor_up = resample_factor; + + netj->resample_factor = resample_factor; + netj->resample_factor_up = resample_factor_up; + + + return netj; +} + +void netjack_release( netjack_driver_state_t *netj ) +{ + close( netj->sockfd ); + close( netj->outsockfd ); + + packet_cache_free( global_packcache ); + global_packcache = NULL; +} + +int +netjack_startup( netjack_driver_state_t *netj ) +{ + int first_pack_len; + struct sockaddr_in address; + // Now open the socket, and wait for the first packet to arrive... + netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0); +#ifdef WIN32 + if (netj->sockfd == INVALID_SOCKET) +#else + if (netj->sockfd == -1) +#endif + { + jack_info ("socket error"); + return -1; + } + address.sin_family = AF_INET; + address.sin_port = htons(netj->listen_port); + address.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0) + { + jack_info("bind error"); + return -1; + } + + netj->outsockfd = socket (AF_INET, SOCK_DGRAM, 0); +#ifdef WIN32 + if (netj->outsockfd == INVALID_SOCKET) +#else + if (netj->outsockfd == -1) +#endif + { + jack_info ("socket error"); + return -1; + } + netj->srcaddress_valid = 0; + if (netj->use_autoconfig) + { + jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header)); +#ifdef WIN32 + int address_size = sizeof( struct sockaddr_in ); +#else + socklen_t address_size = sizeof (struct sockaddr_in); +#endif + //jack_info ("Waiting for an incoming packet !!!"); + //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!"); + + while(1) { + first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); +#ifdef WIN32 + if( first_pack_len == -1 ) { + first_pack_len = sizeof(jacknet_packet_header); + break; + } +#else + if (first_pack_len == sizeof (jacknet_packet_header)) + break; +#endif + } + netj->srcaddress_valid = 1; + + if (first_pack_len == sizeof (jacknet_packet_header)) + { + packet_header_ntoh (first_packet); + + jack_info ("AutoConfig Override !!!"); + if (netj->sample_rate != first_packet->sample_rate) + { + jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate); + netj->sample_rate = first_packet->sample_rate; + } + + if (netj->period_size != first_packet->period_size) + { + jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size); + netj->period_size = first_packet->period_size; + } + if (netj->capture_channels_audio != first_packet->capture_channels_audio) + { + jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio); + netj->capture_channels_audio = first_packet->capture_channels_audio; + } + if (netj->capture_channels_midi != first_packet->capture_channels_midi) + { + jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi); + netj->capture_channels_midi = first_packet->capture_channels_midi; + } + if (netj->playback_channels_audio != first_packet->playback_channels_audio) + { + jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio); + netj->playback_channels_audio = first_packet->playback_channels_audio; + } + if (netj->playback_channels_midi != first_packet->playback_channels_midi) + { + jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi); + netj->playback_channels_midi = first_packet->playback_channels_midi; + } + + netj->mtu = first_packet->mtu; + jack_info ("MTU is set to %d bytes", first_packet->mtu); + netj->latency = first_packet->latency; + } + } + netj->capture_channels = netj->capture_channels_audio + netj->capture_channels_midi; + netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi; + + if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) { + jack_error( "autoconfig requests more than 100MB packet cache... bailing out" ); + exit(1); + } + + if( netj->playback_channels > 1000 ) { + jack_error( "autoconfig requests more than 1000 playback channels... bailing out" ); + exit(1); + } + + + if( netj->mtu < (2*sizeof( jacknet_packet_header )) ) { + jack_error( "bullshit mtu requested by autoconfig" ); + exit(1); + } + + if( netj->sample_rate == 0 ) { + jack_error( "sample_rate 0 requested by autoconfig" ); + exit(1); + } + + // After possible Autoconfig: do all calculations... + netj->period_usecs = + (jack_time_t) floor ((((float) netj->period_size) / (float)netj->sample_rate) + * 1000000.0f); + + if( netj->latency == 0 ) + netj->deadline_offset = 50*netj->period_usecs; + else + netj->deadline_offset = netj->period_usecs + 10*netj->latency*netj->period_usecs/100; + + if( netj->bitdepth == CELT_MODE ) { + // celt mode. + // TODO: this is a hack. But i dont want to change the packet header. + netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); + netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); + + netj->net_period_down = netj->resample_factor; + netj->net_period_up = netj->resample_factor_up; + } else { + netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor; + netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up; + } + + netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth); + netj->pkt_buf = malloc (netj->rx_bufsize); + global_packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu); + + netj->expected_framecnt_valid = 0; + netj->num_lost_packets = 0; + netj->next_deadline_valid = 0; + netj->deadline_goodness = 0; + netj->time_to_deadline = 0; + + // Special handling for latency=0 + if( netj->latency == 0 ) + netj->resync_threshold = 0; + else + netj->resync_threshold = MIN( 15, netj->latency-1 ); + + netj->running_free = 0; + + return 0; +} diff --git a/common/netjack.h b/common/netjack.h new file mode 100644 index 00000000..91c81be5 --- /dev/null +++ b/common/netjack.h @@ -0,0 +1,147 @@ + +/* + Copyright (C) 2003 Robert Ham + Copyright (C) 2005 Torben Hohn + + 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 __NETJACK_H__ +#define __NETJACK_H__ + +#include + +#include +//#include +#include +#include + +#include "jack/jslist.h" + +//#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct _netjack_driver_state netjack_driver_state_t; + +struct _netjack_driver_state { + jack_nframes_t net_period_up; + jack_nframes_t net_period_down; + + jack_nframes_t sample_rate; + jack_nframes_t bitdepth; + jack_nframes_t period_size; + jack_time_t period_usecs; + int dont_htonl_floats; + int always_deadline; + + jack_nframes_t codec_latency; + + unsigned int listen_port; + + unsigned int capture_channels; + unsigned int playback_channels; + unsigned int capture_channels_audio; + unsigned int playback_channels_audio; + unsigned int capture_channels_midi; + unsigned int playback_channels_midi; + + JSList *capture_ports; + JSList *playback_ports; + JSList *playback_srcs; + JSList *capture_srcs; + + jack_client_t *client; + +#ifdef WIN32 + SOCKET sockfd; + SOCKET outsockfd; +#else + int sockfd; + int outsockfd; +#endif + + struct sockaddr_in syncsource_address; + + int reply_port; + int srcaddress_valid; + + int sync_state; + unsigned int handle_transport_sync; + + unsigned int *rx_buf; + unsigned int *pkt_buf; + unsigned int rx_bufsize; + //unsigned int tx_bufsize; + unsigned int mtu; + unsigned int latency; + unsigned int redundancy; + + jack_nframes_t expected_framecnt; + int expected_framecnt_valid; + unsigned int num_lost_packets; + jack_time_t next_deadline; + jack_time_t deadline_offset; + int next_deadline_valid; + int packet_data_valid; + int resync_threshold; + int running_free; + int deadline_goodness; + jack_time_t time_to_deadline; + unsigned int use_autoconfig; + unsigned int resample_factor; + unsigned int resample_factor_up; + int jitter_val; +}; + +int netjack_wait( netjack_driver_state_t *netj ); +void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ); +void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ; +void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate ); +void netjack_attach( netjack_driver_state_t *netj ); +void netjack_detach( netjack_driver_state_t *netj ); + +netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, + jack_client_t * client, + const char *name, + unsigned int capture_ports, + unsigned int playback_ports, + unsigned int capture_ports_midi, + unsigned int playback_ports_midi, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned int listen_port, + unsigned int transport_sync, + unsigned int resample_factor, + unsigned int resample_factor_up, + unsigned int bitdepth, + unsigned int use_autoconfig, + unsigned int latency, + unsigned int redundancy, + int dont_htonl_floats, + int always_deadline, + int jitter_val ); + +void netjack_release( netjack_driver_state_t *netj ); +int netjack_startup( netjack_driver_state_t *netj ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/common/netjack_packet.c b/common/netjack_packet.c new file mode 100644 index 00000000..4edbb2a3 --- /dev/null +++ b/common/netjack_packet.c @@ -0,0 +1,1520 @@ + +/* + * NetJack - Packet Handling functions + * + * used by the driver and the jacknet_client + * + * Copyright (C) 2008 Marc-Olivier Barre + * Copyright (C) 2008 Pieter Palmers + * Copyright (C) 2006 Torben Hohn + * + * 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. + * + * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $ + * + */ + +//#include "config.h" + +#ifdef __APPLE__ +#define _DARWIN_C_SOURCE +#endif + +#if HAVE_PPOLL +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#endif + +#include +#include + +#if HAVE_SAMPLERATE +#include +#endif + +#if HAVE_CELT +#include +#endif + +#include "netjack_packet.h" + +// JACK2 specific. +#include "jack/control.h" + +#ifdef NO_JACK_ERROR +#define jack_error printf +#endif + +int fraggo = 0; + +packet_cache *global_packcache = NULL; + +void +packet_header_hton (jacknet_packet_header *pkthdr) +{ + pkthdr->capture_channels_audio = htonl(pkthdr->capture_channels_audio); + pkthdr->playback_channels_audio = htonl(pkthdr->playback_channels_audio); + pkthdr->capture_channels_midi = htonl(pkthdr->capture_channels_midi); + pkthdr->playback_channels_midi = htonl(pkthdr->playback_channels_midi); + pkthdr->period_size = htonl(pkthdr->period_size); + pkthdr->sample_rate = htonl(pkthdr->sample_rate); + pkthdr->sync_state = htonl(pkthdr->sync_state); + pkthdr->transport_frame = htonl(pkthdr->transport_frame); + pkthdr->transport_state = htonl(pkthdr->transport_state); + pkthdr->framecnt = htonl(pkthdr->framecnt); + pkthdr->latency = htonl(pkthdr->latency); + pkthdr->reply_port = htonl(pkthdr->reply_port); + pkthdr->mtu = htonl(pkthdr->mtu); + pkthdr->fragment_nr = htonl(pkthdr->fragment_nr); +} + +void +packet_header_ntoh (jacknet_packet_header *pkthdr) +{ + pkthdr->capture_channels_audio = ntohl(pkthdr->capture_channels_audio); + pkthdr->playback_channels_audio = ntohl(pkthdr->playback_channels_audio); + pkthdr->capture_channels_midi = ntohl(pkthdr->capture_channels_midi); + pkthdr->playback_channels_midi = ntohl(pkthdr->playback_channels_midi); + pkthdr->period_size = ntohl(pkthdr->period_size); + pkthdr->sample_rate = ntohl(pkthdr->sample_rate); + pkthdr->sync_state = ntohl(pkthdr->sync_state); + pkthdr->transport_frame = ntohl(pkthdr->transport_frame); + pkthdr->transport_state = ntohl(pkthdr->transport_state); + pkthdr->framecnt = ntohl(pkthdr->framecnt); + pkthdr->latency = ntohl(pkthdr->latency); + pkthdr->reply_port = ntohl(pkthdr->reply_port); + pkthdr->mtu = ntohl(pkthdr->mtu); + pkthdr->fragment_nr = ntohl(pkthdr->fragment_nr); +} + +int get_sample_size (int bitdepth) +{ + if (bitdepth == 8) + return sizeof (int8_t); + if (bitdepth == 16) + return sizeof (int16_t); + //JN: why? is this for buffer sizes before or after encoding? + //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? + if( bitdepth == CELT_MODE ) + return sizeof( unsigned char ); + return sizeof (int32_t); +} + +int jack_port_is_audio(const char *porttype) +{ + return (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0); +} + +int jack_port_is_midi(const char *porttype) +{ + return (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0); +} + + +// fragment management functions. + +packet_cache +*packet_cache_new (int num_packets, int pkt_size, int mtu) +{ + int fragment_payload_size = mtu - sizeof (jacknet_packet_header); + int i, fragment_number; + + if( pkt_size == sizeof(jacknet_packet_header) ) + fragment_number = 1; + else + fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1; + + packet_cache *pcache = malloc (sizeof (packet_cache)); + if (pcache == NULL) + { + jack_error ("could not allocate packet cache (1)"); + return NULL; + } + + pcache->size = num_packets; + pcache->packets = malloc (sizeof (cache_packet) * num_packets); + pcache->master_address_valid = 0; + pcache->last_framecnt_retreived = 0; + pcache->last_framecnt_retreived_valid = 0; + + if (pcache->packets == NULL) + { + jack_error ("could not allocate packet cache (2)"); + return NULL; + } + + for (i = 0; i < num_packets; i++) + { + pcache->packets[i].valid = 0; + pcache->packets[i].num_fragments = fragment_number; + pcache->packets[i].packet_size = pkt_size; + pcache->packets[i].mtu = mtu; + pcache->packets[i].framecnt = 0; + pcache->packets[i].fragment_array = malloc (sizeof (char) * fragment_number); + pcache->packets[i].packet_buf = malloc (pkt_size); + if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL)) + { + jack_error ("could not allocate packet cache (3)"); + return NULL; + } + } + pcache->mtu = mtu; + + return pcache; +} + +void +packet_cache_free (packet_cache *pcache) +{ + int i; + if( pcache == NULL ) + return; + + for (i = 0; i < pcache->size; i++) + { + free (pcache->packets[i].fragment_array); + free (pcache->packets[i].packet_buf); + } + + free (pcache->packets); + free (pcache); +} + +cache_packet +*packet_cache_get_packet (packet_cache *pcache, jack_nframes_t framecnt) +{ + int i; + cache_packet *retval; + + for (i = 0; i < pcache->size; i++) + { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) + return &(pcache->packets[i]); + } + + // The Packet is not in the packet cache. + // find a free packet. + + retval = packet_cache_get_free_packet (pcache); + if (retval != NULL) + { + cache_packet_set_framecnt (retval, framecnt); + return retval; + } + + // No Free Packet available + // Get The Oldest packet and reset it. + + retval = packet_cache_get_oldest_packet (pcache); + //printf( "Dropping %d from Cache :S\n", retval->framecnt ); + cache_packet_reset (retval); + cache_packet_set_framecnt (retval, framecnt); + + return retval; +} + +// TODO: fix wrapping case... need to pass +// current expected frame here. +// +// or just save framecount into packet_cache. + +cache_packet +*packet_cache_get_oldest_packet (packet_cache *pcache) +{ + jack_nframes_t minimal_frame = JACK_MAX_FRAMES; + cache_packet *retval = &(pcache->packets[0]); + int i; + + for (i = 0; i < pcache->size; i++) + { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame)) + { + minimal_frame = pcache->packets[i].framecnt; + retval = &(pcache->packets[i]); + } + } + + return retval; +} + +cache_packet +*packet_cache_get_free_packet (packet_cache *pcache) +{ + int i; + + for (i = 0; i < pcache->size; i++) + { + if (pcache->packets[i].valid == 0) + return &(pcache->packets[i]); + } + + return NULL; +} + +void +cache_packet_reset (cache_packet *pack) +{ + int i; + pack->valid = 0; + + // XXX: i dont think this is necessary here... + // fragement array is cleared in _set_framecnt() + + for (i = 0; i < pack->num_fragments; i++) + pack->fragment_array[i] = 0; +} + +void +cache_packet_set_framecnt (cache_packet *pack, jack_nframes_t framecnt) +{ + int i; + + pack->framecnt = framecnt; + + for (i = 0; i < pack->num_fragments; i++) + pack->fragment_array[i] = 0; + + pack->valid = 1; +} + +void +cache_packet_add_fragment (cache_packet *pack, char *packet_buf, int rcv_len) +{ + jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf; + int fragment_payload_size = pack->mtu - sizeof (jacknet_packet_header); + char *packet_bufX = pack->packet_buf + sizeof (jacknet_packet_header); + char *dataX = packet_buf + sizeof (jacknet_packet_header); + + jack_nframes_t fragment_nr = ntohl (pkthdr->fragment_nr); + jack_nframes_t framecnt = ntohl (pkthdr->framecnt); + + if (framecnt != pack->framecnt) + { + jack_error ("errror. framecnts dont match"); + return; + } + + + if (fragment_nr == 0) + { + memcpy (pack->packet_buf, packet_buf, rcv_len); + pack->fragment_array[0] = 1; + + return; + } + + if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0)) + { + if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header))) + { + memcpy (packet_bufX + fragment_nr * fragment_payload_size, dataX, rcv_len - sizeof (jacknet_packet_header)); + pack->fragment_array[fragment_nr] = 1; + } + else + jack_error ("too long packet received..."); + } +} + +int +cache_packet_is_complete (cache_packet *pack) +{ + int i; + for (i = 0; i < pack->num_fragments; i++) + if (pack->fragment_array[i] == 0) + return 0; + + return 1; +} + +#ifndef WIN32 +// new poll using nanoseconds resolution and +// not waiting forever. +int +netjack_poll_deadline (int sockfd, jack_time_t deadline) +{ + struct pollfd fds; + int poll_err = 0; +#if HAVE_PPOLL + struct timespec timeout_spec = { 0, 0 }; +#else + int timeout; +#endif + + + jack_time_t now = jack_get_time(); + if( now >= deadline ) + return 0; + + if( (deadline-now) >= 1000000 ) { + jack_error( "deadline more than 1 second in the future, trimming it." ); + deadline = now+500000; + } +#if HAVE_PPOLL + timeout_spec.tv_nsec = (deadline - now) * 1000; +#else + timeout = (deadline - now + 500) / 1000; +#endif + + + fds.fd = sockfd; + fds.events = POLLIN; + +#if HAVE_PPOLL + poll_err = ppoll (&fds, 1, &timeout_spec, NULL); +#else + poll_err = poll (&fds, 1, timeout); +#endif + + if (poll_err == -1) + { + switch (errno) + { + case EBADF: + jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); + break; + case EFAULT: + jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); + break; + case EINTR: + jack_error ("Error %d: A signal occurred before any requested event", errno); + break; + case EINVAL: + jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); + break; + case ENOMEM: + jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); + break; + } + } + return poll_err; +} + +int +netjack_poll (int sockfd, int timeout) +{ + struct pollfd fds; + int i, poll_err = 0; + sigset_t sigmask, rsigmask; + struct sigaction action; + + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGINT); + sigaddset(&sigmask, SIGQUIT); + sigaddset(&sigmask, SIGPIPE); + sigaddset(&sigmask, SIGTERM); + sigaddset(&sigmask, SIGUSR1); + sigaddset(&sigmask, SIGUSR2); + + action.sa_handler = SIG_DFL; + action.sa_mask = sigmask; + action.sa_flags = SA_RESTART; + + for (i = 1; i < NSIG; i++) + if (sigismember (&sigmask, i)) + sigaction (i, &action, 0); + + fds.fd = sockfd; + fds.events = POLLIN; + + sigprocmask(SIG_UNBLOCK, &sigmask, &rsigmask); + while (poll_err == 0) + { + poll_err = poll (&fds, 1, timeout); + } + sigprocmask(SIG_SETMASK, &rsigmask, NULL); + + if (poll_err == -1) + { + switch (errno) + { + case EBADF: + jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); + break; + case EFAULT: + jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); + break; + case EINTR: + jack_error ("Error %d: A signal occurred before any requested event", errno); + break; + case EINVAL: + jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); + break; + case ENOMEM: + jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); + break; + } + return 0; + } + return 1; +} + +#else +int +netjack_poll (int sockfd, int timeout) +{ + jack_error( "netjack_poll not implemented" ); + return 0; +} +int +netjack_poll_deadline (int sockfd, jack_time_t deadline) +{ + fd_set fds; + FD_ZERO( &fds ); + FD_SET( sockfd, &fds ); + + struct timeval timeout; + while( 1 ) { + jack_time_t now = jack_get_time(); + if( now >= deadline ) + return 0; + + int timeout_usecs = (deadline - now); + //jack_error( "timeout = %d", timeout_usecs ); + timeout.tv_sec = 0; + timeout.tv_usec = (timeout_usecs < 500) ? 500 : timeout_usecs; + timeout.tv_usec = (timeout_usecs > 1000000) ? 500000 : timeout_usecs; + + int poll_err = select (0, &fds, NULL, NULL, &timeout); + if( poll_err != 0 ) + return poll_err; + } + + return 0; +} +#endif +// This now reads all a socket has into the cache. +// replacing netjack_recv functions. + +void +packet_cache_drain_socket( packet_cache *pcache, int sockfd ) +{ + char *rx_packet = alloca (pcache->mtu); + jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; + int rcv_len; + jack_nframes_t framecnt; + cache_packet *cpack; + struct sockaddr_in sender_address; +#ifdef WIN32 + size_t senderlen = sizeof( struct sockaddr_in ); + u_long parm = 1; + ioctlsocket( sockfd, FIONBIO, &parm ); +#else + socklen_t senderlen = sizeof( struct sockaddr_in ); +#endif + while (1) + { +#ifdef WIN32 + rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0, + (struct sockaddr*) &sender_address, &senderlen); +#else + rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, MSG_DONTWAIT, + (struct sockaddr*) &sender_address, &senderlen); +#endif + if (rcv_len < 0) + return; + + if (pcache->master_address_valid) { + // Verify its from our master. + if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0) + continue; + } else { + // Setup this one as master + //printf( "setup master...\n" ); + memcpy ( &(pcache->master_address), &sender_address, senderlen ); + pcache->master_address_valid = 1; + } + + framecnt = ntohl (pkthdr->framecnt); + if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived )) + continue; + + cpack = packet_cache_get_packet (global_packcache, framecnt); + cache_packet_add_fragment (cpack, rx_packet, rcv_len); + cpack->recv_timestamp = jack_get_time(); + } +} + +void +packet_cache_reset_master_address( packet_cache *pcache ) +{ + pcache->master_address_valid = 0; + pcache->last_framecnt_retreived = 0; + pcache->last_framecnt_retreived_valid = 0; +} + +void +packet_cache_clear_old_packets (packet_cache *pcache, jack_nframes_t framecnt ) +{ + int i; + + for (i = 0; i < pcache->size; i++) + { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt)) + { + cache_packet_reset (&(pcache->packets[i])); + } + } +} + +int +packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ) +{ + int i; + cache_packet *cpack = NULL; + + + for (i = 0; i < pcache->size; i++) { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) { + cpack = &(pcache->packets[i]); + break; + } + } + + if( cpack == NULL ) { + //printf( "retreive packet: %d....not found\n", framecnt ); + return -1; + } + + if( !cache_packet_is_complete( cpack ) ) { + return -1; + } + + // ok. cpack is the one we want and its complete. + *packet_buf = cpack->packet_buf; + if( timestamp ) + *timestamp = cpack->recv_timestamp; + + pcache->last_framecnt_retreived_valid = 1; + pcache->last_framecnt_retreived = framecnt; + + return pkt_size; +} + +int +packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ) +{ + int i; + cache_packet *cpack = NULL; + + + for (i = 0; i < pcache->size; i++) { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) { + cpack = &(pcache->packets[i]); + break; + } + } + + if( cpack == NULL ) { + //printf( "retreive packet: %d....not found\n", framecnt ); + return -1; + } + + if( !cache_packet_is_complete( cpack ) ) { + return -1; + } + + cache_packet_reset (cpack); + packet_cache_clear_old_packets( pcache, framecnt ); + + return 0; +} +float +packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ) +{ + int num_packets_before_us = 0; + int i; + + for (i = 0; i < pcache->size; i++) + { + cache_packet *cpack = &(pcache->packets[i]); + if (cpack->valid && cache_packet_is_complete( cpack )) + if( cpack->framecnt >= expected_framecnt ) + num_packets_before_us += 1; + } + + return 100.0 * (float)num_packets_before_us / (float)( pcache->size ) ; +} + +// Returns 0 when no valid packet is inside the cache. +int +packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ) +{ + int i; + jack_nframes_t best_offset = JACK_MAX_FRAMES/2-1; + int retval = 0; + + for (i = 0; i < pcache->size; i++) + { + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + + if (!cpack->valid || !cache_packet_is_complete( cpack )) { + //printf( "invalid\n" ); + continue; + } + + if( cpack->framecnt < expected_framecnt ) + continue; + + if( (cpack->framecnt - expected_framecnt) > best_offset ) { + continue; + } + + best_offset = cpack->framecnt - expected_framecnt; + retval = 1; + + if( best_offset == 0 ) + break; + } + if( retval && framecnt ) + *framecnt = expected_framecnt + best_offset; + + return retval; +} + +int +packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt ) +{ + int i; + jack_nframes_t best_value = 0; + int retval = 0; + + for (i = 0; i < pcache->size; i++) + { + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + + if (!cpack->valid || !cache_packet_is_complete( cpack )) { + //printf( "invalid\n" ); + continue; + } + + if (cpack->framecnt < best_value) { + continue; + } + + best_value = cpack->framecnt; + retval = 1; + + } + if( retval && framecnt ) + *framecnt = best_value; + + return retval; +} + +// Returns 0 when no valid packet is inside the cache. +int +packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ) +{ + int i; + jack_nframes_t best_offset = 0; + int retval = 0; + + for (i = 0; i < pcache->size; i++) + { + cache_packet *cpack = &(pcache->packets[i]); + //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); + + if (!cpack->valid || !cache_packet_is_complete( cpack )) { + //printf( "invalid\n" ); + continue; + } + + if( (cpack->framecnt - expected_framecnt) < best_offset ) { + continue; + } + + best_offset = cpack->framecnt - expected_framecnt; + retval = 1; + + if( best_offset == 0 ) + break; + } + if( retval && framecnt ) + *framecnt = JACK_MAX_FRAMES - best_offset; + + return retval; +} +// fragmented packet IO +int +netjack_recvfrom (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, size_t *addr_size, int mtu) +{ + int retval; + socklen_t from_len = *addr_size; + if (pkt_size <= mtu) { + retval = recvfrom (sockfd, packet_buf, pkt_size, flags, addr, &from_len); + *addr_size = from_len; + return retval; + } + + char *rx_packet = alloca (mtu); + jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; + int rcv_len; + jack_nframes_t framecnt; + cache_packet *cpack; + do + { + rcv_len = recvfrom (sockfd, rx_packet, mtu, 0, addr, &from_len); + if (rcv_len < 0) + return rcv_len; + framecnt = ntohl (pkthdr->framecnt); + cpack = packet_cache_get_packet (global_packcache, framecnt); + cache_packet_add_fragment (cpack, rx_packet, rcv_len); + } while (!cache_packet_is_complete (cpack)); + memcpy (packet_buf, cpack->packet_buf, pkt_size); + cache_packet_reset (cpack); + *addr_size = from_len; + return pkt_size; +} + +int +netjack_recv (int sockfd, char *packet_buf, int pkt_size, int flags, int mtu) +{ + if (pkt_size <= mtu) + return recv (sockfd, packet_buf, pkt_size, flags); + char *rx_packet = alloca (mtu); + jacknet_packet_header *pkthdr = (jacknet_packet_header *) rx_packet; + int rcv_len; + jack_nframes_t framecnt; + cache_packet *cpack; + do + { + rcv_len = recv (sockfd, rx_packet, mtu, flags); + if (rcv_len < 0) + return rcv_len; + framecnt = ntohl (pkthdr->framecnt); + cpack = packet_cache_get_packet (global_packcache, framecnt); + cache_packet_add_fragment (cpack, rx_packet, rcv_len); + } while (!cache_packet_is_complete (cpack)); + memcpy (packet_buf, cpack->packet_buf, pkt_size); + cache_packet_reset (cpack); + return pkt_size; +} + +void +netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu) +{ + int frag_cnt = 0; + char *tx_packet, *dataX; + jacknet_packet_header *pkthdr; + + tx_packet = alloca (mtu + 10); + dataX = tx_packet + sizeof (jacknet_packet_header); + pkthdr = (jacknet_packet_header *) tx_packet; + + int fragment_payload_size = mtu - sizeof (jacknet_packet_header); + + if (pkt_size <= mtu) { + int err; + pkthdr = (jacknet_packet_header *) packet_buf; + pkthdr->fragment_nr = htonl (0); + err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size); + if( err<0 ) { + //printf( "error in send\n" ); + perror( "send" ); + } + } + else + { + int err; + // Copy the packet header to the tx pack first. + memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header)); + + // Now loop and send all + char *packet_bufX = packet_buf + sizeof (jacknet_packet_header); + + while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size)) + { + pkthdr->fragment_nr = htonl (frag_cnt++); + memcpy (dataX, packet_bufX, fragment_payload_size); + sendto (sockfd, tx_packet, mtu, flags, addr, addr_size); + packet_bufX += fragment_payload_size; + } + + int last_payload_size = packet_buf + pkt_size - packet_bufX; + memcpy (dataX, packet_bufX, last_payload_size); + pkthdr->fragment_nr = htonl (frag_cnt); + //jack_log("last fragment_count = %d, payload_size = %d\n", fragment_count, last_payload_size); + + // sendto(last_pack_size); + err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size); + if( err<0 ) { + //printf( "error in send\n" ); + perror( "send" ); + } + } +} + + +void +decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf) +{ + int i; + jack_midi_clear_buffer (buf); + for (i = 0; i < buffer_size_uint32 - 3;) + { + uint32_t payload_size; + payload_size = buffer_uint32[i]; + payload_size = ntohl (payload_size); + if (payload_size) + { + jack_midi_event_t event; + event.time = ntohl (buffer_uint32[i+1]); + event.size = ntohl (buffer_uint32[i+2]); + event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i+3])); + jack_midi_event_write (buf, event.time, event.buffer, event.size); + + // skip to the next event + unsigned int nb_data_quads = (((event.size-1) & ~0x3) >> 2)+1; + i += 3+nb_data_quads; + } + else + break; // no events can follow an empty event, we're done + } +} + +void +encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf) +{ + int i; + unsigned int written = 0; + // midi port, encode midi events + unsigned int nevents = jack_midi_get_event_count (buf); + for (i = 0; i < nevents; ++i) + { + jack_midi_event_t event; + jack_midi_event_get (&event, buf, i); + unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1; + unsigned int payload_size = 3 + nb_data_quads; + // only write if we have sufficient space for the event + // otherwise drop it + if (written + payload_size < buffer_size_uint32 - 1) + { + // write header + buffer_uint32[written]=htonl (payload_size); + written++; + buffer_uint32[written]=htonl (event.time); + written++; + buffer_uint32[written]=htonl (event.size); + written++; + + // write data + jack_midi_data_t* tmpbuff = (jack_midi_data_t*)(&(buffer_uint32[written])); + memcpy (tmpbuff, event.buffer, event.size); + written += nb_data_quads; + } + else + { + // buffer overflow + jack_error ("midi buffer overflow"); + break; + } + } + // now put a netjack_midi 'no-payload' event, signaling EOF + buffer_uint32[written]=0; +} + +// render functions for float +void +render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ + int chn = 0; + JSList *node = capture_ports; +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *)packet_payload; + + if( !packet_payload ) + return; + + while (node != NULL) + { + int i; + int_float_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_down != nframes) + { + SRC_STATE *src_state = src_node->data; + for (i = 0; i < net_period_down; i++) + { + packet_bufX[i] = ntohl (packet_bufX[i]); + } + + src.data_in = (float *) packet_bufX; + src.input_frames = net_period_down; + + src.data_out = buf; + src.output_frames = nframes; + + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } + else +#endif + { + if( dont_htonl_floats ) + { + memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); + } + else + { + for (i = 0; i < net_period_down; i++) + { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; + } + } + } + } + else if (jack_port_is_midi (porttype)) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down; + uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) +{ + int chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + uint32_t *packet_bufX = (uint32_t *) packet_payload; + + while (node != NULL) + { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + int i; + int_float_t val; + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, resample if necessary + +#if HAVE_SAMPLERATE + if (net_period_up != nframes) { + SRC_STATE *src_state = src_node->data; + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = (float *) packet_bufX; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) + { + packet_bufX[i] = htonl (packet_bufX[i]); + } + src_node = jack_slist_next (src_node); + } + else +#endif + { + if( dont_htonl_floats ) + { + memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); + } + else + { + for (i = 0; i < net_period_up; i++) + { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; + } + } + } + } + else if (jack_port_is_midi (porttype)) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +// render functions for 16bit +void +render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + int chn = 0; + JSList *node = capture_ports; +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif + + uint16_t *packet_bufX = (uint16_t *)packet_payload; + + if( !packet_payload ) + return; + + while (node != NULL) + { + int i; + //uint32_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + +#if HAVE_SAMPLERATE + float *floatbuf = alloca (sizeof(float) * net_period_down); +#endif + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, resample if necessary + +#if HAVE_SAMPLERATE + if (net_period_down != nframes) + { + SRC_STATE *src_state = src_node->data; + for (i = 0; i < net_period_down; i++) + { + floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0; + } + + src.data_in = floatbuf; + src.input_frames = net_period_down; + + src.data_out = buf; + src.output_frames = nframes; + + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } + else +#endif + for (i = 0; i < net_period_down; i++) + buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0; + } + else if (jack_port_is_midi (porttype)) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + int chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + uint16_t *packet_bufX = (uint16_t *)packet_payload; + + while (node != NULL) + { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + int i; + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, resample if necessary + +#if HAVE_SAMPLERATE + if (net_period_up != nframes) + { + SRC_STATE *src_state = src_node->data; + + float *floatbuf = alloca (sizeof(float) * net_period_up); + + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = floatbuf; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) + { + packet_bufX[i] = htons (((uint16_t)((floatbuf[i] + 1.0) * 32767.0))); + } + src_node = jack_slist_next (src_node); + } + else +#endif + for (i = 0; i < net_period_up; i++) + packet_bufX[i] = htons(((uint16_t)((buf[i] + 1.0) * 32767.0))); + } + else if (jack_port_is_midi (porttype)) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +// render functions for 8bit +void +render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + int chn = 0; + JSList *node = capture_ports; + +#if HAVE_SAMPLERATE + JSList *src_node = capture_srcs; +#endif + + int8_t *packet_bufX = (int8_t *)packet_payload; + + if( !packet_payload ) + return; + + while (node != NULL) + { + int i; + //uint32_t val; +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + +#if HAVE_SAMPLERATE + float *floatbuf = alloca (sizeof (float) * net_period_down); +#endif + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio(porttype)) + { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_down != nframes) + { + SRC_STATE *src_state = src_node->data; + for (i = 0; i < net_period_down; i++) + floatbuf[i] = ((float) packet_bufX[i]) / 127.0; + + src.data_in = floatbuf; + src.input_frames = net_period_down; + + src.data_out = buf; + src.output_frames = nframes; + + src.src_ratio = (float) nframes / (float) net_period_down; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + src_node = jack_slist_next (src_node); + } + else +#endif + for (i = 0; i < net_period_down; i++) + buf[i] = ((float) packet_bufX[i]) / 127.0; + } + else if (jack_port_is_midi (porttype)) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + int chn = 0; + JSList *node = playback_ports; +#if HAVE_SAMPLERATE + JSList *src_node = playback_srcs; +#endif + + int8_t *packet_bufX = (int8_t *)packet_payload; + + while (node != NULL) + { +#if HAVE_SAMPLERATE + SRC_DATA src; +#endif + int i; + jack_port_t *port = (jack_port_t *) node->data; + + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { +#if HAVE_SAMPLERATE + // audio port, resample if necessary + if (net_period_up != nframes) + { + + SRC_STATE *src_state = src_node->data; + + float *floatbuf = alloca (sizeof (float) * net_period_up); + + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = floatbuf; + src.output_frames = net_period_up; + + src.src_ratio = (float) net_period_up / (float) nframes; + src.end_of_input = 0; + + src_set_ratio (src_state, src.src_ratio); + src_process (src_state, &src); + + for (i = 0; i < net_period_up; i++) + packet_bufX[i] = floatbuf[i] * 127.0; + src_node = jack_slist_next (src_node); + } + else +#endif + for (i = 0; i < net_period_up; i++) + packet_bufX[i] = buf[i] * 127.0; + } + else if (jack_port_is_midi (porttype)) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 4; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +#if HAVE_CELT +// render functions for celt. +void +render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes) +{ + int chn = 0; + JSList *node = capture_ports; + JSList *src_node = capture_srcs; + + unsigned char *packet_bufX = (unsigned char *)packet_payload; + + while (node != NULL) + { + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, decode celt data. + + CELTDecoder *decoder = src_node->data; + if( !packet_payload ) + celt_decode_float( decoder, NULL, net_period_down, buf ); + else + celt_decode_float( decoder, packet_bufX, net_period_down, buf ); + + src_node = jack_slist_next (src_node); + } + else if (jack_port_is_midi (porttype)) + { + // midi port, decode midi events + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_down / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + if( packet_payload ) + decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_down); + node = jack_slist_next (node); + chn++; + } +} + +void +render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up) +{ + int chn = 0; + JSList *node = playback_ports; + JSList *src_node = playback_srcs; + + unsigned char *packet_bufX = (unsigned char *)packet_payload; + + while (node != NULL) + { + jack_port_t *port = (jack_port_t *) node->data; + jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); + const char *porttype = jack_port_type (port); + + if (jack_port_is_audio (porttype)) + { + // audio port, encode celt data. + + int encoded_bytes; + float *floatbuf = alloca (sizeof(float) * nframes ); + memcpy( floatbuf, buf, nframes*sizeof(float) ); + CELTEncoder *encoder = src_node->data; + encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); + if( encoded_bytes != net_period_up ) + printf( "something in celt changed. netjack needs to be changed to handle this.\n" ); + src_node = jack_slist_next( src_node ); + } + else if (jack_port_is_midi (porttype)) + { + // encode midi events from port to packet + // convert the data buffer to a standard format (uint32_t based) + unsigned int buffer_size_uint32 = net_period_up / 2; + uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; + encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); + } + packet_bufX = (packet_bufX + net_period_up); + node = jack_slist_next (node); + chn++; + } +} + +#endif +/* Wrapper functions with bitdepth argument... */ +void +render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +{ + if (bitdepth == 8) + render_payload_to_jack_ports_8bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); + else if (bitdepth == 16) + render_payload_to_jack_ports_16bit (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); +#if HAVE_CELT + else if (bitdepth == CELT_MODE) + render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); +#endif + else + render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); +} + +void +render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) +{ + if (bitdepth == 8) + render_jack_ports_to_payload_8bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); + else if (bitdepth == 16) + render_jack_ports_to_payload_16bit (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); +#if HAVE_CELT + else if (bitdepth == CELT_MODE) + render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); +#endif + else + render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); +} diff --git a/common/netjack_packet.h b/common/netjack_packet.h new file mode 100644 index 00000000..4617310e --- /dev/null +++ b/common/netjack_packet.h @@ -0,0 +1,165 @@ + +/* + * NetJack - Packet Handling functions + * + * used by the driver and the jacknet_client + * + * Copyright (C) 2006 Torben Hohn + * + * 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. + * + * $Id: net_driver.c,v 1.16 2006/03/20 19:41:37 torbenh Exp $ + * + */ + +#ifndef __JACK_NET_PACKET_H__ +#define __JACK_NET_PACKET_H__ + +#ifdef __cplusplus + extern "C" + { +#endif + +#include +#include +//#include +#include + +#include + +//#include +// The Packet Header. + +#define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression +#define MASTER_FREEWHEELS 0x80000000 + +typedef struct _jacknet_packet_header jacknet_packet_header; + +struct _jacknet_packet_header +{ + // General AutoConf Data + jack_nframes_t capture_channels_audio; + jack_nframes_t playback_channels_audio; + jack_nframes_t capture_channels_midi; + jack_nframes_t playback_channels_midi; + jack_nframes_t period_size; + jack_nframes_t sample_rate; + + // Transport Sync + jack_nframes_t sync_state; + jack_nframes_t transport_frame; + jack_nframes_t transport_state; + + // Packet loss Detection, and latency reduction + jack_nframes_t framecnt; + jack_nframes_t latency; + + jack_nframes_t reply_port; + jack_nframes_t mtu; + jack_nframes_t fragment_nr; +}; + +typedef union _int_float int_float_t; + +union _int_float +{ + uint32_t i; + float f; +}; + +// fragment reorder cache. +typedef struct _cache_packet cache_packet; + +struct _cache_packet +{ + int valid; + int num_fragments; + int packet_size; + int mtu; + jack_time_t recv_timestamp; + jack_nframes_t framecnt; + char * fragment_array; + char * packet_buf; +}; + +typedef struct _packet_cache packet_cache; + +struct _packet_cache +{ + int size; + cache_packet *packets; + int mtu; + struct sockaddr_in master_address; + int master_address_valid; + jack_nframes_t last_framecnt_retreived; + int last_framecnt_retreived_valid; +}; + +extern packet_cache *global_packcache; + +// fragment cache function prototypes +// XXX: Some of these are private. +packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu); +void packet_cache_free(packet_cache *pkt_cache); + +cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt); +cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache); +cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache); + +void cache_packet_reset(cache_packet *pack); +void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt); +void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len); +int cache_packet_is_complete(cache_packet *pack); + +void packet_cache_drain_socket( packet_cache *pcache, int sockfd ); +void packet_cache_reset_master_address( packet_cache *pcache ); +float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ); +int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ); +int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ); +int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); +int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt ); +int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); +// Function Prototypes + +int netjack_poll_deadline (int sockfd, jack_time_t deadline); + +void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu); + + +int get_sample_size(int bitdepth); +void packet_header_hton(jacknet_packet_header *pkthdr); + +void packet_header_ntoh(jacknet_packet_header *pkthdr); + +void render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats ); + +void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); + + +// XXX: This is sort of deprecated: +// This one waits forever. an is not using ppoll +int netjack_poll(int sockfd, int timeout); + +// TODO: these are deprecated. +//int netjack_recvfrom(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, socklen_t *addr_size, int mtu); +//int netjack_recv(int sockfd, char *packet_buf, int pkt_size, int flags, int mtu); + +void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); +void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); +#ifdef __cplusplus + } +#endif +#endif + diff --git a/common/ringbuffer.c b/common/ringbuffer.c index a7209a2b..f2096630 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -67,23 +67,27 @@ size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); EXPORT jack_ringbuffer_t * jack_ringbuffer_create (size_t sz) { - int power_of_two; - jack_ringbuffer_t *rb; - - rb = (jack_ringbuffer_t*)malloc (sizeof (jack_ringbuffer_t)); - - for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); - - rb->size = 1 << power_of_two; - rb->size_mask = rb->size; - rb->size_mask -= 1; - rb->write_ptr = 0; - rb->read_ptr = 0; - rb->buf = (char*)malloc (rb->size); - memset(rb->buf, 0, rb->size); - rb->mlocked = 0; - - return rb; + int power_of_two; + jack_ringbuffer_t *rb; + + if ((rb = malloc (sizeof (jack_ringbuffer_t))) == NULL) { + return NULL; + } + + for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); + + rb->size = 1 << power_of_two; + rb->size_mask = rb->size; + rb->size_mask -= 1; + rb->write_ptr = 0; + rb->read_ptr = 0; + if ((rb->buf = malloc (rb->size)) == NULL) { + free (rb); + return NULL; + } + rb->mlocked = 0; + + return rb; } /* Free all data associated with the ringbuffer `rb'. */ @@ -92,12 +96,12 @@ EXPORT void jack_ringbuffer_free (jack_ringbuffer_t * rb) { #ifdef USE_MLOCK - if (rb->mlocked) { - munlock (rb->buf, rb->size); - } + if (rb->mlocked) { + munlock (rb->buf, rb->size); + } #endif /* USE_MLOCK */ - free (rb->buf); - free (rb); + free (rb->buf); + free (rb); } /* Lock the data block of `rb' using the system call 'mlock'. */ @@ -106,12 +110,12 @@ EXPORT int jack_ringbuffer_mlock (jack_ringbuffer_t * rb) { #ifdef USE_MLOCK - if (mlock (rb->buf, rb->size)) { - return -1; - } + if (mlock (rb->buf, rb->size)) { + return -1; + } #endif /* USE_MLOCK */ - rb->mlocked = 1; - return 0; + rb->mlocked = 1; + return 0; } /* Reset the read and write pointers to zero. This is not thread @@ -120,8 +124,8 @@ jack_ringbuffer_mlock (jack_ringbuffer_t * rb) EXPORT void jack_ringbuffer_reset (jack_ringbuffer_t * rb) { - rb->read_ptr = 0; - rb->write_ptr = 0; + rb->read_ptr = 0; + rb->write_ptr = 0; } /* Reset the read and write pointers to zero. This is not thread @@ -130,11 +134,11 @@ jack_ringbuffer_reset (jack_ringbuffer_t * rb) EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz) { - rb->size = sz; - rb->size_mask = rb->size; - rb->size_mask -= 1; - rb->read_ptr = 0; - rb->write_ptr = 0; + rb->size = sz; + rb->size_mask = rb->size; + rb->size_mask -= 1; + rb->read_ptr = 0; + rb->write_ptr = 0; } /* Return the number of bytes available for reading. This is the @@ -144,16 +148,16 @@ jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz) EXPORT size_t jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) { - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - return w - r; - } else { - return (w - r + rb->size) & rb->size_mask; - } + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + return w - r; + } else { + return (w - r + rb->size) & rb->size_mask; + } } /* Return the number of bytes available for writing. This is the @@ -163,18 +167,18 @@ jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) EXPORT size_t jack_ringbuffer_write_space (const jack_ringbuffer_t * rb) { - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - return ((r - w + rb->size) & rb->size_mask) - 1; - } else if (w < r) { - return (r - w) - 1; - } else { - return rb->size - 1; - } + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + return ((r - w + rb->size) & rb->size_mask) - 1; + } else if (w < r) { + return (r - w) - 1; + } else { + return rb->size - 1; + } } /* The copying data reader. Copy at most `cnt' bytes from `rb' to @@ -183,77 +187,77 @@ jack_ringbuffer_write_space (const jack_ringbuffer_t * rb) EXPORT size_t jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_read; - size_t n1, n2; + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; - if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { + return 0; + } - to_read = cnt > free_cnt ? free_cnt : cnt; + to_read = cnt > free_cnt ? free_cnt : cnt; - cnt2 = rb->read_ptr + to_read; + cnt2 = rb->read_ptr + to_read; - if (cnt2 > rb->size) { - n1 = rb->size - rb->read_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_read; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - rb->read_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_read; + n2 = 0; + } - memcpy (dest, &(rb->buf[rb->read_ptr]), n1); - rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; + memcpy (dest, &(rb->buf[rb->read_ptr]), n1); + rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); - rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; - } + if (n2) { + memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); + rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; + } - return to_read; + return to_read; } -/* The copying data reader w/o read pointer advance. Copy at most - `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes -copied. */ +/* The copying data reader w/o read pointer advance. Copy at most + `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes + copied. */ EXPORT size_t jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_read; - size_t n1, n2; - size_t tmp_read_ptr; + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; + size_t tmp_read_ptr; - tmp_read_ptr = rb->read_ptr; + tmp_read_ptr = rb->read_ptr; - if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { + return 0; + } - to_read = cnt > free_cnt ? free_cnt : cnt; + to_read = cnt > free_cnt ? free_cnt : cnt; - cnt2 = tmp_read_ptr + to_read; + cnt2 = tmp_read_ptr + to_read; - if (cnt2 > rb->size) { - n1 = rb->size - tmp_read_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_read; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - tmp_read_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_read; + n2 = 0; + } - memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); - tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; + memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); + tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); - } + if (n2) { + memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); + } - return to_read; + return to_read; } /* The copying data writer. Copy at most `cnt' bytes to `rb' from @@ -262,36 +266,36 @@ jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt) EXPORT size_t jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_write; - size_t n1, n2; + size_t free_cnt; + size_t cnt2; + size_t to_write; + size_t n1, n2; - if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { + return 0; + } - to_write = cnt > free_cnt ? free_cnt : cnt; + to_write = cnt > free_cnt ? free_cnt : cnt; - cnt2 = rb->write_ptr + to_write; + cnt2 = rb->write_ptr + to_write; - if (cnt2 > rb->size) { - n1 = rb->size - rb->write_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_write; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - rb->write_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_write; + n2 = 0; + } - memcpy (&(rb->buf[rb->write_ptr]), src, n1); - rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; + memcpy (&(rb->buf[rb->write_ptr]), src, n1); + rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); - rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; - } + if (n2) { + memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); + rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; + } - return to_write; + return to_write; } /* Advance the read pointer `cnt' places. */ @@ -299,8 +303,8 @@ jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt) EXPORT void jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt) { - size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; - rb->read_ptr = tmp; + size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; + rb->read_ptr = tmp; } /* Advance the write pointer `cnt' places. */ @@ -308,8 +312,8 @@ jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt) EXPORT void jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt) { - size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; - rb->write_ptr = tmp; + size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; + rb->write_ptr = tmp; } /* The non-copying data reader. `vec' is an array of two places. Set @@ -321,39 +325,39 @@ EXPORT void jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb, jack_ringbuffer_data_t * vec) { - size_t free_cnt; - size_t cnt2; - size_t w, r; + size_t free_cnt; + size_t cnt2; + size_t w, r; - w = rb->write_ptr; - r = rb->read_ptr; + w = rb->write_ptr; + r = rb->read_ptr; - if (w > r) { - free_cnt = w - r; - } else { - free_cnt = (w - r + rb->size) & rb->size_mask; - } + if (w > r) { + free_cnt = w - r; + } else { + free_cnt = (w - r + rb->size) & rb->size_mask; + } - cnt2 = r + free_cnt; + cnt2 = r + free_cnt; - if (cnt2 > rb->size) { + if (cnt2 > rb->size) { - /* Two part vector: the rest of the buffer after the current write - ptr, plus some from the start of the buffer. */ + /* Two part vector: the rest of the buffer after the current write + ptr, plus some from the start of the buffer. */ - vec[0].buf = &(rb->buf[r]); - vec[0].len = rb->size - r; - vec[1].buf = rb->buf; - vec[1].len = cnt2 & rb->size_mask; + vec[0].buf = &(rb->buf[r]); + vec[0].len = rb->size - r; + vec[1].buf = rb->buf; + vec[1].len = cnt2 & rb->size_mask; - } else { + } else { - /* Single part vector: just the rest of the buffer */ + /* Single part vector: just the rest of the buffer */ - vec[0].buf = &(rb->buf[r]); - vec[0].len = free_cnt; - vec[1].len = 0; - } + vec[0].buf = &(rb->buf[r]); + vec[0].len = free_cnt; + vec[1].len = 0; + } } /* The non-copying data writer. `vec' is an array of two places. Set @@ -365,35 +369,35 @@ EXPORT void jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb, jack_ringbuffer_data_t * vec) { - size_t free_cnt; - size_t cnt2; - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; - } else if (w < r) { - free_cnt = (r - w) - 1; - } else { - free_cnt = rb->size - 1; - } - - cnt2 = w + free_cnt; - - if (cnt2 > rb->size) { - - /* Two part vector: the rest of the buffer after the current write - ptr, plus some from the start of the buffer. */ - - vec[0].buf = &(rb->buf[w]); - vec[0].len = rb->size - w; - vec[1].buf = rb->buf; - vec[1].len = cnt2 & rb->size_mask; - } else { - vec[0].buf = &(rb->buf[w]); - vec[0].len = free_cnt; - vec[1].len = 0; - } -} + size_t free_cnt; + size_t cnt2; + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; + } else if (w < r) { + free_cnt = (r - w) - 1; + } else { + free_cnt = rb->size - 1; + } + + cnt2 = w + free_cnt; + + if (cnt2 > rb->size) { + + /* Two part vector: the rest of the buffer after the current write + ptr, plus some from the start of the buffer. */ + + vec[0].buf = &(rb->buf[w]); + vec[0].len = rb->size - w; + vec[1].buf = rb->buf; + vec[1].len = cnt2 & rb->size_mask; + } else { + vec[0].buf = &(rb->buf[w]); + vec[0].len = free_cnt; + vec[1].len = 0; + } +} \ No newline at end of file diff --git a/dbus/audio_reserve.c b/dbus/audio_reserve.c index 120db64f..049826a5 100644 --- a/dbus/audio_reserve.c +++ b/dbus/audio_reserve.c @@ -106,10 +106,10 @@ SERVER_EXPORT void audio_release(const char * device_name) } if (i < DEVICE_MAX) { - jack_info("Released audio card %s", device_name); + jack_info("Released audio card %s", device_name); rd_release(gReservedDevice[i].reserved_device); } else { - jack_error("Audio card %s not found!!", device_name); + jack_error("Audio card %s not found!!", device_name); } // Close DBus connection last time diff --git a/dbus/controller_iface_control.c b/dbus/controller_iface_control.c index f55fb608..768c192f 100644 --- a/dbus/controller_iface_control.c +++ b/dbus/controller_iface_control.c @@ -340,7 +340,7 @@ JACK_DBUS_METHOD_ARGUMENTS_BEGIN(LoadInternal) JACK_DBUS_METHOD_ARGUMENT("internal", "s", false) JACK_DBUS_METHOD_ARGUMENTS_END -JACK_DBUS_METHOD_ARGUMENTS_BEGIN(UnlooadInternal) +JACK_DBUS_METHOD_ARGUMENTS_BEGIN(UnloadInternal) JACK_DBUS_METHOD_ARGUMENT("internal", "s", false) JACK_DBUS_METHOD_ARGUMENTS_END @@ -366,7 +366,7 @@ JACK_DBUS_METHODS_BEGIN JACK_DBUS_METHOD_DESCRIBE(IsRealtime, NULL) JACK_DBUS_METHOD_DESCRIBE(ResetXruns, NULL) JACK_DBUS_METHOD_DESCRIBE(LoadInternal, NULL) - JACK_DBUS_METHOD_DESCRIBE(UnlooadInternal, NULL) + JACK_DBUS_METHOD_DESCRIBE(UnloadInternal, NULL) JACK_DBUS_METHOD_DESCRIBE(AddSlave, NULL) JACK_DBUS_METHOD_DESCRIBE(RemoveSlave, NULL) JACK_DBUS_METHODS_END diff --git a/dbus/controller_iface_patchbay.c b/dbus/controller_iface_patchbay.c index e89c7b3b..9adb7cfa 100644 --- a/dbus/controller_iface_patchbay.c +++ b/dbus/controller_iface_patchbay.c @@ -1763,7 +1763,8 @@ JACK_DBUS_METHOD_ARGUMENTS_BEGIN(DisconnectPortsByConnectionID) JACK_DBUS_METHOD_ARGUMENTS_END JACK_DBUS_METHOD_ARGUMENTS_BEGIN(GetClientPID) - JACK_DBUS_METHOD_ARGUMENT("client_id", DBUS_TYPE_INT64_AS_STRING, false) + JACK_DBUS_METHOD_ARGUMENT("client_id", DBUS_TYPE_UINT64_AS_STRING, false) + JACK_DBUS_METHOD_ARGUMENT("process_id", DBUS_TYPE_INT64_AS_STRING, true) JACK_DBUS_METHOD_ARGUMENTS_END JACK_DBUS_METHODS_BEGIN diff --git a/dbus/sigsegv.c b/dbus/sigsegv.c index 46645408..26bc204f 100644 --- a/dbus/sigsegv.c +++ b/dbus/sigsegv.c @@ -26,12 +26,10 @@ #include #include #include -#include #include #include #include #ifndef NO_CPP_DEMANGLE -//#include char * __cxa_demangle(const char * __mangled_name, char * __output_buffer, size_t * __length, int * __status); #endif @@ -56,6 +54,8 @@ static void signal_segv(int signum, siginfo_t* info, void*ptr) #else +#include + static void signal_segv(int signum, siginfo_t* info, void*ptr) { static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"}; diff --git a/example-clients/alsa_in.c b/example-clients/alsa_in.c new file mode 100644 index 00000000..2a8b78c3 --- /dev/null +++ b/example-clients/alsa_in.c @@ -0,0 +1,757 @@ +/** @file simple_client.c + * + * @brief This simple client demonstrates the basic features of JACK + * as they would be used by many applications. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "alsa/asoundlib.h" + +#include + +// Here are the lists of the jack ports... + +JSList *capture_ports = NULL; +JSList *capture_srcs = NULL; +JSList *playback_ports = NULL; +JSList *playback_srcs = NULL; +jack_client_t *client; + +snd_pcm_t *alsa_handle; + +int jack_sample_rate; +int jack_buffer_size; + +int quit = 0; +double resample_mean = 1.0; +double static_resample_factor = 1.0; + +double *offset_array; +double *window_array; +int offset_differential_index = 0; + +double offset_integral = 0; + +// ------------------------------------------------------ commandline parameters + +int sample_rate = 0; /* stream rate */ +int num_channels = 2; /* count of channels */ +int period_size = 1024; +int num_periods = 2; + +int target_delay = 0; /* the delay which the program should try to approach. */ +int max_diff = 0; /* the diff value, when a hard readpointer skip should occur */ +int catch_factor = 100000; +int catch_factor2 = 10000; +double pclamp = 15.0; +double controlquant = 10000.0; +int smooth_size = 256; +int good_window=0; +int verbose = 0; +int instrument = 0; +int samplerate_quality = 2; + +// Debug stuff: + +volatile float output_resampling_factor = 1.0; +volatile int output_new_delay = 0; +volatile float output_offset = 0.0; +volatile float output_integral = 0.0; +volatile float output_diff = 0.0; + +snd_pcm_uframes_t real_buffer_size; +snd_pcm_uframes_t real_period_size; + +// format selection, and corresponding functions from memops in a nice set of structs. + +typedef struct alsa_format { + snd_pcm_format_t format_id; + size_t sample_size; + void (*jack_to_soundcard) (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); + void (*soundcard_to_jack) (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); + const char *name; +} alsa_format_t; + +alsa_format_t formats[] = { + { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, + { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, + { SND_PCM_FORMAT_S24_3LE, 3, sample_move_d24_sS, sample_move_dS_s24, "24bit - real" }, + { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, + { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } +}; +#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) +int format=0; + +// Alsa stuff... i dont want to touch this bullshit in the next years.... please... + +static int xrun_recovery(snd_pcm_t *handle, int err) { +// printf( "xrun !!!.... %d\n", err ); + if (err == -EPIPE) { /* under-run */ + err = snd_pcm_prepare(handle); + if (err < 0) + printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); + return 0; + } else if (err == -EAGAIN) { + while ((err = snd_pcm_resume(handle)) == -EAGAIN) + usleep(100); /* wait until the suspend flag is released */ + if (err < 0) { + err = snd_pcm_prepare(handle); + if (err < 0) + printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); + } + return 0; + } + return err; +} + +static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params ) +{ + int i; + int err; + + for( i=0; i (target_delay+max_diff) ) { + char *tmp = alloca( (delay-target_delay) * formats[format].sample_size * num_channels ); + snd_pcm_readi( alsa_handle, tmp, delay-target_delay ); + output_new_delay = (int) delay; + + delay = target_delay; + + // Set the resample_rate... we need to adjust the offset integral, to do this. + // first look at the PI controller, this code is just a special case, which should never execute once + // everything is swung in. + offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; + // Also clear the array. we are beginning a new control cycle. + for( i=0; i 4 ) current_resample_factor = 4; + + // Now Calculate how many samples we need. + rlen = ceil( ((double)nframes) / current_resample_factor )+2; + assert( rlen > 2 ); + + // Calculate resample_mean so we can init ourselves to saner values. + resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; + /* + * now this should do it... + */ + + outbuf = alloca( rlen * formats[format].sample_size * num_channels ); + + resampbuf = alloca( rlen * sizeof( float ) ); + + // get the data... +again: + err = snd_pcm_readi(alsa_handle, outbuf, rlen); + if( err < 0 ) { + printf( "err = %d\n", err ); + if (xrun_recovery(alsa_handle, err) < 0) { + //printf("Write error: %s\n", snd_strerror(err)); + //exit(EXIT_FAILURE); + } + goto again; + } + if( err != rlen ) { + //printf( "read = %d\n", rlen ); + } + + /* + * render jack ports to the outbuf... + */ + + int chn = 0; + JSList *node = capture_ports; + JSList *src_node = capture_srcs; + SRC_DATA src; + + while ( node != NULL) + { + jack_port_t *port = (jack_port_t *) node->data; + float *buf = jack_port_get_buffer (port, nframes); + + SRC_STATE *src_state = src_node->data; + + formats[format].soundcard_to_jack( resampbuf, outbuf + format[formats].sample_size * chn, rlen, num_channels*format[formats].sample_size ); + + src.data_in = resampbuf; + src.input_frames = rlen; + + src.data_out = buf; + src.output_frames = nframes; + src.end_of_input = 0; + + src.src_ratio = current_resample_factor; + + src_process( src_state, &src ); + + put_back_samples = rlen-src.input_frames_used; + + src_node = jack_slist_next (src_node); + node = jack_slist_next (node); + chn++; + } + + // Put back the samples libsamplerate did not consume. + //printf( "putback = %d\n", put_back_samples ); + snd_pcm_rewind( alsa_handle, put_back_samples ); + + return 0; +} + + +/** + * Allocate the necessary jack ports... + */ + +void alloc_ports( int n_capture, int n_playback ) { + + int port_flags = JackPortIsOutput; + int chn; + jack_port_t *port; + char buf[32]; + + capture_ports = NULL; + for (chn = 0; chn < n_capture; chn++) + { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1); + + port = jack_port_register (client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) + { + printf( "jacknet_client: cannot register port for %s", buf); + break; + } + + capture_srcs = jack_slist_append( capture_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); + capture_ports = jack_slist_append (capture_ports, port); + } + + port_flags = JackPortIsInput; + + playback_ports = NULL; + for (chn = 0; chn < n_playback; chn++) + { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1); + + port = jack_port_register (client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) + { + printf( "jacknet_client: cannot register port for %s", buf); + break; + } + + playback_srcs = jack_slist_append( playback_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); + playback_ports = jack_slist_append (playback_ports, port); + } +} + +/** + * This is the shutdown callback for this JACK application. + * It is called by JACK if the server ever shuts down or + * decides to disconnect the client. + */ + +void jack_shutdown (void *arg) { + + exit (1); +} + +/** + * be user friendly. + * be user friendly. + * be user friendly. + */ + +void printUsage() { +fprintf(stderr, "usage: alsa_out [options]\n" + "\n" + " -j - client name\n" + " -d \n" + " -c \n" + " -p \n" + " -n \n" + " -r \n" + " -q \n" + " -t \n" + " -i turns on instrumentation\n" + " -v turns on printouts\n" + "\n"); +} + + +/** + * the main function.... + */ + +void +sigterm_handler( int signal ) +{ + quit = 1; +} + + +int main (int argc, char *argv[]) { + char jack_name[30] = "alsa_in"; + char alsa_device[30] = "hw:0"; + + extern char *optarg; + extern int optind, optopt; + int errflg=0; + int c; + + while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:")) != -1) { + switch(c) { + case 'j': + strcpy(jack_name,optarg); + break; + case 'r': + sample_rate = atoi(optarg); + break; + case 'c': + num_channels = atoi(optarg); + break; + case 'p': + period_size = atoi(optarg); + break; + case 'n': + num_periods = atoi(optarg); + break; + case 'd': + strcpy(alsa_device,optarg); + break; + case 't': + target_delay = atoi(optarg); + break; + case 'q': + samplerate_quality = atoi(optarg); + break; + case 'm': + max_diff = atoi(optarg); + break; + case 'f': + catch_factor = atoi(optarg); + break; + case 'F': + catch_factor2 = atoi(optarg); + break; + case 'C': + pclamp = (double) atoi(optarg); + break; + case 'Q': + controlquant = (double) atoi(optarg); + break; + case 'v': + verbose = 1; + break; + case 'i': + instrument = 1; + break; + case 's': + smooth_size = atoi(optarg); + break; + case ':': + fprintf(stderr, + "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + fprintf(stderr, + "Unrecognized option: -%c\n", optopt); + errflg++; + } + } + if (errflg) { + printUsage(); + exit(2); + } + + if( (samplerate_quality < 0) || (samplerate_quality > 4) ) { + fprintf (stderr, "invalid samplerate quality\n"); + return 1; + } + if ((client = jack_client_open (jack_name, 0, NULL)) == 0) { + fprintf (stderr, "jack server not running?\n"); + return 1; + } + + /* tell the JACK server to call `process()' whenever + there is work to be done. + */ + + jack_set_process_callback (client, process, 0); + + /* tell the JACK server to call `jack_shutdown()' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. + */ + + jack_on_shutdown (client, jack_shutdown, 0); + + + // get jack sample_rate + + jack_sample_rate = jack_get_sample_rate( client ); + + if( !sample_rate ) + sample_rate = jack_sample_rate; + + // now open the alsa fd... + alsa_handle = open_audiofd( alsa_device, 1, sample_rate, num_channels, period_size, num_periods); + if( alsa_handle == 0 ) + exit(20); + + printf( "selected sample format: %s\n", formats[format].name ); + + static_resample_factor = (double) jack_sample_rate / (double) sample_rate; + resample_mean = static_resample_factor; + + offset_array = malloc( sizeof(double) * smooth_size ); + if( offset_array == NULL ) { + fprintf( stderr, "no memory for offset_array !!!\n" ); + exit(20); + } + window_array = malloc( sizeof(double) * smooth_size ); + if( window_array == NULL ) { + fprintf( stderr, "no memory for window_array !!!\n" ); + exit(20); + } + int i; + for( i=0; i target_delay ) { + fprintf( stderr, "target_delay (%d) cant be smaller than max_diff(%d)\n", target_delay, max_diff ); + exit(20); + } + if( (target_delay+max_diff) > (num_periods*period_size) ) { + fprintf( stderr, "target_delay+max_diff (%d) cant be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size ); + exit(20); + } + // alloc input ports, which are blasted out to alsa... + alloc_ports( num_channels, 0 ); + + + /* tell the JACK server that we are ready to roll */ + + if (jack_activate (client)) { + fprintf (stderr, "cannot activate client"); + return 1; + } + + signal( SIGTERM, sigterm_handler ); + signal( SIGINT, sigterm_handler ); + + if( verbose ) { + while(!quit) { + usleep(500000); + if( output_new_delay ) { + printf( "delay = %d\n", output_new_delay ); + output_new_delay = 0; + } + printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset ); + } + } else if( instrument ) { + printf( "# n\tresamp\tdiff\toffseti\tintegral\n"); + int n=0; + while(!quit) { + usleep(1000); + printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral ); + } + } else { + while(!quit) + { + usleep(500000); + if( output_new_delay ) { + printf( "delay = %d\n", output_new_delay ); + output_new_delay = 0; + } + } + } + + jack_deactivate( client ); + jack_client_close (client); + exit (0); +} + diff --git a/example-clients/alsa_out.c b/example-clients/alsa_out.c new file mode 100644 index 00000000..2d34cd13 --- /dev/null +++ b/example-clients/alsa_out.c @@ -0,0 +1,755 @@ +/** @file simple_client.c + * + * @brief This simple client demonstrates the basic features of JACK + * as they would be used by many applications. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "alsa/asoundlib.h" + +#include + +// Here are the lists of the jack ports... + +JSList *capture_ports = NULL; +JSList *capture_srcs = NULL; +JSList *playback_ports = NULL; +JSList *playback_srcs = NULL; +jack_client_t *client; + +snd_pcm_t *alsa_handle; + +int jack_sample_rate; +int jack_buffer_size; + +double resample_mean = 1.0; +double static_resample_factor = 1.0; + +double *offset_array; +double *window_array; +int offset_differential_index = 0; + +double offset_integral = 0; +int quit = 0; + +// ------------------------------------------------------ commandline parameters + +int sample_rate = 0; /* stream rate */ +int num_channels = 2; /* count of channels */ +int period_size = 1024; +int num_periods = 2; + +int target_delay = 0; /* the delay which the program should try to approach. */ +int max_diff = 0; /* the diff value, when a hard readpointer skip should occur */ +int catch_factor = 100000; +int catch_factor2 = 10000; +double pclamp = 15.0; +double controlquant = 10000.0; +int smooth_size = 256; +int good_window=0; +int verbose = 0; +int instrument = 0; +int samplerate_quality = 2; + +// Debug stuff: + +volatile float output_resampling_factor = 1.0; +volatile int output_new_delay = 0; +volatile float output_offset = 0.0; +volatile float output_integral = 0.0; +volatile float output_diff = 0.0; + +snd_pcm_uframes_t real_buffer_size; +snd_pcm_uframes_t real_period_size; + +// format selection, and corresponding functions from memops in a nice set of structs. + +typedef struct alsa_format { + snd_pcm_format_t format_id; + size_t sample_size; + void (*jack_to_soundcard) (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); + void (*soundcard_to_jack) (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); + const char *name; +} alsa_format_t; + +alsa_format_t formats[] = { + { SND_PCM_FORMAT_FLOAT_LE, 4, sample_move_dS_floatLE, sample_move_floatLE_sSs, "float" }, + { SND_PCM_FORMAT_S32, 4, sample_move_d32u24_sS, sample_move_dS_s32u24, "32bit" }, + { SND_PCM_FORMAT_S24, 4, sample_move_d24_sS, sample_move_dS_s24, "24bit" }, + { SND_PCM_FORMAT_S16, 2, sample_move_d16_sS, sample_move_dS_s16, "16bit" } +}; +#define NUMFORMATS (sizeof(formats)/sizeof(formats[0])) +int format=0; + +// Alsa stuff... i dont want to touch this bullshit in the next years.... please... + +static int xrun_recovery(snd_pcm_t *handle, int err) { +// printf( "xrun !!!.... %d\n", err ); + if (err == -EPIPE) { /* under-run */ + err = snd_pcm_prepare(handle); + if (err < 0) + printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); + return 0; + } else if (err == -EAGAIN) { + while ((err = snd_pcm_resume(handle)) == -EAGAIN) + usleep(100); /* wait until the suspend flag is released */ + if (err < 0) { + err = snd_pcm_prepare(handle); + if (err < 0) + printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); + } + return 0; + } + return err; +} + +static int set_hwformat( snd_pcm_t *handle, snd_pcm_hw_params_t *params ) +{ + int i; + int err; + + for( i=0; i (target_delay+max_diff) ) { + snd_pcm_rewind( alsa_handle, delay - target_delay ); + output_new_delay = (int) delay; + + delay = target_delay; + + // Set the resample_rate... we need to adjust the offset integral, to do this. + // first look at the PI controller, this code is just a special case, which should never execute once + // everything is swung in. + offset_integral = - (resample_mean - static_resample_factor) * catch_factor * catch_factor2; + // Also clear the array. we are beginning a new control cycle. + for( i=0; i 4 ) current_resample_factor = 4; + + // Now Calculate how many samples we need. + rlen = ceil( ((double)nframes) * current_resample_factor )+2; + assert( rlen > 2 ); + + // Calculate resample_mean so we can init ourselves to saner values. + resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; + /* + * now this should do it... + */ + + outbuf = alloca( rlen * formats[format].sample_size * num_channels ); + + resampbuf = alloca( rlen * sizeof( float ) ); + /* + * render jack ports to the outbuf... + */ + + int chn = 0; + JSList *node = playback_ports; + JSList *src_node = playback_srcs; + SRC_DATA src; + + while ( node != NULL) + { + jack_port_t *port = (jack_port_t *) node->data; + float *buf = jack_port_get_buffer (port, nframes); + + SRC_STATE *src_state = src_node->data; + + src.data_in = buf; + src.input_frames = nframes; + + src.data_out = resampbuf; + src.output_frames = rlen; + src.end_of_input = 0; + + src.src_ratio = current_resample_factor; + + src_process( src_state, &src ); + + formats[format].jack_to_soundcard( outbuf + format[formats].sample_size * chn, resampbuf, src.output_frames_gen, num_channels*format[formats].sample_size, NULL); + + src_node = jack_slist_next (src_node); + node = jack_slist_next (node); + chn++; + } + + // now write the output... +again: + err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen); + //err = snd_pcm_writei(alsa_handle, outbuf, src.output_frames_gen); + if( err < 0 ) { + printf( "err = %d\n", err ); + if (xrun_recovery(alsa_handle, err) < 0) { + printf("Write error: %s\n", snd_strerror(err)); + exit(EXIT_FAILURE); + } + goto again; + } + + return 0; +} + + +/** + * Allocate the necessary jack ports... + */ + +void alloc_ports( int n_capture, int n_playback ) { + + int port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + int chn; + jack_port_t *port; + char buf[32]; + + capture_ports = NULL; + for (chn = 0; chn < n_capture; chn++) + { + snprintf (buf, sizeof(buf) - 1, "capture_%u", chn+1); + + port = jack_port_register (client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) + { + printf( "jacknet_client: cannot register port for %s", buf); + break; + } + + capture_srcs = jack_slist_append( capture_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); + capture_ports = jack_slist_append (capture_ports, port); + } + + port_flags = JackPortIsInput; + + playback_ports = NULL; + for (chn = 0; chn < n_playback; chn++) + { + snprintf (buf, sizeof(buf) - 1, "playback_%u", chn+1); + + port = jack_port_register (client, buf, + JACK_DEFAULT_AUDIO_TYPE, + port_flags, 0); + + if (!port) + { + printf( "jacknet_client: cannot register port for %s", buf); + break; + } + + playback_srcs = jack_slist_append( playback_srcs, src_new( 4-samplerate_quality, 1, NULL ) ); + playback_ports = jack_slist_append (playback_ports, port); + } +} + +/** + * This is the shutdown callback for this JACK application. + * It is called by JACK if the server ever shuts down or + * decides to disconnect the client. + */ + +void jack_shutdown (void *arg) { + + exit (1); +} + +/** + * be user friendly. + * be user friendly. + * be user friendly. + */ + +void printUsage() { +fprintf(stderr, "usage: alsa_out [options]\n" + "\n" + " -j - client name\n" + " -d \n" + " -c \n" + " -p \n" + " -n \n" + " -r \n" + " -q \n" + " -t \n" + " -i turns on instrumentation\n" + " -v turns on printouts\n" + "\n"); +} + + +/** + * the main function.... + */ + +void +sigterm_handler( int signal ) +{ + quit = 1; +} + + +int main (int argc, char *argv[]) { + char jack_name[30] = "alsa_out"; + char alsa_device[30] = "hw:0"; + + extern char *optarg; + extern int optind, optopt; + int errflg=0; + int c; + + while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:")) != -1) { + switch(c) { + case 'j': + strcpy(jack_name,optarg); + break; + case 'r': + sample_rate = atoi(optarg); + break; + case 'c': + num_channels = atoi(optarg); + break; + case 'p': + period_size = atoi(optarg); + break; + case 'n': + num_periods = atoi(optarg); + break; + case 'd': + strcpy(alsa_device,optarg); + break; + case 't': + target_delay = atoi(optarg); + break; + case 'q': + samplerate_quality = atoi(optarg); + break; + case 'm': + max_diff = atoi(optarg); + break; + case 'f': + catch_factor = atoi(optarg); + break; + case 'F': + catch_factor2 = atoi(optarg); + break; + case 'C': + pclamp = (double) atoi(optarg); + break; + case 'Q': + controlquant = (double) atoi(optarg); + break; + case 'v': + verbose = 1; + break; + case 'i': + instrument = 1; + break; + case 's': + smooth_size = atoi(optarg); + break; + case ':': + fprintf(stderr, + "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + fprintf(stderr, + "Unrecognized option: -%c\n", optopt); + errflg++; + } + } + if (errflg) { + printUsage(); + exit(2); + } + + if( (samplerate_quality < 0) || (samplerate_quality > 4) ) { + fprintf (stderr, "invalid samplerate quality\n"); + return 1; + } + if ((client = jack_client_open (jack_name, 0, NULL)) == 0) { + fprintf (stderr, "jack server not running?\n"); + return 1; + } + + /* tell the JACK server to call `process()' whenever + there is work to be done. + */ + + jack_set_process_callback (client, process, 0); + + /* tell the JACK server to call `jack_shutdown()' if + it ever shuts down, either entirely, or if it + just decides to stop calling us. + */ + + jack_on_shutdown (client, jack_shutdown, 0); + + + // get jack sample_rate + + jack_sample_rate = jack_get_sample_rate( client ); + + if( !sample_rate ) + sample_rate = jack_sample_rate; + + static_resample_factor = (double) sample_rate / (double) jack_sample_rate; + resample_mean = static_resample_factor; + + offset_array = malloc( sizeof(double) * smooth_size ); + if( offset_array == NULL ) { + fprintf( stderr, "no memory for offset_array !!!\n" ); + exit(20); + } + window_array = malloc( sizeof(double) * smooth_size ); + if( window_array == NULL ) { + fprintf( stderr, "no memory for window_array !!!\n" ); + exit(20); + } + int i; + for( i=0; i target_delay ) { + fprintf( stderr, "target_delay (%d) cant be smaller than max_diff(%d)\n", target_delay, max_diff ); + exit(20); + } + if( (target_delay+max_diff) > (num_periods*period_size) ) { + fprintf( stderr, "target_delay+max_diff (%d) cant be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size ); + exit(20); + } + // now open the alsa fd... + alsa_handle = open_audiofd( alsa_device, 0, sample_rate, num_channels, period_size, num_periods); + if( alsa_handle == 0 ) + exit(20); + + printf( "selected sample format: %s\n", formats[format].name ); + + // alloc input ports, which are blasted out to alsa... + alloc_ports( 0, num_channels ); + + + /* tell the JACK server that we are ready to roll */ + + if (jack_activate (client)) { + fprintf (stderr, "cannot activate client"); + return 1; + } + + signal( SIGTERM, sigterm_handler ); + signal( SIGINT, sigterm_handler ); + + if( verbose ) { + while(!quit) { + usleep(500000); + if( output_new_delay ) { + printf( "delay = %d\n", output_new_delay ); + output_new_delay = 0; + } + printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset ); + } + } else if( instrument ) { + printf( "# n\tresamp\tdiff\toffseti\tintegral\n"); + int n=0; + while(!quit) { + usleep(1000); + printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral ); + } + } else { + while(!quit) + { + usleep(500000); + if( output_new_delay ) { + printf( "delay = %d\n", output_new_delay ); + output_new_delay = 0; + } + } + } + + jack_deactivate( client ); + jack_client_close (client); + exit (0); +} + diff --git a/example-clients/bufsize.c b/example-clients/bufsize.c index d867a9ea..72a0f9e8 100644 --- a/example-clients/bufsize.c +++ b/example-clients/bufsize.c @@ -30,6 +30,7 @@ char *package; /* program name */ jack_client_t *client; jack_nframes_t nframes; +int just_print_bufsize=0; void jack_shutdown(void *arg) { @@ -54,6 +55,10 @@ void parse_arguments(int argc, char *argv[]) else package++; + if (argc==1) { + just_print_bufsize = 1; + return; + } if (argc < 2) { fprintf(stderr, "usage: %s \n", package); exit(9); @@ -74,7 +79,7 @@ int main(int argc, char *argv[]) parse_arguments(argc, argv); /* become a JACK client */ - if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { + if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { fprintf(stderr, "JACK server not running?\n"); exit(1); } @@ -86,10 +91,16 @@ int main(int argc, char *argv[]) jack_on_shutdown(client, jack_shutdown, 0); - rc = jack_set_buffer_size(client, nframes); - if (rc) - fprintf(stderr, "jack_set_buffer_size(): %s\n", strerror(rc)); - + if (just_print_bufsize) { + fprintf(stdout, "%d\n", jack_get_buffer_size( client ) ); + rc=0; + } + else + { + rc = jack_set_buffer_size(client, nframes); + if (rc) + fprintf(stderr, "jack_set_buffer_size(): %s\n", strerror(rc)); + } jack_client_close(client); return rc; diff --git a/example-clients/internal_metro.cpp b/example-clients/internal_metro.cpp index 6591ec7c..59806c74 100644 --- a/example-clients/internal_metro.cpp +++ b/example-clients/internal_metro.cpp @@ -57,7 +57,7 @@ InternalMetro::InternalMetro(int freq, double max_amp, int dur_arg, int bpm, cha client_name = (char *) malloc (9 * sizeof (char)); strcpy (client_name, "metro"); } - if ((client = jack_client_new (client_name)) == 0) { + if ((client = jack_client_open (client_name, JackNullOption, NULL)) == 0) { fprintf (stderr, "jack server not running?\n"); return ; } diff --git a/example-clients/netsource.c b/example-clients/netsource.c new file mode 100644 index 00000000..ed4c1af0 --- /dev/null +++ b/example-clients/netsource.c @@ -0,0 +1,780 @@ +/* +NetJack Client + +Copyright (C) 2008 Marc-Olivier Barre +Copyright (C) 2008 Pieter Palmers +Copyright (C) 2006 Torben Hohn + +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. + +*/ + +/** @file netsource.c + * + * @brief This client connects a remote slave JACK to a local JACK server assumed to be the master + */ + + +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#endif + +/* These two required by FreeBSD. */ +#include + + +#include + +//#include +#include +#if HAVE_SAMPLERATE +#include +#endif + +#if HAVE_CELT +#include +#endif + +#include + +JSList *capture_ports = NULL; +JSList *capture_srcs = NULL; +int capture_channels = 0; +int capture_channels_audio = 2; +int capture_channels_midi = 1; +JSList *playback_ports = NULL; +JSList *playback_srcs = NULL; +int playback_channels = 0; +int playback_channels_audio = 2; +int playback_channels_midi = 1; +int dont_htonl_floats = 0; + +int latency = 5; +jack_nframes_t factor = 1; +int bitdepth = 0; +int mtu = 1400; +int reply_port = 0; +int bind_port = 0; +int redundancy = 1; +jack_client_t *client; + +int state_connected = 0; +int state_latency = 0; +int state_netxruns = 0; +int state_currentframe = 0; +int state_recv_packet_queue_time = 0; + +int quit=0; + + +int outsockfd; +int insockfd; +#ifdef WIN32 +struct sockaddr_in destaddr; +struct sockaddr_in bindaddr; +#else +struct sockaddr destaddr; +struct sockaddr bindaddr; +#endif + +int sync_state; +jack_transport_state_t last_transport_state; + +int framecnt = 0; + +int cont_miss = 0; + +int freewheeling = 0; + +/** + * This Function allocates all the I/O Ports which are added the lists. + */ +void +alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi) +{ + + int port_flags = JackPortIsOutput; + int chn; + jack_port_t *port; + char buf[32]; + + capture_ports = NULL; + /* Allocate audio capture channels */ + for (chn = 0; chn < n_capture_audio; chn++) + { + snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); + port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); + if (!port) + { + printf( "jack_netsource: cannot register %s port\n", buf); + break; + } + if( bitdepth == 1000 ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); + capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); + capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL)); +#endif + } + capture_ports = jack_slist_append (capture_ports, port); + } + + /* Allocate midi capture channels */ + for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) + { + snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); + port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); + if (!port) + { + printf ("jack_netsource: cannot register %s port\n", buf); + break; + } + capture_ports = jack_slist_append(capture_ports, port); + } + + /* Allocate audio playback channels */ + port_flags = JackPortIsInput; + playback_ports = NULL; + for (chn = 0; chn < n_playback_audio; chn++) + { + snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); + port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); + if (!port) + { + printf ("jack_netsource: cannot register %s port\n", buf); + break; + } + if( bitdepth == 1000 ) { +#if HAVE_CELT +#if HAVE_CELT_API_0_7 + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); + playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); +#else + CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); + playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); +#endif +#endif + } else { +#if HAVE_SAMPLERATE + playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL)); +#endif + } + playback_ports = jack_slist_append (playback_ports, port); + } + + /* Allocate midi playback channels */ + for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) + { + snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); + port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); + if (!port) + { + printf ("jack_netsource: cannot register %s port\n", buf); + break; + } + playback_ports = jack_slist_append (playback_ports, port); + } +} + +/** + * The Sync callback... sync state is set elsewhere... + * we will see if this is working correctly. + * i dont really believe in it yet. + */ +int +sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg) +{ + static int latency_count = 0; + int retval = sync_state; + + if (latency_count) { + latency_count--; + retval = 0; + } + + else if (state == JackTransportStarting && last_transport_state != JackTransportStarting) + { + retval = 0; + latency_count = latency - 1; + } + + last_transport_state = state; + return retval; +} + +void +freewheel_cb (int starting, void *arg) +{ + freewheeling = starting; +} + + int deadline_goodness=0; +/** + * The process callback for this JACK application. + * It is called by JACK at the appropriate times. + */ +int +process (jack_nframes_t nframes, void *arg) +{ + jack_nframes_t net_period; + int rx_bufsize, tx_bufsize; + + jack_default_audio_sample_t *buf; + jack_port_t *port; + JSList *node; + int chn; + int size, i; + const char *porttype; + int input_fd; + + jack_position_t local_trans_pos; + + uint32_t *packet_buf, *packet_bufX; + uint32_t *rx_packet_ptr; + jack_time_t packet_recv_timestamp; + + if( bitdepth == 1000 ) + net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; + else + net_period = (float) nframes / (float) factor; + + rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); + tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header); + + + /* Allocate a buffer where both In and Out Buffer will fit */ + packet_buf = alloca ((rx_bufsize > tx_bufsize) ? rx_bufsize : tx_bufsize); + + jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf; + + /* + * for latency==0 we need to send out the packet before we wait on the reply. + * but this introduces a cycle of latency, when netsource is connected to itself. + * so we send out before read only in zero latency mode. + * + */ + + if( latency == 0 ) { + /* reset packet_bufX... */ + packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + + /* ---------- Send ---------- */ + render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, + packet_bufX, net_period, dont_htonl_floats); + + /* fill in packet hdr */ + pkthdr->transport_state = jack_transport_query (client, &local_trans_pos); + pkthdr->transport_frame = local_trans_pos.frame; + pkthdr->framecnt = framecnt; + pkthdr->latency = latency; + pkthdr->reply_port = reply_port; + pkthdr->sample_rate = jack_get_sample_rate (client); + pkthdr->period_size = nframes; + + /* playback for us is capture on the other side */ + pkthdr->capture_channels_audio = playback_channels_audio; + pkthdr->playback_channels_audio = capture_channels_audio; + pkthdr->capture_channels_midi = playback_channels_midi; + pkthdr->playback_channels_midi = capture_channels_midi; + pkthdr->mtu = mtu; + if( freewheeling!= 0 ) + pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; + else + pkthdr->sync_state = (jack_nframes_t)deadline_goodness; + //printf("goodness=%d\n", deadline_goodness ); + + packet_header_hton (pkthdr); + if (cont_miss < 3*latency+5) { + int r; + for( r=0; r 50+5*latency) + { + state_connected = 0; + packet_cache_reset_master_address( global_packcache ); + //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); + cont_miss = 0; + } + } + + /* + * ok... now the RECEIVE code. + * + */ + + /* reset packet_bufX... */ + packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + + if( reply_port ) + input_fd = insockfd; + else + input_fd = outsockfd; + + // for latency == 0 we can poll. + if( (latency == 0) || (freewheeling!=0) ) { + jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client); + // Now loop until we get the right packet. + while(1) { + jack_nframes_t got_frame; + if ( ! netjack_poll_deadline( input_fd, deadline ) ) + break; + + packet_cache_drain_socket(global_packcache, input_fd); + + if (packet_cache_get_next_available_framecnt( global_packcache, framecnt - latency, &got_frame )) + if( got_frame == (framecnt - latency) ) + break; + } + } else { + // normally: + // only drain socket. + packet_cache_drain_socket(global_packcache, input_fd); + } + + size = packet_cache_retreive_packet_pointer( global_packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); + /* First alternative : we received what we expected. Render the data + * to the JACK ports so it can be played. */ + if (size == rx_bufsize) + { + packet_buf = rx_packet_ptr; + pkthdr = (jacknet_packet_header *) packet_buf; + packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + // calculate how much time there would have been, if this packet was sent at the deadline. + + int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp); + packet_header_ntoh (pkthdr); + deadline_goodness = recv_time_offset - (int)pkthdr->latency; + //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset ); + + if (cont_miss) + { + //printf("Frame %d \tRecovered from dropouts\n", framecnt); + cont_miss = 0; + } + render_payload_to_jack_ports (bitdepth, packet_bufX, net_period, + capture_ports, capture_srcs, nframes, dont_htonl_floats); + + state_currentframe = framecnt; + state_recv_packet_queue_time = recv_time_offset; + state_connected = 1; + sync_state = pkthdr->sync_state; + packet_cache_release_packet( global_packcache, framecnt - latency ); + } + /* Second alternative : we've received something that's not + * as big as expected or we missed a packet. We render silence + * to the ouput ports */ + else + { + jack_nframes_t latency_estimate; + if( packet_cache_find_latency( global_packcache, framecnt, &latency_estimate ) ) + //if( (state_latency == 0) || (latency_estimate < state_latency) ) + state_latency = latency_estimate; + + // Set the counters up. + state_currentframe = framecnt; + //state_latency = framecnt - pkthdr->framecnt; + state_netxruns += 1; + + //printf ("Frame %d \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size); + //printf ("Frame %d \tPacket missed or incomplete\n", framecnt); + cont_miss += 1; + chn = 0; + node = capture_ports; + while (node != NULL) + { + port = (jack_port_t *) node->data; + buf = jack_port_get_buffer (port, nframes); + porttype = jack_port_type (port); + if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0) + for (i = 0; i < nframes; i++) + buf[i] = 0.0; + else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0) + jack_midi_clear_buffer (buf); + node = jack_slist_next (node); + chn++; + } + } + if( latency != 0 ) { + /* reset packet_bufX... */ + packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + + /* ---------- Send ---------- */ + render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, + packet_bufX, net_period, dont_htonl_floats); + + /* fill in packet hdr */ + pkthdr->transport_state = jack_transport_query (client, &local_trans_pos); + pkthdr->transport_frame = local_trans_pos.frame; + pkthdr->framecnt = framecnt; + pkthdr->latency = latency; + pkthdr->reply_port = reply_port; + pkthdr->sample_rate = jack_get_sample_rate (client); + pkthdr->period_size = nframes; + + /* playback for us is capture on the other side */ + pkthdr->capture_channels_audio = playback_channels_audio; + pkthdr->playback_channels_audio = capture_channels_audio; + pkthdr->capture_channels_midi = playback_channels_midi; + pkthdr->playback_channels_midi = capture_channels_midi; + pkthdr->mtu = mtu; + if( freewheeling!= 0 ) + pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; + else + pkthdr->sync_state = (jack_nframes_t)deadline_goodness; + //printf("goodness=%d\n", deadline_goodness ); + + packet_header_hton (pkthdr); + if (cont_miss < 3*latency+5) { + int r; + for( r=0; r 50+5*latency) + { + state_connected = 0; + packet_cache_reset_master_address( global_packcache ); + //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); + cont_miss = 0; + } + } + + framecnt++; + return 0; +} + +/** + * This is the shutdown callback for this JACK application. + * It is called by JACK if the server ever shuts down or + * decides to disconnect the client. + */ + +void +jack_shutdown (void *arg) +{ + exit (1); +} + +void +init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port) +{ + name->sin_family = AF_INET ; + name->sin_port = htons (port); + if (hostname) + { + struct hostent *hostinfo = gethostbyname (hostname); + if (hostinfo == NULL) { + fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname); + fflush( stderr ); + } +#ifdef WIN32 + name->sin_addr.s_addr = inet_addr( hostname ); +#else + name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; +#endif + } + else + name->sin_addr.s_addr = htonl (INADDR_ANY) ; + +} + +void +printUsage () +{ +fprintf (stderr, "usage: jack_netsource [options]\n" + "\n" + " -h this help text\n" + " -H - Host name of the slave JACK\n" + " -o - Number of audio playback channels\n" + " -i - Number of audio capture channels\n" + " -O - Number of midi playback channels\n" + " -I - Number of midi capture channels\n" + " -n - Network latency in JACK periods\n" + " -p - UDP port that the slave is listening on\n" + " -r - UDP port that we are listening on\n" + " -B - reply port, for use in NAT environments\n" + " -b - Set transport to use 16bit or 8bit\n" + " -c - Use CELT encoding with kbits per channel\n" + " -m - Assume this mtu for the link\n" + " -R - Redundancy: send out packets N times.\n" + " -e - skip host-to-network endianness conversion\n" + " -N - Reports a different name to jack\n" + " -s - The name of the local jack server\n" + "\n"); +} + +void +sigterm_handler( int signal ) +{ + quit = 1; +} + +int +main (int argc, char *argv[]) +{ + /* Some startup related basics */ + char *client_name, *server_name = NULL, *peer_ip; + int peer_port = 3000; + jack_options_t options = JackNullOption; + jack_status_t status; +#ifdef WIN32 + WSADATA wsa; + int rc = WSAStartup(MAKEWORD(2,0),&wsa); +#endif + /* Torben's famous state variables, aka "the reporting API" ! */ + /* heh ? these are only the copies of them ;) */ + int statecopy_connected, statecopy_latency, statecopy_netxruns; + jack_nframes_t net_period; + /* Argument parsing stuff */ + extern char *optarg; + extern int optind, optopt; + int errflg=0, c; + + if (argc < 3) + { + printUsage (); + return 1; + } + + client_name = (char *) malloc (sizeof (char) * 10); + peer_ip = (char *) malloc (sizeof (char) * 10); + sprintf(client_name, "netjack"); + sprintf(peer_ip, "localhost"); + + while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1) + { + switch (c) + { + case 'h': + printUsage(); + exit (0); + break; + case 'H': + free(peer_ip); + peer_ip = (char *) malloc (sizeof (char) * strlen (optarg)+1); + strcpy (peer_ip, optarg); + break; + case 'o': + playback_channels_audio = atoi (optarg); + break; + case 'i': + capture_channels_audio = atoi (optarg); + break; + case 'O': + playback_channels_midi = atoi (optarg); + break; + case 'I': + capture_channels_midi = atoi (optarg); + break; + case 'n': + latency = atoi (optarg); + break; + case 'p': + peer_port = atoi (optarg); + break; + case 'r': + reply_port = atoi (optarg); + break; + case 'B': + bind_port = atoi (optarg); + break; + case 'f': + factor = atoi (optarg); + printf("This feature is deprecated and will be removed in future netjack versions. CELT offers a superiour way to conserve bandwidth"); + break; + case 'b': + bitdepth = atoi (optarg); + break; + case 'c': +#if HAVE_CELT + bitdepth = 1000; + factor = atoi (optarg); +#else + printf( "not built with celt supprt\n" ); + exit(10); +#endif + break; + case 'm': + mtu = atoi (optarg); + break; + case 'R': + redundancy = atoi (optarg); + break; + case 'e': + dont_htonl_floats = 1; + break; + case 'N': + free(client_name); + client_name = (char *) malloc (sizeof (char) * strlen (optarg)+1); + strcpy (client_name, optarg); + break; + case 's': + server_name = (char *) malloc (sizeof (char) * strlen (optarg)+1); + strcpy (server_name, optarg); + options |= JackServerName; + break; + case ':': + fprintf (stderr, "Option -%c requires an operand\n", optopt); + errflg++; + break; + case '?': + fprintf (stderr, "Unrecognized option: -%c\n", optopt); + errflg++; + } + } + if (errflg) + { + printUsage (); + exit (2); + } + + capture_channels = capture_channels_audio + capture_channels_midi; + playback_channels = playback_channels_audio + playback_channels_midi; + + outsockfd = socket (AF_INET, SOCK_DGRAM, 0); + insockfd = socket (AF_INET, SOCK_DGRAM, 0); + + if( (outsockfd == -1) || (insockfd == -1) ) { + fprintf (stderr, "cant open sockets\n" ); + return 1; + } + + init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port); + if(bind_port) { + init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port); + if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) { + fprintf (stderr, "bind failure\n" ); + } + } + if(reply_port) + { + init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); + if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { + fprintf (stderr, "bind failure\n" ); + } + } + + /* try to become a client of the JACK server */ + client = jack_client_open (client_name, options, &status, server_name); + if (client == NULL) + { + fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n" + "Is the JACK server running ?\n", status); + return 1; + } + + /* Set up jack callbacks */ + jack_set_process_callback (client, process, 0); + jack_set_sync_callback (client, sync_cb, 0); + jack_set_freewheel_callback (client, freewheel_cb, 0); + jack_on_shutdown (client, jack_shutdown, 0); + + alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi); + + if( bitdepth == 1000 ) + net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; + else + net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); + + int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); + global_packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); + + /* tell the JACK server that we are ready to roll */ + if (jack_activate (client)) + { + fprintf (stderr, "Cannot activate client"); + return 1; + } + + /* Now sleep forever... and evaluate the state_ vars */ + + signal( SIGTERM, sigterm_handler ); + signal( SIGINT, sigterm_handler ); + + statecopy_connected = 2; // make it report unconnected on start. + statecopy_latency = state_latency; + statecopy_netxruns = state_netxruns; + + while ( !quit ) + { +#ifdef WIN32 + Sleep (1000); +#else + sleep(1); +#endif + if (statecopy_connected != state_connected) + { + statecopy_connected = state_connected; + if (statecopy_connected) + { + state_netxruns = 1; // We want to reset the netxrun count on each new connection + printf ("Connected :-)\n"); + } + else + printf ("Not Connected\n"); + + fflush(stdout); + } + + if (statecopy_connected) + { + if (statecopy_netxruns != state_netxruns) { + statecopy_netxruns = state_netxruns; + printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", + client_name, + state_currentframe, + statecopy_netxruns, + 100*statecopy_netxruns/state_currentframe, + state_recv_packet_queue_time); + + fflush(stdout); + } + } + else + { + if (statecopy_latency != state_latency) + { + statecopy_latency = state_latency; + if (statecopy_latency > 1) + printf ("current latency %d\n", statecopy_latency); + fflush(stdout); + } + } + } + + jack_client_close (client); + packet_cache_free (global_packcache); + exit (0); +} diff --git a/example-clients/samplerate.c b/example-clients/samplerate.c new file mode 100644 index 00000000..e8b77ecd --- /dev/null +++ b/example-clients/samplerate.c @@ -0,0 +1,85 @@ +/* + * smaplerate.c -- get current samplerate + * + * Copyright (C) 2003 Jack O'Quin. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +char *package; /* program name */ +jack_client_t *client; + +void jack_shutdown(void *arg) +{ + fprintf(stderr, "JACK shut down, exiting ...\n"); + exit(1); +} + +void signal_handler(int sig) +{ + jack_client_close(client); + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); +} + +void parse_arguments(int argc, char *argv[]) +{ + + /* basename $0 */ + package = strrchr(argv[0], '/'); + if (package == 0) + package = argv[0]; + else + package++; + + if (argc==1) { + return; + } + fprintf(stderr, "usage: %s [bufsize]\n", package); + exit(9); +} + +int main(int argc, char *argv[]) +{ + parse_arguments(argc, argv); + + /* become a JACK client */ + if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { + fprintf(stderr, "JACK server not running?\n"); + exit(1); + } + + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + + jack_on_shutdown(client, jack_shutdown, 0); + + fprintf(stdout, "%d\n", jack_get_sample_rate( client ) ); + + jack_client_close(client); + + return 0; +} diff --git a/example-clients/wait.c b/example-clients/wait.c new file mode 100644 index 00000000..81870321 --- /dev/null +++ b/example-clients/wait.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include + +#include + +#include + +char * my_name; + +void +show_usage (void) +{ + fprintf (stderr, "\nUsage: %s [options]\n", my_name); + fprintf (stderr, "Check for jack existence, or wait, until it either quits, or gets started\n"); + fprintf (stderr, "options:\n"); + fprintf (stderr, " -s, --server Connect to the jack server named \n"); + fprintf (stderr, " -w, --wait Wait for server to become available\n"); + fprintf (stderr, " -q, --quit Wait until server is quit\n"); + fprintf (stderr, " -c, --check Check wether server is running\n"); + fprintf (stderr, " -t, --timeout Wait timeout in seconds\n"); + fprintf (stderr, " -h, --help Display this help message\n"); + fprintf (stderr, "For more information see http://jackaudio.org/\n"); +} + +int +main (int argc, char *argv[]) +{ + jack_client_t *client; + jack_status_t status; + jack_options_t options = JackNoStartServer; + int c; + int option_index; + char *server_name = NULL; + int wait_for_start = 0; + int wait_for_quit = 0; + int just_check = 0; + int wait_timeout = 0; + time_t start_timestamp; + + + struct option long_options[] = { + { "server", 1, 0, 's' }, + { "wait", 0, 0, 'w' }, + { "quit", 0, 0, 'q' }, + { "check", 0, 0, 'c' }, + { "timeout", 1, 0, 't' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } + }; + + my_name = strrchr(argv[0], '/'); + if (my_name == 0) { + my_name = argv[0]; + } else { + my_name ++; + } + + while ((c = getopt_long (argc, argv, "s:wqct:hv", long_options, &option_index)) >= 0) { + switch (c) { + case 's': + server_name = (char *) malloc (sizeof (char) * strlen(optarg)); + strcpy (server_name, optarg); + options |= JackServerName; + break; + case 'w': + wait_for_start = 1; + break; + case 'q': + wait_for_quit = 1; + break; + case 'c': + just_check = 1; + break; + case 't': + wait_timeout = atoi(optarg); + break; + case 'h': + show_usage (); + return 1; + break; + default: + show_usage (); + return 1; + break; + } + } + + /* try to open server in a loop. breaking under certein conditions */ + + start_timestamp = time( NULL ); + + while(1) { + client = jack_client_open ("wait", options, &status, server_name); + /* check for some real error and bail out */ + if( (client == NULL) && !(status & JackServerFailed) ) { + fprintf (stderr, "jack_client_open() failed, " + "status = 0x%2.0x\n", status); + return 1; + } + + if( client == NULL ) { + if( wait_for_quit ) { + fprintf( stdout, "server is gone\n" ); + break; + } + if( just_check ) { + fprintf( stdout, "not running\n" ); + break; + } + } else { + jack_client_close( client ); + if( wait_for_start ) { + fprintf( stdout, "server is available\n" ); + break; + } + if( just_check ) { + fprintf( stdout, "running\n" ); + break; + } + } + if( wait_timeout ) { + if( (time( NULL ) - start_timestamp) > wait_timeout ) { + fprintf( stdout, "timeout\n" ); + break; + } + } + + // Wait a second, and repeat + sleep(1); + } + + exit (0); +} diff --git a/example-clients/wscript b/example-clients/wscript index 3906cfd2..04cc9c4f 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -16,6 +16,8 @@ example_programs = { 'jack_showtime' : 'showtime.c', 'jack_alias' : 'alias.c', 'jack_bufsize' : 'bufsize.c', + 'jack_wait' : 'wait.c', + 'jack_samplerate' : 'samplerate.c', 'jack_evmon' : 'evmon.c', 'jack_monitor_client' : 'monitor_client.c', 'jack_thru' : 'thru_client.c', @@ -30,9 +32,16 @@ example_libs = { def configure(conf): e = conf.check_cc(header_name='sndfile.h', define_name="HAVE_SNDFILE") + conf.check_cc(header_name='samplerate.h', define_name="HAVE_SAMPLERATE") + + if conf.is_defined('HAVE_SAMPLERATE'): + conf.env['LIB_SAMPLERATE'] = ['samplerate'] + if conf.is_defined('HAVE_SNDFILE'): conf.env['LIB_SNDFILE'] = ['sndfile'] + conf.check_cfg(package='celt', atleast_version='0.5.0', args='--cflags --libs') + e = conf.check_cc(header_name='ncurses.h', define_name="HAVE_NCURSES") if conf.is_defined('HAVE_NCURSES'): @@ -47,6 +56,8 @@ def configure(conf): conf.env['BUILD_EXAMPLE_CLIENT_REC'] = conf.is_defined('HAVE_SNDFILE') + conf.env['BUILD_EXAMPLE_ALSA_IO'] = conf.is_defined('HAVE_SAMPLERATE') + def build(bld): if bld.env['IS_LINUX']: os_incdir = ['../linux', '../posix'] @@ -73,8 +84,7 @@ def build(bld): prog.uselib_local = 'clientlib' prog.target = example_program - #if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] - if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] == True: + if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT']: prog = bld.new_task_gen('cc', 'program') prog.includes = os_incdir + ['../common/jack', '../common'] prog.source = 'transport.c' @@ -89,7 +99,7 @@ def build(bld): prog.uselib_local = 'clientlib' prog.target = 'jack_transport' - if bld.env['BUILD_EXAMPLE_CLIENT_REC'] == True: + if bld.env['BUILD_EXAMPLE_CLIENT_REC']: prog = bld.new_task_gen('cc', 'program') prog.includes = os_incdir + ['../common/jack', '../common'] prog.source = 'capture_client.c' @@ -105,6 +115,38 @@ def build(bld): prog.uselib_local = 'clientlib' prog.target = 'jack_rec' + if bld.env['IS_LINUX'] or bld.env['IS_MACOSX']: + prog = bld.new_task_gen('cc', 'program') + prog.includes = os_incdir + ['../common/jack', '../common'] + prog.source = ['netsource.c', '../common/netjack_packet.c'] + prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") + # Seems uneeded here... + #if bld.env['HAVE_CELT']: + #if bld.env['HAVE_CELT_API_0_5']: + # prog.defines = ['HAVE_CELT', 'HAVE_CELT_API_0_5'] + #elif bld.env['HAVE_CELT_API_0_7']: + # prog.defines = ['HAVE_CELT', 'HAVE_CELT_API_0_7'] + prog.uselib = 'CELT SAMPLERATE' + prog.uselib_local = 'clientlib' + prog.target = 'jack_netsource' + + if bld.env['IS_LINUX'] and bld.env['BUILD_EXAMPLE_ALSA_IO']: + prog = bld.new_task_gen('cc', 'program') + prog.includes = os_incdir + ['../common/jack', '../common'] + prog.source = ['alsa_in.c', '../common/memops.c'] + prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") + prog.uselib = 'ALSA SAMPLERATE' + prog.uselib_local = 'clientlib' + prog.target = 'alsa_in' + + prog = bld.new_task_gen('cc', 'program') + prog.includes = os_incdir + ['../common/jack', '../common'] + prog.source = ['alsa_out.c', '../common/memops.c'] + prog.env.append_value("CCFLAGS", "-DNO_JACK_ERROR") + prog.uselib = 'ALSA SAMPLERATE' + prog.uselib_local = 'clientlib' + prog.target = 'alsa_out' + for example_lib, example_lib_source in example_libs.items(): lib = bld.new_task_gen('cc', 'shlib') lib.env['shlib_PATTERN'] = '%s.so' diff --git a/example-clients/zombie.c b/example-clients/zombie.c index 0d3943c4..a3a2dadd 100644 --- a/example-clients/zombie.c +++ b/example-clients/zombie.c @@ -52,9 +52,8 @@ int main (int argc, char *argv[]) { jack_client_t* client = NULL; - /* try to become a client of the JACK server */ - if ((client = jack_client_new ("zombie")) == 0) { + if ((client = jack_client_open ("zombie", JackNullOption, NULL)) == 0) { fprintf (stderr, "jack server not running?\n"); goto error; } diff --git a/linux/wscript b/linux/wscript index 8e12b8ad..56a77330 100644 --- a/linux/wscript +++ b/linux/wscript @@ -11,11 +11,14 @@ def configure(conf): conf. check_cfg(package='libffado', atleast_version='1.999.17', args='--cflags --libs') conf.env['BUILD_DRIVER_FFADO'] = conf.is_defined('HAVE_LIBFFADO') + conf.define('HAVE_PPOLL', 1 ) + + def create_jack_driver_obj(bld, target, sources, uselib = None): driver = bld.new_task_gen('cxx', 'shlib') driver.features.append('cc') driver.env['shlib_PATTERN'] = 'jack_%s.so' - driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] + driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE', 'HAVE_PPOLL'] driver.includes = ['.', '../linux', '../posix', '../common', '../common/jack', '../dbus'] driver.target = target driver.source = sources @@ -64,3 +67,8 @@ def build(bld): create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') create_jack_driver_obj(bld, 'loopback', '../common/JackLoopbackDriver.cpp') + + create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp', + '../common/netjack.c', + '../common/netjack_packet.c' ], "SAMPLERATE CELT" ) + diff --git a/macosx/JackMacEngineRPC.cpp b/macosx/JackMacEngineRPC.cpp index 7d28b619..4ddb0b1c 100644 --- a/macosx/JackMacEngineRPC.cpp +++ b/macosx/JackMacEngineRPC.cpp @@ -59,12 +59,12 @@ rpc_type server_rpc_jack_client_close(mach_port_t private_port, int refnum, int* return KERN_SUCCESS; } -rpc_type server_rpc_jack_client_activate(mach_port_t private_port, int refnum, int state, int* result) +rpc_type server_rpc_jack_client_activate(mach_port_t private_port, int refnum, int is_real_time, int* result) { jack_log("rpc_jack_client_activate"); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); - *result = channel->GetEngine()->ClientActivate(refnum, state); + *result = channel->GetEngine()->ClientActivate(refnum, is_real_time); return KERN_SUCCESS; } @@ -83,7 +83,7 @@ rpc_type server_rpc_jack_client_deactivate(mach_port_t private_port, int refnum, 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, unsigned int* port_index, int* result) { - jack_log("rpc_jack_port_register ref = %ld name = %s", refnum, name); + jack_log("rpc_jack_port_register ref = %d name = %s", refnum, name); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); *result = channel->GetEngine()->PortRegister(refnum, name, type, flags, buffer_size, port_index); @@ -92,7 +92,7 @@ rpc_type server_rpc_jack_port_register(mach_port_t private_port, int refnum, cli rpc_type server_rpc_jack_port_unregister(mach_port_t private_port, int refnum, int port, int* result) { - jack_log("rpc_jack_port_unregister ref = %ld port = %ld ", refnum, port); + jack_log("rpc_jack_port_unregister ref = %d port = %d ", refnum, port); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); *result = channel->GetEngine()->PortUnRegister(refnum, port); @@ -234,7 +234,7 @@ rpc_type server_rpc_jack_internal_clientunload(mach_port_t private_port, int ref rpc_type server_rpc_jack_client_rt_notify(mach_port_t server_port, int refnum, int notify, int value) { - jack_log("rpc_jack_client_rt_notify ref = %ld notify = %ld value = %ld", refnum, notify, value); + jack_log("rpc_jack_client_rt_notify ref = %d notify = %d value = %d", refnum, notify, value); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; assert(channel); assert(channel->GetServer()); diff --git a/macosx/JackMacLibClientRPC.cpp b/macosx/JackMacLibClientRPC.cpp index 07f5e51c..b70878a1 100644 --- a/macosx/JackMacLibClientRPC.cpp +++ b/macosx/JackMacLibClientRPC.cpp @@ -27,21 +27,21 @@ using namespace Jack; #define rpc_type kern_return_t // for astyle -rpc_type rpc_jack_client_sync_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, int value1, int value2, int* result) +rpc_type rpc_jack_client_sync_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, message_t message, int value1, int value2, int* result) { - jack_log("rpc_jack_client_sync_notify ref = %ld name = %s notify = %ld val1 = %ld val2 = %ld", refnum, name, notify, value1, value2); + jack_log("rpc_jack_client_sync_notify ref = %ld name = %s notify = %ld message %s val1 = %ld val2 = %ld", refnum, name, notify, message, value1, value2); JackClient* client = gClientTable[client_port]; assert(client); - *result = client->ClientNotify(refnum, name, notify, true, value1, value2); + *result = client->ClientNotify(refnum, name, notify, true, message, value1, value2); return KERN_SUCCESS; } -rpc_type rpc_jack_client_async_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, int value1, int value2) +rpc_type rpc_jack_client_async_notify(mach_port_t client_port, int refnum, client_name_t name, int notify, message_t message, int value1, int value2) { - jack_log("rpc_jack_client_async_notify ref = %ld name = %s notify = %ld val1 = %ld val2 = %ld", refnum, name, notify, value1, value2); + jack_log("rpc_jack_client_async_notify ref = %ld name = %s notify = %ld message %s val1 = %ld val2 = %ld", refnum, name, notify, message, value1, value2); JackClient* client = gClientTable[client_port]; assert(client); - client->ClientNotify(refnum, name, notify, false, value1, value2); + client->ClientNotify(refnum, name, notify, false, message, value1, value2); return KERN_SUCCESS; } diff --git a/macosx/JackMachClientChannel.cpp b/macosx/JackMachClientChannel.cpp index d3d81bdd..c666bbb3 100644 --- a/macosx/JackMachClientChannel.cpp +++ b/macosx/JackMachClientChannel.cpp @@ -154,9 +154,9 @@ void JackMachClientChannel::ClientClose(int refnum, int* result) } } -void JackMachClientChannel::ClientActivate(int refnum, int state, int* result) +void JackMachClientChannel::ClientActivate(int refnum, int is_real_time, int* result) { - kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, state, result); + kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, is_real_time, result); if (res != KERN_SUCCESS) { *result = -1; jack_error("JackMachClientChannel::ClientActivate err = %s", mach_error_string(res)); diff --git a/macosx/JackMachClientChannel.h b/macosx/JackMachClientChannel.h index 9e323cf5..379fb535 100644 --- a/macosx/JackMachClientChannel.h +++ b/macosx/JackMachClientChannel.h @@ -61,7 +61,7 @@ class JackMachClientChannel : public detail::JackClientChannelInterface, public {} void ClientClose(int refnum, int* result); - void ClientActivate(int refnum, int state, int* result); + void ClientActivate(int refnum, int is_real_time, int* result); void ClientDeactivate(int refnum, 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); diff --git a/macosx/JackMachNotifyChannel.cpp b/macosx/JackMachNotifyChannel.cpp index 86236304..56d6b425 100644 --- a/macosx/JackMachNotifyChannel.cpp +++ b/macosx/JackMachNotifyChannel.cpp @@ -49,11 +49,11 @@ void JackMachNotifyChannel::Close() fClientPort.DisconnectPort(); } -void JackMachNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result) +void JackMachNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) { kern_return_t res = (sync) - ? rpc_jack_client_sync_notify(fClientPort.GetPort(), refnum, (char*)name, notify, value1, value2, result) - : rpc_jack_client_async_notify(fClientPort.GetPort(), refnum, (char*)name, notify, value1, value2); + ? rpc_jack_client_sync_notify(fClientPort.GetPort(), refnum, (char*)name, notify, (char*)message, value1, value2, result) + : rpc_jack_client_async_notify(fClientPort.GetPort(), refnum, (char*)name, notify, (char*)message, value1, value2); if (res == KERN_SUCCESS) { *result = 0; } else { diff --git a/macosx/JackMachNotifyChannel.h b/macosx/JackMachNotifyChannel.h index 14afeb3f..ab99fef4 100644 --- a/macosx/JackMachNotifyChannel.h +++ b/macosx/JackMachNotifyChannel.h @@ -44,7 +44,7 @@ class JackMachNotifyChannel int Open(const char* name); // Open the Server/Client connection void Close(); // Close the Server/Client connection - void ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result); + void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); }; } // end of namespace diff --git a/macosx/JackMachServerChannel.cpp b/macosx/JackMachServerChannel.cpp index 84d87b93..19295f79 100644 --- a/macosx/JackMachServerChannel.cpp +++ b/macosx/JackMachServerChannel.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackServer.h" #include "JackLockedEngine.h" #include "JackNotification.h" +#include "JackServerGlobals.h" using namespace std; @@ -49,11 +50,6 @@ int JackMachServerChannel::Open(const char* server_name, JackServer* server) return -1; } - if (fThread.Start() != 0) { - jack_error("Cannot start Jack server listener"); - return -1; - } - fServer = server; fPortTable[fServerPort.GetPort()] = this; return 0; @@ -65,6 +61,16 @@ void JackMachServerChannel::Close() fThread.Kill(); fServerPort.DestroyPort(); } + +int JackMachServerChannel::Start() +{ + if (fThread.Start() != 0) { + jack_error("Cannot start Jack server listener"); + return -1; + } + + return 0; +} JackLockedEngine* JackMachServerChannel::GetEngine() { diff --git a/macosx/JackMachServerChannel.h b/macosx/JackMachServerChannel.h index 9e5ac35f..fc5a100b 100644 --- a/macosx/JackMachServerChannel.h +++ b/macosx/JackMachServerChannel.h @@ -53,7 +53,9 @@ class JackMachServerChannel : public JackRunnableInterface int Open(const char* server_name, JackServer* server); // Open the Server/Client connection void Close(); // Close the Server/Client connection - + + int Start(); + JackLockedEngine* GetEngine(); JackServer* GetServer(); @@ -64,6 +66,7 @@ class JackMachServerChannel : public JackRunnableInterface bool Execute(); + // Has to be public.. static std::map fPortTable; }; diff --git a/macosx/JackMachServerNotifyChannel.cpp b/macosx/JackMachServerNotifyChannel.cpp index ab686c57..2e1c9abe 100644 --- a/macosx/JackMachServerNotifyChannel.cpp +++ b/macosx/JackMachServerNotifyChannel.cpp @@ -50,7 +50,7 @@ void JackMachServerNotifyChannel::Notify(int refnum, int notify, int value) { kern_return_t res = rpc_jack_client_rt_notify(fClientPort.GetPort(), refnum, notify, value, 0); if (res != KERN_SUCCESS) { - jack_error("Could not write request ref = %ld notify = %ld err = %s", refnum, notify, mach_error_string(res)); + jack_error("Could not write request ref = %d notify = %d err = %s", refnum, notify, mach_error_string(res)); } } diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index 2d809c2a..9a7ed47d 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -118,13 +118,13 @@ UInt32 JackMachThread::GetThreadPriority(pthread_t thread, int inWhichPriority) return 0; } -int JackMachThread::GetParams(UInt64* period, UInt64* computation, UInt64* constraint) +int JackMachThread::GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint) { thread_time_constraint_policy_data_t theTCPolicy; mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT; boolean_t get_default = false; - kern_return_t res = thread_policy_get(pthread_mach_thread_np(pthread_self()), + kern_return_t res = thread_policy_get(pthread_mach_thread_np(thread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t) & theTCPolicy, &count, @@ -145,9 +145,11 @@ int JackMachThread::Kill() // pthread_cancel still not yet implemented in Darwin (TO CHECK ON TIGER) jack_log("JackMachThread::Kill"); - if (fThread) { // If thread has been started + if (fThread != (pthread_t)NULL) { // If thread has been started mach_port_t machThread = pthread_mach_thread_np(fThread); - return (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1; + int res = (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1; + fThread = (pthread_t)NULL; + return res; } else { return -1; } @@ -157,7 +159,14 @@ int JackMachThread::AcquireRealTime() { jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); - return (fThread) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; + return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; +} + +int JackMachThread::AcquireSelfRealTime() +{ + jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", + long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); + return AcquireRealTimeImp(pthread_self(), fPeriod, fComputation, fConstraint); } int JackMachThread::AcquireRealTime(int priority) @@ -166,19 +175,26 @@ int JackMachThread::AcquireRealTime(int priority) return AcquireRealTime(); } +int JackMachThread::AcquireSelfRealTime(int priority) +{ + fPriority = priority; + return AcquireSelfRealTime(); +} + int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint) { SetThreadToPriority(thread, 96, true, period, computation, constraint); - UInt64 int_period; - UInt64 int_computation; - UInt64 int_constraint; - GetParams(&int_period, &int_computation, &int_constraint); return 0; } int JackMachThread::DropRealTime() { - return (fThread) ? DropRealTimeImp(fThread) : -1; + return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1; +} + +int JackMachThread::DropSelfRealTime() +{ + return DropRealTimeImp(pthread_self()); } int JackMachThread::DropRealTimeImp(pthread_t thread) diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index 4e17959b..c7a44f79 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -103,11 +103,17 @@ class SERVER_EXPORT JackMachThread : public JackPosixThread int Kill(); - int AcquireRealTime(); - int AcquireRealTime(int priority); - int DropRealTime(); + int AcquireRealTime(); // Used when called from another thread + int AcquireSelfRealTime(); // Used when called from thread itself + + int AcquireRealTime(int priority); // Used when called from another thread + int AcquireSelfRealTime(int priority); // Used when called from thread itself + + int DropRealTime(); // Used when called from another thread + int DropSelfRealTime(); // Used when called from thread itself + void SetParams(UInt64 period, UInt64 computation, UInt64 constraint); - static int GetParams(UInt64* period, UInt64* computation, UInt64* constraint); + static int GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint); static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint); static int AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint); diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 53eb7be7..c8aae4f5 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ 4B35C6B20D4733B9000DE7AE /* PBXTargetDependency */, 4BDCDC2C1002036100B15929 /* PBXTargetDependency */, 4BDCDC2E1002036100B15929 /* PBXTargetDependency */, + 4B32259110A31ABA00838A8E /* PBXTargetDependency */, + 4B43A8E91014618D00E52943 /* PBXTargetDependency */, 4BDCDC301002036100B15929 /* PBXTargetDependency */, 4BDCDC39100203D500B15929 /* PBXTargetDependency */, 4BDCDC3B100203D500B15929 /* PBXTargetDependency */, @@ -44,7 +46,7 @@ 4BFA83380DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833A0DF6AB540087B4E1 /* PBXTargetDependency */, 4BFA833C0DF6AB540087B4E1 /* PBXTargetDependency */, - 4B43A8E91014618D00E52943 /* PBXTargetDependency */, + 4B32258F10A31AB400838A8E /* PBXTargetDependency */, ); name = "All Universal 32/64 bits"; productName = All; @@ -62,6 +64,7 @@ 4BF339280F8B87800080FB5B /* PBXTargetDependency */, 4B699DBC097D421700A18468 /* PBXTargetDependency */, BA222AF20DC883F3001A17F4 /* PBXTargetDependency */, + 4B32258D10A31A9D00838A8E /* PBXTargetDependency */, 4B43A8CD1014607100E52943 /* PBXTargetDependency */, 4BD624D30CBCF55700DE782F /* PBXTargetDependency */, BA222AF00DC883EF001A17F4 /* PBXTargetDependency */, @@ -86,10 +89,10 @@ 4BFA99540AAAED90009E916C /* PBXTargetDependency */, 4B363E750DEB0838001F72D9 /* PBXTargetDependency */, 4B363E770DEB0838001F72D9 /* PBXTargetDependency */, - 4B363EF20DEB0965001F72D9 /* PBXTargetDependency */, 4B363F250DEB0ABE001F72D9 /* PBXTargetDependency */, 4B363F530DEB0CFE001F72D9 /* PBXTargetDependency */, 4B363F780DEB0D85001F72D9 /* PBXTargetDependency */, + 4B32258B10A31A9000838A8E /* PBXTargetDependency */, ); name = "All Universal 32 bits"; productName = All; @@ -107,6 +110,28 @@ 4B19B31B0E2362E800DD4A82 /* JackLibSampleRateResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B30E0E2362E700DD4A82 /* JackLibSampleRateResampler.cpp */; }; 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; + 4B3224EA10A315B100838A8E /* JackNetOneDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */; }; + 4B3224EB10A315B100838A8E /* JackNetOneDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224E910A315B100838A8E /* JackNetOneDriver.h */; }; + 4B3224F010A315C400838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; + 4B3224F110A315C400838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; + 4B3224F210A315C400838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; + 4B3224F310A315C400838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; + 4B32253110A3173900838A8E /* JackNetOneDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */; }; + 4B32253210A3173A00838A8E /* JackNetOneDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224E910A315B100838A8E /* JackNetOneDriver.h */; }; + 4B32253310A3173B00838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; + 4B32253410A3173C00838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; + 4B32253510A3173D00838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; + 4B32253610A3173E00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; + 4B32256410A318E300838A8E /* netsource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B32256310A318E300838A8E /* netsource.c */; }; + 4B32256B10A318FA00838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; + 4B32256C10A318FB00838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; + 4B32256D10A318FC00838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; + 4B32256E10A318FD00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; + 4B32257D10A3195700838A8E /* netjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EE10A315C400838A8E /* netjack.c */; }; + 4B32257E10A3195800838A8E /* netjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224EF10A315C400838A8E /* netjack.h */; }; + 4B32257F10A3195900838A8E /* netjack_packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B3224EC10A315C400838A8E /* netjack_packet.c */; }; + 4B32258010A3195A00838A8E /* netjack_packet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B3224ED10A315C400838A8E /* netjack_packet.h */; }; + 4B32258110A3195B00838A8E /* netsource.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B32256310A318E300838A8E /* netsource.c */; }; 4B35C41E0D4731D1000DE7AE /* Jackdmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2250834F06A00C94B91 /* Jackdmp.cpp */; }; 4B35C4290D4731D1000DE7AE /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; 4B35C42A0D4731D1000DE7AE /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; @@ -485,6 +510,8 @@ 4B93F19E0E87998400E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; 4B93F1C00E87A35400E4ECCD /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4B93F22B0E87A72500E4ECCD /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; + 4B94334A10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B94334B10A5E666002A187F /* systemdeps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B94334910A5E666002A187F /* systemdeps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B95BCAE0D913073000F7695 /* control.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B95BCAD0D913073000F7695 /* control.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B9A25B50DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A25B60DBF8330006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; @@ -496,6 +523,117 @@ 4B9A26610DBF8ADD006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26640DBF8B14006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; 4B9A26790DBF8B88006E9FBC /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; + 4BA3393510B2E36800190E3B /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; + 4BA3393610B2E36800190E3B /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; + 4BA3393710B2E36800190E3B /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; + 4BA3393810B2E36800190E3B /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; + 4BA3393910B2E36800190E3B /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; + 4BA3393A10B2E36800190E3B /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; + 4BA3393B10B2E36800190E3B /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; + 4BA3393C10B2E36800190E3B /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; + 4BA3393D10B2E36800190E3B /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; + 4BA3393E10B2E36800190E3B /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; + 4BA3393F10B2E36800190E3B /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; + 4BA3394010B2E36800190E3B /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; + 4BA3394110B2E36800190E3B /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; + 4BA3394210B2E36800190E3B /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; + 4BA3394310B2E36800190E3B /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; + 4BA3394410B2E36800190E3B /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; + 4BA3394510B2E36800190E3B /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; + 4BA3394610B2E36800190E3B /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; + 4BA3394710B2E36800190E3B /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; + 4BA3394810B2E36800190E3B /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; + 4BA3394910B2E36800190E3B /* JackAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2290834F07D00C94B91 /* JackAudioDriver.h */; }; + 4BA3394A10B2E36800190E3B /* JackFreewheelDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B90834EEF100C94B91 /* JackFreewheelDriver.h */; }; + 4BA3394B10B2E36800190E3B /* JackThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1BD0834EEFC00C94B91 /* JackThreadedDriver.h */; }; + 4BA3394C10B2E36800190E3B /* JackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1B50834EEE400C94B91 /* JackDriver.h */; }; + 4BA3394D10B2E36800190E3B /* driver_interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B3D08C8D21C001CF041 /* driver_interface.h */; }; + 4BA3394E10B2E36800190E3B /* JackDriverLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B869B4208C8D22F001CF041 /* JackDriverLoader.h */; }; + 4BA3394F10B2E36800190E3B /* JackEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2130834F02800C94B91 /* JackEngine.h */; }; + 4BA3395010B2E36800190E3B /* JackExternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1F70834EFBD00C94B91 /* JackExternalClient.h */; }; + 4BA3395110B2E36800190E3B /* JackServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D2220834F05C00C94B91 /* JackServer.h */; }; + 4BA3395210B2E36800190E3B /* JackMachNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298908AF450200D450D4 /* JackMachNotifyChannel.h */; }; + 4BA3395310B2E36800190E3B /* JackMachServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297808AF44ED00D450D4 /* JackMachServerChannel.h */; }; + 4BA3395410B2E36800190E3B /* JackMachServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB297A08AF44ED00D450D4 /* JackMachServerNotifyChannel.h */; }; + 4BA3395510B2E36800190E3B /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; + 4BA3395610B2E36800190E3B /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; + 4BA3395710B2E36800190E3B /* JackServerGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC2168D0A444BED00BDA09F /* JackServerGlobals.h */; }; + 4BA3395810B2E36800190E3B /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395910B2E36800190E3B /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395A10B2E36800190E3B /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395B10B2E36800190E3B /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395C10B2E36800190E3B /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395D10B2E36800190E3B /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395E10B2E36800190E3B /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3395F10B2E36800190E3B /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3396010B2E36800190E3B /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; + 4BA3396110B2E36800190E3B /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; + 4BA3396210B2E36800190E3B /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3396310B2E36800190E3B /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; + 4BA3396410B2E36800190E3B /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; + 4BA3396510B2E36800190E3B /* JackNetTool.h in Headers */ = {isa = PBXBuildFile; fileRef = BA222AD70DC88268001A17F4 /* JackNetTool.h */; }; + 4BA3396610B2E36800190E3B /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BA3396710B2E36800190E3B /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; + 4BA3396810B2E36800190E3B /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; + 4BA3396910B2E36800190E3B /* JackControlAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4E9AF90E5F1090000A3278 /* JackControlAPI.h */; }; + 4BA3396A10B2E36800190E3B /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; + 4BA3396B10B2E36800190E3B /* JackEngineProfiling.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBAE40E0F42FA6100B8BD3F /* JackEngineProfiling.h */; }; + 4BA3396C10B2E36800190E3B /* JackProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BECB2F40F4451C10091B70A /* JackProcessSync.h */; }; + 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */; }; + 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BBC93B90DF9736C002DF220 /* JackWaitThreadedDriver.h */; }; + 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF284170F31B4BC00B05BE3 /* JackArgParser.h */; }; + 4BA3397210B2E36800190E3B /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; + 4BA3397310B2E36800190E3B /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; + 4BA3397410B2E36800190E3B /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; + 4BA3397510B2E36800190E3B /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; + 4BA3397610B2E36800190E3B /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; + 4BA3397710B2E36800190E3B /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; + 4BA3397810B2E36800190E3B /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; + 4BA3397910B2E36800190E3B /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; + 4BA3397A10B2E36800190E3B /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; + 4BA3397B10B2E36800190E3B /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; + 4BA3397C10B2E36800190E3B /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; + 4BA3397D10B2E36800190E3B /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; + 4BA3397E10B2E36800190E3B /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; + 4BA3397F10B2E36800190E3B /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; + 4BA3398010B2E36800190E3B /* JackAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D22A0834F07D00C94B91 /* JackAudioDriver.cpp */; }; + 4BA3398110B2E36800190E3B /* JackFreewheelDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BA0834EEF100C94B91 /* JackFreewheelDriver.cpp */; }; + 4BA3398210B2E36800190E3B /* JackThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1BE0834EEFC00C94B91 /* JackThreadedDriver.cpp */; }; + 4BA3398310B2E36800190E3B /* JackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */; }; + 4BA3398410B2E36800190E3B /* JackDriverLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B869D7F08C9CB00001CF041 /* JackDriverLoader.cpp */; }; + 4BA3398510B2E36800190E3B /* JackEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2140834F02800C94B91 /* JackEngine.cpp */; }; + 4BA3398610B2E36800190E3B /* JackExternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F80834EFBD00C94B91 /* JackExternalClient.cpp */; }; + 4BA3398710B2E36800190E3B /* JackInternalClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1ED0834EF9200C94B91 /* JackInternalClient.cpp */; }; + 4BA3398810B2E36800190E3B /* JackRPCClientUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B759076B731100D170DE /* JackRPCClientUser.c */; }; + 4BA3398910B2E36800190E3B /* JackServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D2210834F05C00C94B91 /* JackServer.cpp */; }; + 4BA3398A10B2E36800190E3B /* JackMacEngineRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */; }; + 4BA3398B10B2E36800190E3B /* JackMachNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB298808AF450200D450D4 /* JackMachNotifyChannel.cpp */; }; + 4BA3398C10B2E36800190E3B /* JackMachServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297908AF44ED00D450D4 /* JackMachServerChannel.cpp */; }; + 4BA3398D10B2E36800190E3B /* JackMachServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */; }; + 4BA3398E10B2E36800190E3B /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; + 4BA3398F10B2E36800190E3B /* JackServerAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1F50834EFB000C94B91 /* JackServerAPI.cpp */; }; + 4BA3399010B2E36800190E3B /* JackServerGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC216880A444BDE00BDA09F /* JackServerGlobals.cpp */; }; + 4BA3399110B2E36800190E3B /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; + 4BA3399210B2E36800190E3B /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; + 4BA3399310B2E36800190E3B /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; + 4BA3399410B2E36800190E3B /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; + 4BA3399510B2E36800190E3B /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; + 4BA3399610B2E36800190E3B /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; + 4BA3399710B2E36800190E3B /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; + 4BA3399810B2E36800190E3B /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; + 4BA3399910B2E36800190E3B /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BA222AD60DC88268001A17F4 /* JackNetTool.cpp */; }; + 4BA3399A10B2E36800190E3B /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; + 4BA3399B10B2E36800190E3B /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; + 4BA3399C10B2E36800190E3B /* JackRestartThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */; }; + 4BA3399D10B2E36800190E3B /* JackControlAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */; }; + 4BA3399E10B2E36800190E3B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; + 4BA3399F10B2E36800190E3B /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; + 4BA339A010B2E36800190E3B /* JackEngineProfiling.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBAE40F0F42FA6100B8BD3F /* JackEngineProfiling.cpp */; }; + 4BA339A110B2E36800190E3B /* JackProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BECB2F30F4451C10091B70A /* JackProcessSync.cpp */; }; + 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */; }; + 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC93B80DF9736C002DF220 /* JackWaitThreadedDriver.cpp */; }; + 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF284160F31B4BC00B05BE3 /* JackArgParser.cpp */; }; + 4BA339A710B2E36800190E3B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BA4ADB40E87AB2500F26C85 /* JackCoreAudioDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */; }; 4BA4ADB50E87AB2600F26C85 /* JackCoreAudioDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE5FECC0E725C090020B576 /* JackCoreAudioDriver.h */; }; 4BA692B30CBE4C2D00EAD520 /* ipload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692B20CBE4C2D00EAD520 /* ipload.c */; }; @@ -623,8 +761,8 @@ 4BF4BAB10E3480AB00403CDF /* JackAudioAdapterFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4BAB00E3480AB00403CDF /* JackAudioAdapterFactory.cpp */; }; 4BF520530CB8D0E80037470E /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 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, ); }; }; + 4BF520590CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (); }; }; + 4BF5205A0CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (); }; }; 4BF5FBBC0E878B9C003D2374 /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; 4BF5FBC90E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; 4BF5FBCA0E878D24003D2374 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; @@ -677,6 +815,41 @@ remoteGlobalIDString = 4B5E08BF0E5B66EE00BEE4E0; remoteInfo = netadapter; }; + 4B3224E610A3157900838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B3224D710A3156800838A8E; + remoteInfo = "jack_netone Universal"; + }; + 4B32258A10A31A9000838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B32255710A3187800838A8E; + remoteInfo = "jack_netsource Universal"; + }; + 4B32258C10A31A9D00838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B3224D710A3156800838A8E; + remoteInfo = "jack_netone Universal"; + }; + 4B32258E10A31AB400838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B32257110A3190C00838A8E; + remoteInfo = "jack_netsource 64 bits"; + }; + 4B32259010A31ABA00838A8E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4B32251D10A316B200838A8E; + remoteInfo = "jack_netone 64 bits"; + }; 4B35C5540D4731D2000DE7AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -845,13 +1018,6 @@ remoteGlobalIDString = 4B363E440DEB0775001F72D9; remoteInfo = "jack_bufsize Universal"; }; - 4B363EF10DEB0965001F72D9 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4B363EDF0DEB091C001F72D9; - remoteInfo = "jack_rec Universal"; - }; 4B363F240DEB0ABE001F72D9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; @@ -1197,6 +1363,17 @@ 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLibSampleRateResampler.h; path = ../common/JackLibSampleRateResampler.h; sourceTree = SOURCE_ROOT; }; 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; + 4B3224E510A3156800838A8E /* jack_netone.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_netone.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetOneDriver.cpp; path = ../common/JackNetOneDriver.cpp; sourceTree = SOURCE_ROOT; }; + 4B3224E910A315B100838A8E /* JackNetOneDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetOneDriver.h; path = ../common/JackNetOneDriver.h; sourceTree = SOURCE_ROOT; }; + 4B3224EC10A315C400838A8E /* netjack_packet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netjack_packet.c; path = ../common/netjack_packet.c; sourceTree = SOURCE_ROOT; }; + 4B3224ED10A315C400838A8E /* netjack_packet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netjack_packet.h; path = ../common/netjack_packet.h; sourceTree = SOURCE_ROOT; }; + 4B3224EE10A315C400838A8E /* netjack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netjack.c; path = ../common/netjack.c; sourceTree = SOURCE_ROOT; }; + 4B3224EF10A315C400838A8E /* netjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = netjack.h; path = ../common/netjack.h; sourceTree = SOURCE_ROOT; }; + 4B32252B10A316B200838A8E /* jack_netone.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_netone.so; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B32256110A3187800838A8E /* jack_netsource */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_netsource; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B32256310A318E300838A8E /* netsource.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = netsource.c; path = "../example-clients/netsource.c"; sourceTree = SOURCE_ROOT; }; + 4B32257B10A3190C00838A8E /* jack_netsource */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_netsource; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4250D4731D1000DE7AE /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4830D4731D1000DE7AE /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1303,12 +1480,15 @@ 4B89B759076B731100D170DE /* JackRPCClientUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCClientUser.c; path = RPC/JackRPCClientUser.c; sourceTree = SOURCE_ROOT; }; 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = JackRPCEngineUser.c; path = RPC/JackRPCEngineUser.c; sourceTree = SOURCE_ROOT; }; 4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = ""; }; + 4B94334910A5E666002A187F /* systemdeps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = systemdeps.h; path = ../common/jack/systemdeps.h; sourceTree = SOURCE_ROOT; }; 4B95BCAD0D913073000F7695 /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = ../common/jack/control.h; sourceTree = SOURCE_ROOT; }; 4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B98AE000931D30C0091932A /* JackDebugClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackDebugClient.cpp; path = ../common/JackDebugClient.cpp; sourceTree = SOURCE_ROOT; }; 4B98AE010931D30C0091932A /* JackDebugClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackDebugClient.h; path = ../common/JackDebugClient.h; sourceTree = SOURCE_ROOT; }; 4B9A25B30DBF8330006E9FBC /* JackError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackError.cpp; path = ../common/JackError.cpp; sourceTree = SOURCE_ROOT; }; 4B9A26000DBF8584006E9FBC /* jslist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jslist.h; path = ../common/jack/jslist.h; sourceTree = SOURCE_ROOT; }; + 4BA339AC10B2E36800190E3B /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BA339AD10B2E36800190E3B /* Jack-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = ""; }; 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroClient.cpp; path = ../tests/testSynchroClient.cpp; sourceTree = SOURCE_ROOT; }; 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroServer.cpp; path = ../tests/testSynchroServer.cpp; sourceTree = SOURCE_ROOT; }; 4BA692B00CBE4BC700EAD520 /* jack_load */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_load; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1498,6 +1678,34 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3224E010A3156800838A8E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32252610A316B200838A8E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32255B10A3187800838A8E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32257510A3190C00838A8E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B35C41F0D4731D1000DE7AE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1899,6 +2107,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA339A610B2E36800190E3B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BA339A710B2E36800190E3B /* Accelerate.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA692AA0CBE4BC700EAD520 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2072,6 +2288,7 @@ 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */, 1AB674ADFE9D54B511CA2CBB /* Products */, 4B464301076CAC7700E5077C /* Jack-Info.plist */, + 4BA339AD10B2E36800190E3B /* Jack-Info.plist */, ); name = JackServer; sourceTree = ""; @@ -2184,6 +2401,11 @@ 4BDCDC251001FDE300B15929 /* netadapter.so */, 4B43A8BA10145F6F00E52943 /* jack_loopback.so */, 4B43A8E71014615800E52943 /* jack_loopback.so */, + 4B3224E510A3156800838A8E /* jack_netone.so */, + 4B32252B10A316B200838A8E /* jack_netone.so */, + 4B32256110A3187800838A8E /* jack_netsource */, + 4B32257B10A3190C00838A8E /* jack_netsource */, + 4BA339AC10B2E36800190E3B /* Jackservermp.framework */, ); name = Products; sourceTree = ""; @@ -2377,6 +2599,7 @@ 4B6C73780CC60A6D001AFFD4 /* jack */ = { isa = PBXGroup; children = ( + 4B94334910A5E666002A187F /* systemdeps.h */, 4B9A26000DBF8584006E9FBC /* jslist.h */, 4B95BCAD0D913073000F7695 /* control.h */, 4B6B9EF50CD0958B0051EE5A /* midiport.h */, @@ -2678,6 +2901,13 @@ BA222AEA0DC88379001A17F4 /* Net */ = { isa = PBXGroup; children = ( + 4B32256310A318E300838A8E /* netsource.c */, + 4B3224EC10A315C400838A8E /* netjack_packet.c */, + 4B3224ED10A315C400838A8E /* netjack_packet.h */, + 4B3224EE10A315C400838A8E /* netjack.c */, + 4B3224EF10A315C400838A8E /* netjack.h */, + 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */, + 4B3224E910A315B100838A8E /* JackNetOneDriver.h */, 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */, 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */, 4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */, @@ -2732,6 +2962,44 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3224D810A3156800838A8E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B3224EB10A315B100838A8E /* JackNetOneDriver.h in Headers */, + 4B3224F110A315C400838A8E /* netjack_packet.h in Headers */, + 4B3224F310A315C400838A8E /* netjack.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32251E10A316B200838A8E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32253210A3173A00838A8E /* JackNetOneDriver.h in Headers */, + 4B32253410A3173C00838A8E /* netjack.h in Headers */, + 4B32253610A3173E00838A8E /* netjack_packet.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32255810A3187800838A8E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32256C10A318FB00838A8E /* netjack.h in Headers */, + 4B32256E10A318FD00838A8E /* netjack_packet.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32257210A3190C00838A8E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32257E10A3195800838A8E /* netjack.h in Headers */, + 4B32258010A3195A00838A8E /* netjack_packet.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B35C41C0D4731D1000DE7AE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3167,6 +3435,7 @@ 4BB9D4B30E2610B300351653 /* JackTransportEngine.h in Headers */, 4BC3B6A50E703B2E0066E42F /* JackPosixThread.h in Headers */, 4BECB2F80F4451C10091B70A /* JackProcessSync.h in Headers */, + 4B94334A10A5E666002A187F /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3236,6 +3505,7 @@ 4BBAE4100F42FA6100B8BD3F /* JackEngineProfiling.h in Headers */, 4BECB2F60F4451C10091B70A /* JackProcessSync.h in Headers */, 4BF339240F8B873E0080FB5B /* JackMidiDriver.h in Headers */, + 4B94334B10A5E666002A187F /* systemdeps.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3348,6 +3618,72 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA3393410B2E36800190E3B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BA3393510B2E36800190E3B /* JackMachPort.h in Headers */, + 4BA3393610B2E36800190E3B /* JackError.h in Headers */, + 4BA3393710B2E36800190E3B /* JackTime.h in Headers */, + 4BA3393810B2E36800190E3B /* JackShmMem.h in Headers */, + 4BA3393910B2E36800190E3B /* shm.h in Headers */, + 4BA3393A10B2E36800190E3B /* JackThread.h in Headers */, + 4BA3393B10B2E36800190E3B /* JackActivationCount.h in Headers */, + 4BA3393C10B2E36800190E3B /* JackChannel.h in Headers */, + 4BA3393D10B2E36800190E3B /* JackGraphManager.h in Headers */, + 4BA3393E10B2E36800190E3B /* JackPort.h in Headers */, + 4BA3393F10B2E36800190E3B /* JackClientInterface.h in Headers */, + 4BA3394010B2E36800190E3B /* JackClientControl.h in Headers */, + 4BA3394110B2E36800190E3B /* JackClient.h in Headers */, + 4BA3394210B2E36800190E3B /* JackInternalClient.h in Headers */, + 4BA3394310B2E36800190E3B /* JackConnectionManager.h in Headers */, + 4BA3394410B2E36800190E3B /* JackFrameTimer.h in Headers */, + 4BA3394510B2E36800190E3B /* JackMachSemaphore.h in Headers */, + 4BA3394610B2E36800190E3B /* JackGlobals.h in Headers */, + 4BA3394710B2E36800190E3B /* JackMachThread.h in Headers */, + 4BA3394810B2E36800190E3B /* JackSynchro.h in Headers */, + 4BA3394910B2E36800190E3B /* JackAudioDriver.h in Headers */, + 4BA3394A10B2E36800190E3B /* JackFreewheelDriver.h in Headers */, + 4BA3394B10B2E36800190E3B /* JackThreadedDriver.h in Headers */, + 4BA3394C10B2E36800190E3B /* JackDriver.h in Headers */, + 4BA3394D10B2E36800190E3B /* driver_interface.h in Headers */, + 4BA3394E10B2E36800190E3B /* JackDriverLoader.h in Headers */, + 4BA3394F10B2E36800190E3B /* JackEngine.h in Headers */, + 4BA3395010B2E36800190E3B /* JackExternalClient.h in Headers */, + 4BA3395110B2E36800190E3B /* JackServer.h in Headers */, + 4BA3395210B2E36800190E3B /* JackMachNotifyChannel.h in Headers */, + 4BA3395310B2E36800190E3B /* JackMachServerChannel.h in Headers */, + 4BA3395410B2E36800190E3B /* JackMachServerNotifyChannel.h in Headers */, + 4BA3395510B2E36800190E3B /* JackConstants.h in Headers */, + 4BA3395610B2E36800190E3B /* JackTransportEngine.h in Headers */, + 4BA3395710B2E36800190E3B /* JackServerGlobals.h in Headers */, + 4BA3395810B2E36800190E3B /* timestamps.h in Headers */, + 4BA3395910B2E36800190E3B /* jack.h in Headers */, + 4BA3395A10B2E36800190E3B /* intclient.h in Headers */, + 4BA3395B10B2E36800190E3B /* ringbuffer.h in Headers */, + 4BA3395C10B2E36800190E3B /* statistics.h in Headers */, + 4BA3395D10B2E36800190E3B /* thread.h in Headers */, + 4BA3395E10B2E36800190E3B /* transport.h in Headers */, + 4BA3395F10B2E36800190E3B /* types.h in Headers */, + 4BA3396010B2E36800190E3B /* JackPortType.h in Headers */, + 4BA3396110B2E36800190E3B /* JackMidiPort.h in Headers */, + 4BA3396210B2E36800190E3B /* midiport.h in Headers */, + 4BA3396310B2E36800190E3B /* JackDebugClient.h in Headers */, + 4BA3396410B2E36800190E3B /* JackTools.h in Headers */, + 4BA3396510B2E36800190E3B /* JackNetTool.h in Headers */, + 4BA3396610B2E36800190E3B /* jslist.h in Headers */, + 4BA3396710B2E36800190E3B /* JackMessageBuffer.h in Headers */, + 4BA3396810B2E36800190E3B /* JackRestartThreadedDriver.h in Headers */, + 4BA3396910B2E36800190E3B /* JackControlAPI.h in Headers */, + 4BA3396A10B2E36800190E3B /* JackPosixThread.h in Headers */, + 4BA3396B10B2E36800190E3B /* JackEngineProfiling.h in Headers */, + 4BA3396C10B2E36800190E3B /* JackProcessSync.h in Headers */, + 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */, + 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */, + 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA692A70CBE4BC700EAD520 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3588,6 +3924,78 @@ productReference = 4B19B3000E23620F00DD4A82 /* audioadapter.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4B3224D710A3156800838A8E /* jack_netone Universal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B3224E110A3156800838A8E /* Build configuration list for PBXNativeTarget "jack_netone Universal" */; + buildPhases = ( + 4B3224D810A3156800838A8E /* Headers */, + 4B3224DC10A3156800838A8E /* Sources */, + 4B3224E010A3156800838A8E /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_netone Universal"; + productName = jack_coreaudio; + productReference = 4B3224E510A3156800838A8E /* jack_netone.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4B32251D10A316B200838A8E /* jack_netone 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B32252710A316B200838A8E /* Build configuration list for PBXNativeTarget "jack_netone 64 bits" */; + buildPhases = ( + 4B32251E10A316B200838A8E /* Headers */, + 4B32252210A316B200838A8E /* Sources */, + 4B32252610A316B200838A8E /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_netone 64 bits"; + productName = jack_coreaudio; + productReference = 4B32252B10A316B200838A8E /* jack_netone.so */; + productType = "com.apple.product-type.library.dynamic"; + }; + 4B32255710A3187800838A8E /* jack_netsource Universal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B32255D10A3187800838A8E /* Build configuration list for PBXNativeTarget "jack_netsource Universal" */; + buildPhases = ( + 4B32255810A3187800838A8E /* Headers */, + 4B32255910A3187800838A8E /* Sources */, + 4B32255B10A3187800838A8E /* Frameworks */, + 4B32255C10A3187800838A8E /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_netsource Universal"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B32256110A3187800838A8E /* jack_netsource */; + productType = "com.apple.product-type.tool"; + }; + 4B32257110A3190C00838A8E /* jack_netsource 64 bits */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B32257710A3190C00838A8E /* Build configuration list for PBXNativeTarget "jack_netsource 64 bits" */; + buildPhases = ( + 4B32257210A3190C00838A8E /* Headers */, + 4B32257310A3190C00838A8E /* Sources */, + 4B32257510A3190C00838A8E /* Frameworks */, + 4B32257610A3190C00838A8E /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "jack_netsource 64 bits"; + productInstallPath = /usr/local/bin; + productName = jack_metro; + productReference = 4B32257B10A3190C00838A8E /* jack_netsource */; + productType = "com.apple.product-type.tool"; + }; 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */ = { isa = PBXNativeTarget; buildConfigurationList = 4B35C4210D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jackdmp framework 64bits" */; @@ -4634,6 +5042,25 @@ productReference = 4B978DBB0A31CF4A009E2DD1 /* jack_portaudio.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BA339A810B2E36800190E3B /* Build configuration list for PBXNativeTarget "Jackservermp.framework 64 bits profiling" */; + buildPhases = ( + 4BA3393410B2E36800190E3B /* Headers */, + 4BA3397010B2E36800190E3B /* Resources */, + 4BA3397110B2E36800190E3B /* Sources */, + 4BA339A510B2E36800190E3B /* Rez */, + 4BA339A610B2E36800190E3B /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Jackservermp.framework 64 bits profiling"; + productName = Jack; + productReference = 4BA339AC10B2E36800190E3B /* Jackservermp.framework */; + productType = "com.apple.product-type.framework"; + }; 4BA692A60CBE4BC700EAD520 /* jack_load Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BA692AC0CBE4BC700EAD520 /* Build configuration list for PBXNativeTarget "jack_load Universal" */; @@ -5011,6 +5438,7 @@ buildRules = ( ); dependencies = ( + 4B3224E710A3157900838A8E /* PBXTargetDependency */, ); name = "jack_net Universal"; productName = jack_coreaudio; @@ -5077,6 +5505,7 @@ 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */, 4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */, 4B363F680DEB0D4E001F72D9 /* jack_impulse_grabber Universal */, + 4B32255710A3187800838A8E /* jack_netsource Universal */, 4B699D4F097D421600A18468 /* synchroServer Universal */, 4B699D67097D421600A18468 /* synchroClient Universal */, 4B699D7F097D421700A18468 /* synchroServerClient Universal */, @@ -5086,6 +5515,7 @@ 4B43A8B010145F6F00E52943 /* jack_loopback Universal */, 4B699DA6097D421700A18468 /* jack_dummy Universal */, BA222AC50DC88132001A17F4 /* jack_net Universal */, + 4B3224D710A3156800838A8E /* jack_netone Universal */, 4BD623ED0CBCF0F000DE782F /* inprocess Universal */, BA222AE00DC882DB001A17F4 /* netmanager Universal */, 4B19B2F60E23620F00DD4A82 /* audioadapter Universal */, @@ -5093,6 +5523,7 @@ 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */, 4B35C4270D4731D1000DE7AE /* Jackmp.framework 64 bits */, 4B35C4850D4731D1000DE7AE /* Jackservermp.framework 64 bits */, + 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */, 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */, 4B35C5160D4731D1000DE7AE /* jack_midisine 64 bits */, 4B35C5220D4731D1000DE7AE /* jack_metro 64 bits */, @@ -5116,6 +5547,7 @@ 4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */, 4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */, 4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */, + 4B32257110A3190C00838A8E /* jack_netsource 64 bits */, 4B35C5D80D4731D2000DE7AE /* synchroServer 64 bits */, 4B35C5EC0D4731D2000DE7AE /* synchroClient 64 bits */, 4B35C6000D4731D2000DE7AE /* synchroServerClient 64 bits */, @@ -5125,6 +5557,7 @@ 4B43A8DD1014615800E52943 /* jack_loopback 64 bits */, 4BDCDB931001FB9C00B15929 /* jack_coremidi 64 bits */, 4BDCDBB71001FCC000B15929 /* jack_net 64 bits */, + 4B32251D10A316B200838A8E /* jack_netone 64 bits */, 4BDCDBD71001FD2D00B15929 /* netmanager 64 bits */, 4BDCDBEC1001FD7300B15929 /* audioadapter 64 bits */, 4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */, @@ -5162,6 +5595,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA3397010B2E36800190E3B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ @@ -5179,6 +5619,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B32255C10A3187800838A8E /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32257610A3190C00838A8E /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B35C4200D4731D1000DE7AE /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -5501,6 +5955,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA339A510B2E36800190E3B /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA692AB0CBE4BC700EAD520 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -5624,6 +6085,46 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B3224DC10A3156800838A8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B3224EA10A315B100838A8E /* JackNetOneDriver.cpp in Sources */, + 4B3224F010A315C400838A8E /* netjack_packet.c in Sources */, + 4B3224F210A315C400838A8E /* netjack.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32252210A316B200838A8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32253110A3173900838A8E /* JackNetOneDriver.cpp in Sources */, + 4B32253310A3173B00838A8E /* netjack.c in Sources */, + 4B32253510A3173D00838A8E /* netjack_packet.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32255910A3187800838A8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32256410A318E300838A8E /* netsource.c in Sources */, + 4B32256B10A318FA00838A8E /* netjack.c in Sources */, + 4B32256D10A318FC00838A8E /* netjack_packet.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4B32257310A3190C00838A8E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B32257D10A3195700838A8E /* netjack.c in Sources */, + 4B32257F10A3195900838A8E /* netjack_packet.c in Sources */, + 4B32258110A3195B00838A8E /* netsource.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B35C41D0D4731D1000DE7AE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6246,6 +6747,64 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BA3397110B2E36800190E3B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BA3397210B2E36800190E3B /* JackMachPort.cpp in Sources */, + 4BA3397310B2E36800190E3B /* JackShmMem.cpp in Sources */, + 4BA3397410B2E36800190E3B /* shm.c in Sources */, + 4BA3397510B2E36800190E3B /* JackActivationCount.cpp in Sources */, + 4BA3397610B2E36800190E3B /* JackGraphManager.cpp in Sources */, + 4BA3397710B2E36800190E3B /* JackPort.cpp in Sources */, + 4BA3397810B2E36800190E3B /* JackClient.cpp in Sources */, + 4BA3397910B2E36800190E3B /* JackAPI.cpp in Sources */, + 4BA3397A10B2E36800190E3B /* JackConnectionManager.cpp in Sources */, + 4BA3397B10B2E36800190E3B /* JackFrameTimer.cpp in Sources */, + 4BA3397C10B2E36800190E3B /* JackMachSemaphore.cpp in Sources */, + 4BA3397D10B2E36800190E3B /* JackMachThread.cpp in Sources */, + 4BA3397E10B2E36800190E3B /* JackGlobals.cpp in Sources */, + 4BA3397F10B2E36800190E3B /* ringbuffer.c in Sources */, + 4BA3398010B2E36800190E3B /* JackAudioDriver.cpp in Sources */, + 4BA3398110B2E36800190E3B /* JackFreewheelDriver.cpp in Sources */, + 4BA3398210B2E36800190E3B /* JackThreadedDriver.cpp in Sources */, + 4BA3398310B2E36800190E3B /* JackDriver.cpp in Sources */, + 4BA3398410B2E36800190E3B /* JackDriverLoader.cpp in Sources */, + 4BA3398510B2E36800190E3B /* JackEngine.cpp in Sources */, + 4BA3398610B2E36800190E3B /* JackExternalClient.cpp in Sources */, + 4BA3398710B2E36800190E3B /* JackInternalClient.cpp in Sources */, + 4BA3398810B2E36800190E3B /* JackRPCClientUser.c in Sources */, + 4BA3398910B2E36800190E3B /* JackServer.cpp in Sources */, + 4BA3398A10B2E36800190E3B /* JackMacEngineRPC.cpp in Sources */, + 4BA3398B10B2E36800190E3B /* JackMachNotifyChannel.cpp in Sources */, + 4BA3398C10B2E36800190E3B /* JackMachServerChannel.cpp in Sources */, + 4BA3398D10B2E36800190E3B /* JackMachServerNotifyChannel.cpp in Sources */, + 4BA3398E10B2E36800190E3B /* JackTransportEngine.cpp in Sources */, + 4BA3398F10B2E36800190E3B /* JackServerAPI.cpp in Sources */, + 4BA3399010B2E36800190E3B /* JackServerGlobals.cpp in Sources */, + 4BA3399110B2E36800190E3B /* timestamps.c in Sources */, + 4BA3399210B2E36800190E3B /* JackPortType.cpp in Sources */, + 4BA3399310B2E36800190E3B /* JackAudioPort.cpp in Sources */, + 4BA3399410B2E36800190E3B /* JackMidiPort.cpp in Sources */, + 4BA3399510B2E36800190E3B /* JackMidiAPI.cpp in Sources */, + 4BA3399610B2E36800190E3B /* JackEngineControl.cpp in Sources */, + 4BA3399710B2E36800190E3B /* JackDebugClient.cpp in Sources */, + 4BA3399810B2E36800190E3B /* JackTools.cpp in Sources */, + 4BA3399910B2E36800190E3B /* JackNetTool.cpp in Sources */, + 4BA3399A10B2E36800190E3B /* JackError.cpp in Sources */, + 4BA3399B10B2E36800190E3B /* JackMessageBuffer.cpp in Sources */, + 4BA3399C10B2E36800190E3B /* JackRestartThreadedDriver.cpp in Sources */, + 4BA3399D10B2E36800190E3B /* JackControlAPI.cpp in Sources */, + 4BA3399E10B2E36800190E3B /* JackPosixThread.cpp in Sources */, + 4BA3399F10B2E36800190E3B /* JackMachTime.c in Sources */, + 4BA339A010B2E36800190E3B /* JackEngineProfiling.cpp in Sources */, + 4BA339A110B2E36800190E3B /* JackProcessSync.cpp in Sources */, + 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */, + 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */, + 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BA692A80CBE4BC700EAD520 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6468,6 +7027,31 @@ target = 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */; targetProxy = 4B224B330E65BA330066BE5B /* PBXContainerItemProxy */; }; + 4B3224E710A3157900838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B3224D710A3156800838A8E /* jack_netone Universal */; + targetProxy = 4B3224E610A3157900838A8E /* PBXContainerItemProxy */; + }; + 4B32258B10A31A9000838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B32255710A3187800838A8E /* jack_netsource Universal */; + targetProxy = 4B32258A10A31A9000838A8E /* PBXContainerItemProxy */; + }; + 4B32258D10A31A9D00838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B3224D710A3156800838A8E /* jack_netone Universal */; + targetProxy = 4B32258C10A31A9D00838A8E /* PBXContainerItemProxy */; + }; + 4B32258F10A31AB400838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B32257110A3190C00838A8E /* jack_netsource 64 bits */; + targetProxy = 4B32258E10A31AB400838A8E /* PBXContainerItemProxy */; + }; + 4B32259110A31ABA00838A8E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4B32251D10A316B200838A8E /* jack_netone 64 bits */; + targetProxy = 4B32259010A31ABA00838A8E /* PBXContainerItemProxy */; + }; 4B35C5530D4731D2000DE7AE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B699D03097D421600A18468 /* jack_external_metro Universal */; @@ -6588,11 +7172,6 @@ target = 4B363E440DEB0775001F72D9 /* jack_bufsize Universal */; targetProxy = 4B363E760DEB0838001F72D9 /* PBXContainerItemProxy */; }; - 4B363EF20DEB0965001F72D9 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4B363EDF0DEB091C001F72D9 /* jack_rec Universal */; - targetProxy = 4B363EF10DEB0965001F72D9 /* PBXContainerItemProxy */; - }; 4B363F250DEB0ABE001F72D9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */; @@ -6889,12 +7468,8 @@ 4B0A292A0D52108E002EFF74 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ppc64, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -6923,12 +7498,8 @@ 4B0A292B0D52108E002EFF74 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ppc64, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -7127,46 +7698,37 @@ }; name = Default; }; - 4B35C4220D4731D1000DE7AE /* Development */ = { + 4B3224E210A3156800838A8E /* Development */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( - ppc64, - ppc, i386, - x86_64, + ppc, ); COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - FRAMEWORK_SEARCH_PATHS = ""; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; - GCC_PREPROCESSOR_DEFINITIONS = ""; HEADER_SEARCH_PATHS = ( + ../common, ., ../common/jack, ../posix, - ../common, - RPC, - ); - MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ( - "-DUSE_POSIX_SHM", - "-D__SMP__", - "-DJACK_32_64", - ); - OTHER_CPLUSPLUSFLAGS = ( - "-DMACH_RPC_MACH_SEMA", - "-D__SMP__", - "-DJACK_32_64", ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; OTHER_LDFLAGS = ( "-framework", - Jackdmp, + Jackservermp, "-framework", CoreAudio, "-framework", @@ -7175,8 +7737,8 @@ AudioUnit, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jackdmp; - REZ_EXECUTABLE = YES; + PREBINDING = NO; + PRODUCT_NAME = jack_netone; SDKROOT = ""; SECTORDER_FLAGS = ""; WARNING_CFLAGS = ( @@ -7188,15 +7750,485 @@ }; name = Development; }; - 4B35C4230D4731D1000DE7AE /* Deployment */ = { + 4B3224E310A3156800838A8E /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( - ppc64, + i386, ppc, + ); + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + HEADER_SEARCH_PATHS = ( + ../common, + ., + ../common/jack, + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_netone; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B3224E410A3156800838A8E /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( i386, - x86_64, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B32252810A316B200838A8E /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G4; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ( + ../common, + ., + ../common/jack, + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_netone; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B32252910A316B200838A8E /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + HEADER_SEARCH_PATHS = ( + ../common, + ., + ../common/jack, + ../posix, + ); + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); + OTHER_LDFLAGS = ( + "-framework", + Jackservermp, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_netone; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B32252A10A316B200838A8E /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_dummy; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B32255E10A3187800838A8E /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_netsource; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B32255F10A3187800838A8E /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_netsource; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B32256010A3187800838A8E /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B32257810A3190C00838A8E /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_netsource; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B32257910A3190C00838A8E /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_netsource; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B32257A10A3190C00838A8E /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ""; + HEADER_SEARCH_PATHS = ../common; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Jackmp, + "-framework", + CoreFoundation, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jack_midiseq; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4B35C4220D4731D1000DE7AE /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ( + ., + ../common/jack, + ../posix, + ../common, + RPC, + ); + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DUSE_POSIX_SHM", + "-D__SMP__", + "-DJACK_32_64", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-D__SMP__", + "-DJACK_32_64", + ); + OTHER_LDFLAGS = ( + "-framework", + Jackdmp, + "-framework", + CoreAudio, + "-framework", + CoreServices, + "-framework", + AudioUnit, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = jackdmp; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4B35C4230D4731D1000DE7AE /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = dwarf; FRAMEWORK_SEARCH_PATHS = ""; @@ -7307,12 +8339,8 @@ 4B35C4800D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -7375,12 +8403,8 @@ 4B35C4810D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -7506,12 +8530,8 @@ 4B35C4F90D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -7574,12 +8594,8 @@ 4B35C4FA0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -7707,12 +8723,8 @@ 4B35C5110D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -7744,12 +8756,8 @@ 4B35C5120D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -7810,12 +8818,8 @@ 4B35C51D0D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -7847,12 +8851,8 @@ 4B35C51E0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -7913,12 +8913,8 @@ 4B35C5290D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -7950,12 +8946,8 @@ 4B35C52A0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -8016,12 +9008,8 @@ 4B35C5350D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -8051,12 +9039,8 @@ 4B35C5360D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -8113,12 +9097,8 @@ 4B35C5410D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8148,12 +9128,8 @@ 4B35C5420D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; @@ -8210,12 +9186,8 @@ 4B35C54D0D4731D1000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8244,12 +9216,8 @@ 4B35C54E0D4731D1000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; @@ -8304,12 +9272,8 @@ 4B35C55B0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8340,12 +9304,8 @@ 4B35C55C0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; @@ -8404,12 +9364,8 @@ 4B35C5670D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -8439,12 +9395,8 @@ 4B35C5680D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -8501,12 +9453,8 @@ 4B35C5730D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -8539,12 +9487,8 @@ 4B35C5740D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -8650,12 +9594,8 @@ 4B35C5840D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -8763,12 +9703,8 @@ 4B35C5980D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -8830,12 +9766,8 @@ 4B35C5A30D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8865,12 +9797,8 @@ 4B35C5A40D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ../common; @@ -8927,12 +9855,8 @@ 4B35C5AF0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -8961,12 +9885,8 @@ 4B35C5B00D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -9023,12 +9943,8 @@ 4B35C5BB0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -9057,12 +9973,8 @@ 4B35C5BC0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -9119,12 +10031,8 @@ 4B35C5C70D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -9153,12 +10061,8 @@ 4B35C5C80D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -9215,12 +10119,8 @@ 4B35C5D30D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; @@ -9249,12 +10149,8 @@ 4B35C5D40D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_OPTIMIZATION_LEVEL = 3; @@ -9354,12 +10250,8 @@ 4B35C5E80D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( @@ -9471,15 +10363,11 @@ }; name = Development; }; - 4B35C5FC0D4731D2000DE7AE /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + 4B35C5FC0D4731D2000DE7AE /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( @@ -9593,12 +10481,8 @@ 4B35C6100D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; HEADER_SEARCH_PATHS = ( @@ -9669,12 +10553,8 @@ 4B35C61B0D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -9724,12 +10604,8 @@ 4B35C61C0D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -9879,12 +10755,8 @@ 4B35C6270D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -9980,12 +10852,8 @@ 4B35C6310D4731D2000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -10034,12 +10902,8 @@ 4B35C6320D4731D2000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -10129,12 +10993,8 @@ 4B35C63B0D4731D3000DE7AE /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -10179,12 +11039,8 @@ 4B35C63C0D4731D3000DE7AE /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -10775,7 +11631,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -10846,7 +11701,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_showtime; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -10873,7 +11728,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -10971,7 +11825,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -11163,10 +12016,8 @@ 4B43A8E41014615800E52943 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -11216,7 +12067,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -12040,10 +12891,8 @@ 4B699CA9097D421600A18468 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -12099,10 +12948,8 @@ 4B699CAA097D421600A18468 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; @@ -13866,91 +14713,288 @@ i386, ppc, ); - COPY_PHASE_STRIP = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_EXTENSION = so; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G4; - GCC_PREPROCESSOR_DEFINITIONS = ""; - HEADER_SEARCH_PATHS = ../common/; - INSTALL_PATH = /usr/local/lib; - LD_OPENMP_FLAGS = "-fopenmp"; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; + COPY_PHASE_STRIP = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ../common/; + INSTALL_PATH = /usr/local/lib; + LD_OPENMP_FLAGS = "-fopenmp"; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + libportaudio.a, + "-framework", + Jackservermp, + "-framework", + CoreAudio, + "-framework", + AudioUnit, + "-framework", + CoreServices, + "-framework", + AudioToolbox, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_portaudio; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B978DBA0A31CF4A009E2DD1 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + EXECUTABLE_EXTENSION = so; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G4; + GCC_PREPROCESSOR_DEFINITIONS = ""; + HEADER_SEARCH_PATHS = ../common/; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = DYNAMIC; + MACH_O_TYPE = mh_dylib; + OTHER_CFLAGS = ""; + OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_LDFLAGS = ( + libportaudio.a, + "-framework", + Jackdmp, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + "-framework", + AudioUnit, + "-framework", + CoreServices, + ); + OTHER_REZFLAGS = ""; + PREBINDING = NO; + PRODUCT_NAME = jack_portaudio; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; + 4BA339A910B2E36800190E3B /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + ../common, + ../posix, + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + OTHER_CFLAGS = ( + "-DJACK_MONITOR", + "-DSERVER_SIDE", + "-DJACK_32_64", + "-D__SMP__", + "-DUSE_POSIX_SHM", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DJACK_MONITOR", + "-DSERVER_SIDE", + "-DJACK_32_64", + "-D__SMP__", + "-DMACH_RPC_MACH_SEMA", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = Jackdmp; + REZ_EXECUTABLE = NO; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + ZERO_LINK = YES; + }; + name = Development; + }; + 4BA339AA10B2E36800190E3B /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_AUTO_VECTORIZATION = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_ENABLE_SSE3_EXTENSIONS = YES; + GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + ../common, + ../posix, + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; MACOSX_DEPLOYMENT_TARGET = 10.4; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CFLAGS = ( + "-DJACK_MONITOR", + "-DSERVER_SIDE", + "-DJACK_32_64", + "-D__SMP__", + "-DUSE_POSIX_SHM", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DJACK_MONITOR", + "-DSERVER_SIDE", + "-DJACK_32_64", + "-D__SMP__", + "-DMACH_RPC_MACH_SEMA", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( - libportaudio.a, "-framework", - Jackservermp, + Carbon, "-framework", CoreAudio, - "-framework", - AudioUnit, - "-framework", - CoreServices, - "-framework", - AudioToolbox, ); OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = jack_portaudio; + PRODUCT_NAME = Jackservermp; + REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); + WARNING_CFLAGS = "-Wmost"; ZERO_LINK = NO; }; name = Deployment; }; - 4B978DBA0A31CF4A009E2DD1 /* Default */ = { + 4BA339AB10B2E36800190E3B /* Default */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = ( - i386, + ppc64, ppc, + i386, + x86_64, ); + DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - EXECUTABLE_EXTENSION = so; - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; - GCC_MODEL_TUNING = G4; - GCC_PREPROCESSOR_DEFINITIONS = ""; - HEADER_SEARCH_PATHS = ../common/; - INSTALL_PATH = /usr/local/lib; - LIBRARY_STYLE = DYNAMIC; - MACH_O_TYPE = mh_dylib; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + OTHER_CFLAGS = ( + "-D__SMP__", + "-DJACK_32_64", + "-DUSE_POSIX_SHM", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-D__SMP__", + "-DJACK_32_64", + "-DMACH_RPC_MACH_SEMA", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_LDFLAGS = ( - libportaudio.a, "-framework", - Jackdmp, + Carbon, "-framework", AudioToolBox, "-framework", CoreAudio, - "-framework", - AudioUnit, - "-framework", - CoreServices, ); OTHER_REZFLAGS = ""; - PREBINDING = NO; - PRODUCT_NAME = jack_portaudio; + PRODUCT_NAME = Jackdmp; + REZ_EXECUTABLE = NO; SDKROOT = ""; SECTORDER_FLAGS = ""; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); + WARNING_CFLAGS = "-Wmost"; }; name = Default; }; @@ -14366,10 +15410,8 @@ 4BDCDB9A1001FB9C00B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14419,7 +15461,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14514,10 +15556,8 @@ 4BDCDBC21001FCC000B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14567,7 +15607,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14655,10 +15695,8 @@ 4BDCDBE51001FD2D00B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - i386, - ppc, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14709,7 +15747,7 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "ppc i386 ppc64 x86_64"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14801,7 +15839,7 @@ 4BDCDBFC1001FD7300B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = i386; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14852,8 +15890,7 @@ 4BDCDBFD1001FD7300B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -14946,7 +15983,7 @@ 4BDCDC221001FDE300B15929 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = i386; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; COPY_PHASE_STRIP = NO; DEBUGGING_SYMBOLS = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -14997,8 +16034,7 @@ 4BDCDC231001FDE300B15929 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + ARCHS = "$(NATIVE_ARCH_ACTUAL)"; COPY_PHASE_STRIP = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -15537,12 +16573,8 @@ 4BFA82890DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15574,12 +16606,8 @@ 4BFA828A0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -15640,12 +16668,8 @@ 4BFA829C0DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15677,12 +16701,8 @@ 4BFA829D0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -15741,12 +16761,8 @@ 4BFA82A80DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15783,12 +16799,8 @@ 4BFA82A90DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -15852,12 +16864,8 @@ 4BFA82B40DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15889,12 +16897,8 @@ 4BFA82B50DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -15902,7 +16906,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -15954,12 +16957,8 @@ 4BFA82C00DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -15975,7 +16974,7 @@ CoreFoundation, ); OTHER_REZFLAGS = ""; - PRODUCT_NAME = jack_midiseq; + PRODUCT_NAME = jack_showtime; REZ_EXECUTABLE = YES; SDKROOT = ""; SECTORDER_FLAGS = ""; @@ -15991,12 +16990,8 @@ 4BFA82C10DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -16004,7 +16999,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -16056,12 +17050,8 @@ 4BFA82CC0DF6A9E40087B4E1 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ""; GCC_DYNAMIC_NO_PIC = NO; @@ -16093,12 +17083,8 @@ 4BFA82CD0DF6A9E40087B4E1 /* Deployment */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - ppc64, - ppc, - i386, - x86_64, - ); + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; COPY_PHASE_STRIP = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; @@ -16106,7 +17092,6 @@ MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ( - "-lsndfile", "-framework", Jackmp, "-framework", @@ -16567,6 +17552,46 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B3224E110A3156800838A8E /* Build configuration list for PBXNativeTarget "jack_netone Universal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B3224E210A3156800838A8E /* Development */, + 4B3224E310A3156800838A8E /* Deployment */, + 4B3224E410A3156800838A8E /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B32252710A316B200838A8E /* Build configuration list for PBXNativeTarget "jack_netone 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B32252810A316B200838A8E /* Development */, + 4B32252910A316B200838A8E /* Deployment */, + 4B32252A10A316B200838A8E /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B32255D10A3187800838A8E /* Build configuration list for PBXNativeTarget "jack_netsource Universal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B32255E10A3187800838A8E /* Development */, + 4B32255F10A3187800838A8E /* Deployment */, + 4B32256010A3187800838A8E /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; + 4B32257710A3190C00838A8E /* Build configuration list for PBXNativeTarget "jack_netsource 64 bits" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B32257810A3190C00838A8E /* Development */, + 4B32257910A3190C00838A8E /* Deployment */, + 4B32257A10A3190C00838A8E /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B35C4210D4731D1000DE7AE /* Build configuration list for PBXNativeTarget "jackdmp framework 64bits" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -17157,6 +18182,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4BA339A810B2E36800190E3B /* Build configuration list for PBXNativeTarget "Jackservermp.framework 64 bits profiling" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BA339A910B2E36800190E3B /* Development */, + 4BA339AA10B2E36800190E3B /* Deployment */, + 4BA339AB10B2E36800190E3B /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4BA692AC0CBE4BC700EAD520 /* Build configuration list for PBXNativeTarget "jack_load Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/macosx/RPC/JackRPCClient.defs b/macosx/RPC/JackRPCClient.defs index ea5489ca..3c3eb515 100644 --- a/macosx/RPC/JackRPCClient.defs +++ b/macosx/RPC/JackRPCClient.defs @@ -24,14 +24,15 @@ subsystem JackRPCClient 1000; import "Jackdefs.h"; waittime 5000; -type client_name_t = c_string[128]; -type client_port_name_t = c_string[128]; +type client_name_t = c_string[64]; +type message_t = c_string[256]; routine rpc_jack_client_sync_notify( client_port : mach_port_t; refnum : int; client_name : client_name_t; notify : int; + message : message_t; value1 : int; value2 : int; out result : int); @@ -41,5 +42,6 @@ simpleroutine rpc_jack_client_async_notify( refnum : int; client_name : client_name_t; notify : int; + message : message_t; value1 : int; value2 : int); diff --git a/macosx/RPC/JackRPCClient.h b/macosx/RPC/JackRPCClient.h index 72c53fda..d4462479 100644 --- a/macosx/RPC/JackRPCClient.h +++ b/macosx/RPC/JackRPCClient.h @@ -21,7 +21,7 @@ typedef struct { char *name; function_ptr_t function; } function_table_entry; -typedef function_table_entry *function_table_t; +typedef function_table_entry *function_table_t; #endif /* FUNCTION_PTR_T */ #endif /* AUTOTEST */ @@ -55,6 +55,7 @@ kern_return_t rpc_jack_client_sync_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2, int *result @@ -72,6 +73,7 @@ kern_return_t rpc_jack_client_async_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2 ); @@ -103,6 +105,7 @@ __END_DECLS int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } __Request__rpc_jack_client_sync_notify_t; @@ -119,6 +122,7 @@ __END_DECLS int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } __Request__rpc_jack_client_async_notify_t; diff --git a/macosx/RPC/JackRPCClientServer.c b/macosx/RPC/JackRPCClientServer.c index efb4e9e9..7f5af274 100644 --- a/macosx/RPC/JackRPCClientServer.c +++ b/macosx/RPC/JackRPCClientServer.c @@ -1,7 +1,7 @@ /* * IDENTIFICATION: - * stub generated Mon Sep 1 17:42:27 2008 - * with a MiG generated Tue Feb 19 02:01:43 PST 2008 by root@b75.local + * stub generated Fri Oct 23 10:35:08 2009 + * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com * OPTIONS: */ @@ -113,6 +113,7 @@ int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } __Request__rpc_jack_client_sync_notify_t; @@ -129,6 +130,7 @@ int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } __Request__rpc_jack_client_async_notify_t; @@ -224,11 +226,11 @@ mig_internal novalue _Xrpc_jack_client_async_notify #elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__int_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ @@ -252,6 +254,26 @@ mig_internal novalue _Xrpc_jack_client_async_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#if defined(__NDR_convert__int_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__int_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__int_rep__message_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__int_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__int_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__int_rep__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__int_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ + #ifndef __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined #if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined @@ -324,11 +346,11 @@ mig_internal novalue _Xrpc_jack_client_async_notify #elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__char_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ @@ -352,6 +374,26 @@ mig_internal novalue _Xrpc_jack_client_async_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#if defined(__NDR_convert__char_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__char_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__char_rep__message_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__char_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__char_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__char_rep__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__char_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ + #ifndef __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined #if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined @@ -424,11 +466,11 @@ mig_internal novalue _Xrpc_jack_client_async_notify #elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__float_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined */ @@ -452,6 +494,26 @@ mig_internal novalue _Xrpc_jack_client_async_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#if defined(__NDR_convert__float_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__float_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__float_rep__message_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__float_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__float_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__float_rep__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(a, f) \ + __NDR_convert__float_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ + #ifndef __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined #if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined @@ -503,9 +565,24 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->message), 256); + if (( memchr(In0P->message, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ + defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -518,6 +595,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined) + __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ @@ -530,6 +610,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ + defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) if (In0P->NDR.char_rep != NDR_record.char_rep) { @@ -542,6 +623,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined) + __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.char_rep); +#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ @@ -554,6 +638,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__refnum__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__client_name__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) || \ + defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value2__defined) if (In0P->NDR.float_rep != NDR_record.float_rep) { @@ -566,6 +651,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_sync_notify_t(_ #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined) __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify(&In0P->notify, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__notify__defined */ +#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined) + __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message(&In0P->message, In0P->NDR.float_rep); +#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__message__defined */ #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined) __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1(&In0P->value1, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_sync_notify_t__value1__defined */ @@ -594,6 +682,7 @@ kern_return_t rpc_jack_client_sync_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2, int *result @@ -613,6 +702,7 @@ mig_internal novalue _Xrpc_jack_client_sync_notify int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; mach_msg_trailer_t trailer; @@ -646,7 +736,7 @@ mig_internal novalue _Xrpc_jack_client_sync_notify { MIG_RETURN_ERROR(OutP, check_result); } #endif /* defined(__MIG_check__Request__rpc_jack_client_sync_notify_t__defined) */ - OutP->RetCode = rpc_jack_client_sync_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->value1, In0P->value2, &OutP->result); + OutP->RetCode = rpc_jack_client_sync_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->message, In0P->value1, In0P->value2, &OutP->result); if (OutP->RetCode != KERN_SUCCESS) { MIG_RETURN_ERROR(OutP, OutP->RetCode); } @@ -694,11 +784,11 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__int_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ @@ -722,6 +812,26 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#if defined(__NDR_convert__int_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__int_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__int_rep__message_t__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__int_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__int_rep__JackRPCClient__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__int_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__int_rep__string__defined) +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__int_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined */ + #ifndef __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined #if defined(__NDR_convert__int_rep__JackRPCClient__int__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined @@ -794,11 +904,11 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__char_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ @@ -822,6 +932,26 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#if defined(__NDR_convert__char_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__char_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__char_rep__message_t__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__char_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__char_rep__JackRPCClient__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__char_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__char_rep__string__defined) +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__char_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined */ + #ifndef __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined #if defined(__NDR_convert__char_rep__JackRPCClient__int__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined @@ -894,11 +1024,11 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCClient__string(a, f, 128) + __NDR_convert__float_rep__JackRPCClient__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined */ @@ -922,6 +1052,26 @@ mig_internal novalue _Xrpc_jack_client_sync_notify #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#if defined(__NDR_convert__float_rep__JackRPCClient__message_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__float_rep__JackRPCClient__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__float_rep__message_t__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__float_rep__message_t((message_t *)(a), f) +#elif defined(__NDR_convert__float_rep__JackRPCClient__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__float_rep__JackRPCClient__string(a, f, 256) +#elif defined(__NDR_convert__float_rep__string__defined) +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined +#define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(a, f) \ + __NDR_convert__float_rep__string(a, f, 256) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined */ + #ifndef __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined #if defined(__NDR_convert__float_rep__JackRPCClient__int__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined @@ -973,9 +1123,24 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->message), 256); + if (( memchr(In0P->message, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ + defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value2__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -988,6 +1153,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined) __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined) + __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__message__defined */ #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined) __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.int_rep); #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ @@ -1000,6 +1168,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ + defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value2__defined) if (In0P->NDR.char_rep != NDR_record.char_rep) { @@ -1012,6 +1181,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined) __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined) + __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.char_rep); +#endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__message__defined */ #if defined(__NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined) __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.char_rep); #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ @@ -1024,6 +1196,7 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__refnum__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__client_name__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined) || \ + defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined) || \ defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value2__defined) if (In0P->NDR.float_rep != NDR_record.float_rep) { @@ -1036,6 +1209,9 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_async_notify_t( #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined) __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify(&In0P->notify, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__notify__defined */ +#if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined) + __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message(&In0P->message, In0P->NDR.float_rep); +#endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__message__defined */ #if defined(__NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined) __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1(&In0P->value1, In0P->NDR.float_rep); #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_async_notify_t__value1__defined */ @@ -1064,6 +1240,7 @@ kern_return_t rpc_jack_client_async_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2 ); @@ -1082,6 +1259,7 @@ mig_internal novalue _Xrpc_jack_client_async_notify int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; mach_msg_trailer_t trailer; @@ -1115,7 +1293,7 @@ mig_internal novalue _Xrpc_jack_client_async_notify { MIG_RETURN_ERROR(OutP, check_result); } #endif /* defined(__MIG_check__Request__rpc_jack_client_async_notify_t__defined) */ - OutP->RetCode = rpc_jack_client_async_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->value1, In0P->value2); + OutP->RetCode = rpc_jack_client_async_notify(In0P->Head.msgh_request_port, In0P->refnum, In0P->client_name, In0P->notify, In0P->message, In0P->value1, In0P->value2); __AfterRcvSimple(1001, "rpc_jack_client_async_notify") } @@ -1145,9 +1323,9 @@ const struct JackRPCClient_subsystem { (vm_address_t)0, { { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_sync_notify, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_sync_notify_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_sync_notify, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_sync_notify_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_async_notify, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_async_notify_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_async_notify, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_async_notify_t)}, } }; diff --git a/macosx/RPC/JackRPCClientUser.c b/macosx/RPC/JackRPCClientUser.c index 4dc66a10..e6fef35e 100644 --- a/macosx/RPC/JackRPCClientUser.c +++ b/macosx/RPC/JackRPCClientUser.c @@ -1,7 +1,7 @@ /* * IDENTIFICATION: - * stub generated Mon Sep 1 17:42:27 2008 - * with a MiG generated Tue Feb 19 02:01:43 PST 2008 by root@b75.local + * stub generated Fri Oct 23 10:35:08 2009 + * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com * OPTIONS: */ #define __MIG_check__Reply__JackRPCClient_subsystem__ 1 @@ -50,15 +50,15 @@ #ifndef __MachMsgErrorWithTimeout #define __MachMsgErrorWithTimeout(_R_) { \ switch (_R_) { \ - case MACH_SEND_INVALID_REPLY: \ - case MACH_RCV_INVALID_NAME: \ - case MACH_RCV_PORT_DIED: \ - case MACH_RCV_PORT_CHANGED: \ - case MACH_RCV_TIMED_OUT: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ break; \ + case MACH_SEND_TIMED_OUT: \ + case MACH_RCV_TIMED_OUT: \ default: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ } \ } #endif /* __MachMsgErrorWithTimeout */ @@ -66,14 +66,13 @@ #ifndef __MachMsgErrorWithoutTimeout #define __MachMsgErrorWithoutTimeout(_R_) { \ switch (_R_) { \ - case MACH_SEND_INVALID_REPLY: \ - case MACH_RCV_INVALID_NAME: \ - case MACH_RCV_PORT_DIED: \ - case MACH_RCV_PORT_CHANGED: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ break; \ default: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ } \ } #endif /* __MachMsgErrorWithoutTimeout */ @@ -265,6 +264,7 @@ mig_external kern_return_t rpc_jack_client_sync_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2, int *result @@ -280,6 +280,7 @@ mig_external kern_return_t rpc_jack_client_sync_notify int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } Request; @@ -341,10 +342,12 @@ mig_external kern_return_t rpc_jack_client_sync_notify InP->refnum = refnum; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->notify = notify; + (void) mig_strncpy(InP->message, message, 256); + InP->value1 = value1; InP->value2 = value2; @@ -387,6 +390,7 @@ mig_external kern_return_t rpc_jack_client_async_notify int refnum, client_name_t client_name, int notify, + message_t message, int value1, int value2 ) @@ -401,6 +405,7 @@ mig_external kern_return_t rpc_jack_client_async_notify int refnum; client_name_t client_name; int notify; + message_t message; int value1; int value2; } Request; @@ -433,10 +438,12 @@ mig_external kern_return_t rpc_jack_client_async_notify InP->refnum = refnum; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->notify = notify; + (void) mig_strncpy(InP->message, message, 256); + InP->value1 = value1; InP->value2 = value2; diff --git a/macosx/RPC/JackRPCEngine.defs b/macosx/RPC/JackRPCEngine.defs index 63500f41..468b3775 100644 --- a/macosx/RPC/JackRPCEngine.defs +++ b/macosx/RPC/JackRPCEngine.defs @@ -25,11 +25,11 @@ import "Jackdefs.h"; ServerPrefix server_; -type client_name_t = c_string[128]; +type client_name_t = c_string[64]; 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]; +type so_name_t = c_string[256]; +type objet_data_t = c_string[256]; routine rpc_jack_client_open( server_port : mach_port_t; diff --git a/macosx/RPC/JackRPCEngine.h b/macosx/RPC/JackRPCEngine.h index 8b4fddf4..b9ba07f0 100644 --- a/macosx/RPC/JackRPCEngine.h +++ b/macosx/RPC/JackRPCEngine.h @@ -21,7 +21,7 @@ typedef struct { char *name; function_ptr_t function; } function_table_entry; -typedef function_table_entry *function_table_t; +typedef function_table_entry *function_table_t; #endif /* FUNCTION_PTR_T */ #endif /* AUTOTEST */ diff --git a/macosx/RPC/JackRPCEngineServer.c b/macosx/RPC/JackRPCEngineServer.c index 16508dcf..7ef5d556 100644 --- a/macosx/RPC/JackRPCEngineServer.c +++ b/macosx/RPC/JackRPCEngineServer.c @@ -1,7 +1,7 @@ /* * IDENTIFICATION: - * stub generated Mon Sep 1 17:42:28 2008 - * with a MiG generated Tue Feb 19 02:01:43 PST 2008 by root@b75.local + * stub generated Fri Oct 23 10:35:08 2009 + * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com * OPTIONS: */ @@ -791,11 +791,11 @@ mig_internal novalue _Xrpc_jack_client_rt_notify #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined */ @@ -831,11 +831,11 @@ mig_internal novalue _Xrpc_jack_client_rt_notify #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_open_t__client_name__defined */ @@ -871,11 +871,11 @@ mig_internal novalue _Xrpc_jack_client_rt_notify #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_open_t__client_name__defined */ @@ -910,6 +910,17 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_open_t(__attrib return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_open_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_open_t__pid__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -1064,11 +1075,11 @@ mig_internal novalue _Xrpc_jack_client_open #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined */ @@ -1124,11 +1135,11 @@ mig_internal novalue _Xrpc_jack_client_open #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_client_check_t__client_name__defined */ @@ -1184,11 +1195,11 @@ mig_internal novalue _Xrpc_jack_client_open #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_client_check_t__client_name__defined */ @@ -1243,6 +1254,17 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_client_check_t(__attri return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__protocol__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_client_check_t__options__defined) @@ -2283,6 +2305,20 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_register_t(__attr return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->name), 128); + if (( memchr(In0P->name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->port_type), 128); + if (( memchr(In0P->port_type, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #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) || \ @@ -3526,6 +3562,20 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_connect_name_t(__ return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->src), 128); + if (( memchr(In0P->src, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->dst), 128); + if (( memchr(In0P->dst, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__src__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_connect_name_t__dst__defined) @@ -3848,6 +3898,20 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_disconnect_name_t return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->src), 128); + if (( memchr(In0P->src, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->dst), 128); + if (( memchr(In0P->dst, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__src__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_disconnect_name_t__dst__defined) @@ -4170,6 +4234,17 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_port_rename_t(__attrib return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->name), 128); + if (( memchr(In0P->name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__src__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_port_rename_t__name__defined) @@ -5352,11 +5427,11 @@ mig_internal novalue _Xrpc_jack_get_internal_clientname #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ @@ -5392,11 +5467,11 @@ mig_internal novalue _Xrpc_jack_get_internal_clientname #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ @@ -5432,11 +5507,11 @@ mig_internal novalue _Xrpc_jack_get_internal_clientname #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined */ @@ -5451,6 +5526,17 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_internal_clienthandle_ return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clienthandle_t__client_name__defined) if (In0P->NDR.int_rep != NDR_record.int_rep) { @@ -5602,11 +5688,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ @@ -5622,11 +5708,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__int_rep__string(a, f, 1024) + __NDR_convert__int_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ @@ -5642,11 +5728,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__int_rep__string(a, f, 1024) + __NDR_convert__int_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ @@ -5702,11 +5788,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ @@ -5722,11 +5808,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__char_rep__string(a, f, 1024) + __NDR_convert__char_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ @@ -5742,11 +5828,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__char_rep__string(a, f, 1024) + __NDR_convert__char_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ @@ -5802,11 +5888,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__client_name__defined */ @@ -5822,11 +5908,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name(a, f) \ - __NDR_convert__float_rep__string(a, f, 1024) + __NDR_convert__float_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__so_name__defined */ @@ -5842,11 +5928,11 @@ mig_internal novalue _Xrpc_jack_internal_clienthandle #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 1024) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 256) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined #define __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data(a, f) \ - __NDR_convert__float_rep__string(a, f, 1024) + __NDR_convert__float_rep__string(a, f, 256) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Request__rpc_jack_internal_clientload_t__objet_data__defined */ @@ -5881,6 +5967,23 @@ mig_internal kern_return_t __MIG_check__Request__rpc_jack_internal_clientload_t( return MIG_BAD_ARGUMENTS; #endif /* __MigTypeCheck */ +#if __MigTypeCheck + { + char * msg_limit = ((char *) In0P) + In0P->Head.msgh_size; + size_t memchr_limit; + + memchr_limit = min((msg_limit - In0P->client_name), 64); + if (( memchr(In0P->client_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->so_name), 256); + if (( memchr(In0P->so_name, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + memchr_limit = min((msg_limit - In0P->objet_data), 256); + if (( memchr(In0P->objet_data, '\0', memchr_limit) == NULL )) + return MIG_BAD_ARGUMENTS; // string length exceeds buffer length! + } +#endif /* __MigTypeCheck */ + #if defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__refnum__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__client_name__defined) || \ defined(__NDR_convert__int_rep__Request__rpc_jack_internal_clientload_t__so_name__defined) || \ @@ -6626,47 +6729,47 @@ const struct server_JackRPCEngine_subsystem { (vm_address_t)0, { { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_open, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_open_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_open, 8, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_open_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_check, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_check_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_check, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_check_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_close, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_close_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_close, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_close_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_activate, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_activate_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_activate, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_activate_t)}, { (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_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, 8, 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_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, - (mig_stub_routine_t) _Xrpc_jack_port_connect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_connect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_disconnect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_disconnect, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_connect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_name_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_connect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_connect_name_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_disconnect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_name_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_disconnect_name, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_disconnect_name_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_port_rename, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_rename_t)}, + (mig_stub_routine_t) _Xrpc_jack_port_rename, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_port_rename_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_buffer_size, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_buffer_size_t)}, + (mig_stub_routine_t) _Xrpc_jack_set_buffer_size, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_buffer_size_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_freewheel, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_freewheel_t)}, + (mig_stub_routine_t) _Xrpc_jack_set_freewheel, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_freewheel_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_release_timebase, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_release_timebase_t)}, + (mig_stub_routine_t) _Xrpc_jack_release_timebase, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_release_timebase_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_set_timebase_callback, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_timebase_callback_t)}, + (mig_stub_routine_t) _Xrpc_jack_set_timebase_callback, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_set_timebase_callback_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_get_internal_clientname, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_get_internal_clientname_t)}, + (mig_stub_routine_t) _Xrpc_jack_get_internal_clientname, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_get_internal_clientname_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clienthandle, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clienthandle_t)}, + (mig_stub_routine_t) _Xrpc_jack_internal_clienthandle, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clienthandle_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clientload, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientload_t)}, + (mig_stub_routine_t) _Xrpc_jack_internal_clientload, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientload_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_internal_clientunload, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientunload_t)}, + (mig_stub_routine_t) _Xrpc_jack_internal_clientunload, 5, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_internal_clientunload_t)}, { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xrpc_jack_client_rt_notify, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_rt_notify_t)}, + (mig_stub_routine_t) _Xrpc_jack_client_rt_notify, 4, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__rpc_jack_client_rt_notify_t)}, } }; diff --git a/macosx/RPC/JackRPCEngineUser.c b/macosx/RPC/JackRPCEngineUser.c index f6e5b3f0..e86e8cfc 100644 --- a/macosx/RPC/JackRPCEngineUser.c +++ b/macosx/RPC/JackRPCEngineUser.c @@ -1,7 +1,7 @@ /* * IDENTIFICATION: - * stub generated Mon Sep 1 17:42:28 2008 - * with a MiG generated Tue Feb 19 02:01:43 PST 2008 by root@b75.local + * stub generated Fri Oct 23 10:35:08 2009 + * with a MiG generated Mon May 18 09:59:33 PDT 2009 by root@sulitlana.apple.com * OPTIONS: */ #define __MIG_check__Reply__JackRPCEngine_subsystem__ 1 @@ -50,15 +50,15 @@ #ifndef __MachMsgErrorWithTimeout #define __MachMsgErrorWithTimeout(_R_) { \ switch (_R_) { \ - case MACH_SEND_INVALID_REPLY: \ - case MACH_RCV_INVALID_NAME: \ - case MACH_RCV_PORT_DIED: \ - case MACH_RCV_PORT_CHANGED: \ - case MACH_RCV_TIMED_OUT: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ break; \ + case MACH_SEND_TIMED_OUT: \ + case MACH_RCV_TIMED_OUT: \ default: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ } \ } #endif /* __MachMsgErrorWithTimeout */ @@ -66,14 +66,13 @@ #ifndef __MachMsgErrorWithoutTimeout #define __MachMsgErrorWithoutTimeout(_R_) { \ switch (_R_) { \ - case MACH_SEND_INVALID_REPLY: \ - case MACH_RCV_INVALID_NAME: \ - case MACH_RCV_PORT_DIED: \ - case MACH_RCV_PORT_CHANGED: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ break; \ default: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ } \ } #endif /* __MachMsgErrorWithoutTimeout */ @@ -399,8 +398,9 @@ mig_internal kern_return_t __MIG_check__Reply__rpc_jack_client_open_t(__Reply__r #if __MigTypeCheck if (Out0P->private_port.type != MACH_MSG_PORT_DESCRIPTOR || - Out0P->private_port.disposition != 17) - { return MIG_TYPE_ERROR; } + Out0P->private_port.disposition != 17) { + return MIG_TYPE_ERROR; + } #endif /* __MigTypeCheck */ #if defined(__NDR_convert__int_rep__Reply__rpc_jack_client_open_t__shared_engine__defined) || \ @@ -561,7 +561,7 @@ mig_external kern_return_t rpc_jack_client_open InP->NDR = NDR_record; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->pid = pid; @@ -628,11 +628,11 @@ mig_external kern_return_t rpc_jack_client_open #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ @@ -692,11 +692,11 @@ mig_external kern_return_t rpc_jack_client_open #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ @@ -756,11 +756,11 @@ mig_external kern_return_t rpc_jack_client_open #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined #define __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Reply__rpc_jack_client_check_t__client_name_res__defined */ @@ -983,7 +983,7 @@ mig_external kern_return_t rpc_jack_client_check InP->NDR = NDR_record; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->protocol = protocol; @@ -1011,7 +1011,7 @@ mig_external kern_return_t rpc_jack_client_check { return check_result; } #endif /* defined(__MIG_check__Reply__rpc_jack_client_check_t__defined) */ - (void) mig_strncpy(client_name_res, Out0P->client_name_res, 128); + (void) mig_strncpy(client_name_res, Out0P->client_name_res, 64); *status = Out0P->status; @@ -4739,11 +4739,11 @@ mig_external kern_return_t rpc_jack_set_timebase_callback #elif defined(__NDR_convert__int_rep__JackRPCEngine__string__defined) #define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__int_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__int_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__int_rep__string__defined) #define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__int_rep__string(a, f, 128) + __NDR_convert__int_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__int_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ @@ -4782,11 +4782,11 @@ mig_external kern_return_t rpc_jack_set_timebase_callback #elif defined(__NDR_convert__char_rep__JackRPCEngine__string__defined) #define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__char_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__char_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__char_rep__string__defined) #define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__char_rep__string(a, f, 128) + __NDR_convert__char_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__char_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ @@ -4825,11 +4825,11 @@ mig_external kern_return_t rpc_jack_set_timebase_callback #elif defined(__NDR_convert__float_rep__JackRPCEngine__string__defined) #define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__float_rep__JackRPCEngine__string(a, f, 128) + __NDR_convert__float_rep__JackRPCEngine__string(a, f, 64) #elif defined(__NDR_convert__float_rep__string__defined) #define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined #define __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res(a, f) \ - __NDR_convert__float_rep__string(a, f, 128) + __NDR_convert__float_rep__string(a, f, 64) #endif /* defined(__NDR_convert__*__defined) */ #endif /* __NDR_convert__float_rep__Reply__rpc_jack_get_internal_clientname_t__client_name_res__defined */ @@ -5040,7 +5040,7 @@ mig_external kern_return_t rpc_jack_get_internal_clientname { return check_result; } #endif /* defined(__MIG_check__Reply__rpc_jack_get_internal_clientname_t__defined) */ - (void) mig_strncpy(client_name_res, Out0P->client_name_res, 128); + (void) mig_strncpy(client_name_res, Out0P->client_name_res, 64); *result = Out0P->result; @@ -5431,7 +5431,7 @@ mig_external kern_return_t rpc_jack_internal_clienthandle InP->refnum = refnum; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); @@ -5854,11 +5854,11 @@ mig_external kern_return_t rpc_jack_internal_clientload InP->refnum = refnum; - (void) mig_strncpy(InP->client_name, client_name, 128); + (void) mig_strncpy(InP->client_name, client_name, 64); - (void) mig_strncpy(InP->so_name, so_name, 1024); + (void) mig_strncpy(InP->so_name, so_name, 256); - (void) mig_strncpy(InP->objet_data, objet_data, 1024); + (void) mig_strncpy(InP->objet_data, objet_data, 256); InP->options = options; diff --git a/macosx/RPC/Jackdefs.h b/macosx/RPC/Jackdefs.h index 5636c37e..5e73d984 100644 --- a/macosx/RPC/Jackdefs.h +++ b/macosx/RPC/Jackdefs.h @@ -18,7 +18,8 @@ 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_name_t[128]; typedef char client_port_type_t[128]; typedef char so_name_t[256]; typedef char objet_data_t[256]; +typedef char message_t[256]; diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index a0222cab..cb05d622 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -21,9 +21,25 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackError.h" #include +#include + namespace Jack { +static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) +{ + jack_log("- - - - - - - - - - - - - - - - - - - -"); + jack_log(" Sample Rate:%f", inDesc->mSampleRate); + jack_log(" Format ID:%.*s", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); + jack_log(" Format Flags:%lX", inDesc->mFormatFlags); + jack_log(" Bytes per Packet:%ld", inDesc->mBytesPerPacket); + jack_log(" Frames per Packet:%ld", inDesc->mFramesPerPacket); + jack_log(" Bytes per Frame:%ld", inDesc->mBytesPerFrame); + jack_log(" Channels per Frame:%ld", inDesc->mChannelsPerFrame); + jack_log(" Bits per Channel:%ld", inDesc->mBitsPerChannel); + jack_log("- - - - - - - - - - - - - - - - - - - -"); +} + static OSStatus DisplayDeviceNames() { UInt32 size; @@ -162,70 +178,30 @@ OSStatus JackCoreAudioAdapter::SRNotificationCallback(AudioDeviceID inDevice, } // A better implementation would try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) - OSStatus JackCoreAudioAdapter::DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { - JackCoreAudioAdapter* driver = (JackCoreAudioAdapter*)inClientData; - + switch (inPropertyID) { + + case kAudioDeviceProcessorOverload: { + jack_error("JackCoreAudioAdapter::DeviceNotificationCallback kAudioDeviceProcessorOverload"); + break; + } - case kAudioDevicePropertyStreamConfiguration: + case kAudioDevicePropertyStreamConfiguration: { + jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration"); + return kAudioHardwareUnsupportedOperationError; + } + case kAudioDevicePropertyNominalSampleRate: { - - UInt32 outSize = sizeof(Float64); - Float64 sampleRate; - int in_nChannels = 0; - int out_nChannels = 0; - char capture_driver_name[256]; - char playback_driver_name[256]; - - // Stop and restart - AudioOutputUnitStop(driver->fAUHAL); - driver->RemoveListeners(); - driver->CloseAUHAL(); - - OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); - if (err != noErr) { - jack_error("Cannot get current sample rate"); - printError(err); - } - jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyNominalSampleRate %ld", long(sampleRate)); - - if (driver->SetupDevices(driver->fCaptureUID, driver->fPlaybackUID, capture_driver_name, playback_driver_name) < 0) - return -1; - - if (driver->SetupChannels(driver->fCapturing, driver->fPlaying, driver->fCaptureChannels, driver->fPlaybackChannels, in_nChannels, out_nChannels, false) < 0) - return -1; - - if (driver->SetupBufferSizeAndSampleRate(driver->fAdaptedBufferSize, sampleRate) < 0) - return -1; - - driver->SetAdaptedSampleRate(sampleRate); - - if (driver->OpenAUHAL(driver->fCapturing, - driver->fPlaying, - driver->fCaptureChannels, - driver->fPlaybackChannels, - in_nChannels, - out_nChannels, - driver->fAdaptedBufferSize, - sampleRate, - false) < 0) - goto error; - - if (driver->AddListeners() < 0) - goto error; - - AudioOutputUnitStart(driver->fAUHAL); - return noErr; -error: - driver->CloseAUHAL(); - break; + jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate"); + return kAudioHardwareUnsupportedOperationError; } + } return noErr; } @@ -235,7 +211,13 @@ int JackCoreAudioAdapter::AddListeners() OSStatus err = noErr; // Add listeners - + err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback, this); + if (err != noErr) { + jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDeviceProcessorOverload"); + printError(err); + return -1; + } + err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioHardwarePropertyDevices"); @@ -274,9 +256,9 @@ int JackCoreAudioAdapter::AddListeners() return 0; } - void JackCoreAudioAdapter::RemoveListeners() { + AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDeviceProcessorOverload, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioHardwarePropertyDevices, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, DeviceNotificationCallback); AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyDeviceIsRunning, DeviceNotificationCallback); @@ -311,19 +293,34 @@ OSStatus JackCoreAudioAdapter::Render(void *inRefCon, JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) :JackAudioAdapterInterface(buffer_size, sample_rate), fInputData(0), fCapturing(false), fPlaying(false), fState(false) { - const JSList* node; const jack_driver_param_t* param; - + int in_nChannels = 0; + int out_nChannels = 0; char captureName[256]; char playbackName[256]; - fCaptureUID[0] = 0; fPlaybackUID[0] = 0; + fClockDriftCompensate = false; // Default values - fCaptureChannels = 0; - fPlaybackChannels = 0; + fCaptureChannels = -1; + fPlaybackChannels = -1; + + SInt32 major; + SInt32 minor; + Gestalt(gestaltSystemVersionMajor, &major); + Gestalt(gestaltSystemVersionMinor, &minor); + + // Starting with 10.6 systems, the HAL notification thread is created internally + if (major == 10 && minor >= 6) { + CFRunLoopRef theRunLoop = NULL; + AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + OSStatus theError = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); + if (theError != noErr) { + jack_error("JackCoreAudioAdapter::Open kAudioHardwarePropertyRunLoop error"); + } + } for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; @@ -381,6 +378,10 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra fRingbufferCurSize = param->value.ui; fAdaptative = false; break; + + case 's': + fClockDriftCompensate = true; + break; } } @@ -389,26 +390,26 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra fCapturing = true; fPlaying = true; } - - int in_nChannels = 0; - int out_nChannels = 0; - if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName) < 0) + if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0) throw -1; if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0) throw -1; + + if (SetupBufferSize(fAdaptedBufferSize) < 0) + throw -1; - if (SetupBufferSizeAndSampleRate(fAdaptedBufferSize, fAdaptedSampleRate) < 0) + if (SetupSampleRate(fAdaptedSampleRate) < 0) throw -1; - + + if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate) < 0) + throw -1; + if (fCapturing && fCaptureChannels > 0) if (SetupBuffers(fCaptureChannels) < 0) throw -1; - - if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate, true) < 0) - throw -1; - + if (AddListeners() < 0) throw -1; } @@ -428,7 +429,7 @@ OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id) jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); - // Get the device only if default input and ouput are the same + // Get the device only if default input and output are the same if (inDefault == outDefault) { *id = inDefault; return noErr; @@ -516,26 +517,43 @@ OSStatus JackCoreAudioAdapter::GetDeviceNameFromID(AudioDeviceID id, char* name) int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, - char* playback_driver_name) + char* playback_driver_name, + jack_nframes_t samplerate) { capture_driver_name[0] = 0; playback_driver_name[0] = 0; // Duplex if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { - jack_log("JackCoreAudioAdapter::Open duplex"); - if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { - if (GetDefaultDevice(&fDeviceID) != noErr) { - jack_error("Cannot open default device"); + + // Same device for capture and playback... + if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { + + if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { + jack_log("Will take default in/out"); + if (GetDefaultDevice(&fDeviceID) != noErr) { + jack_error("Cannot open default device"); + return -1; + } + } + if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { + jack_error("Cannot get device name from device ID"); return -1; } - } - if (GetDeviceNameFromID(fDeviceID, capture_driver_name) != noErr || GetDeviceNameFromID(fDeviceID, playback_driver_name) != noErr) { - jack_error("Cannot get device name from device ID"); - return -1; + + } else { + + // Creates aggregate device + AudioDeviceID captureID, playbackID; + if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) + return -1; + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) + return -1; + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) + return -1; } - // Capture only + // Capture only } else if (strcmp(capture_driver_uid, "") != 0) { jack_log("JackCoreAudioAdapter::Open capture only"); if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) { @@ -549,7 +567,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, return -1; } - // Playback only + // Playback only } else if (strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioAdapter::Open playback only"); if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { @@ -563,7 +581,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, return -1; } - // Use default driver in duplex mode + // Use default driver in duplex mode } else { jack_log("JackCoreAudioAdapter::Open default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { @@ -623,72 +641,82 @@ int JackCoreAudioAdapter::SetupChannels(bool capturing, return -1; } - if (inchannels == 0) { + if (inchannels == -1) { jack_log("Setup max in channels = %ld", in_nChannels); inchannels = in_nChannels; } - if (outchannels == 0) { + if (outchannels == -1) { jack_log("Setup max out channels = %ld", out_nChannels); outchannels = out_nChannels; } - + return 0; } -int JackCoreAudioAdapter::SetupBufferSizeAndSampleRate(jack_nframes_t nframes, jack_nframes_t samplerate) +int JackCoreAudioAdapter::SetupBufferSize(jack_nframes_t buffer_size) { - OSStatus err = noErr; - UInt32 outSize; - Float64 sampleRate; - // Setting buffer size - outSize = sizeof(UInt32); - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &nframes); + UInt32 outSize = sizeof(UInt32); + OSStatus err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); if (err != noErr) { - jack_error("Cannot set buffer size %ld", nframes); + jack_error("Cannot set buffer size %ld", buffer_size); printError(err); return -1; } + + return 0; +} +int JackCoreAudioAdapter::SetupSampleRate(jack_nframes_t samplerate) +{ + return SetupSampleRateAux(fDeviceID, samplerate); +} + +int JackCoreAudioAdapter::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate) +{ + OSStatus err = noErr; + UInt32 outSize; + Float64 sampleRate; + // Get sample rate outSize = sizeof(Float64); - err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); return -1; } - + // If needed, set new sample rate if (samplerate != (jack_nframes_t)sampleRate) { sampleRate = (Float64)samplerate; - + // To get SR change notification - err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); + err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate"); printError(err); return -1; } - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); + err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); if (err != noErr) { jack_error("Cannot set sample rate = %ld", samplerate); printError(err); return -1; } - + // Waiting for SR change notification int count = 0; - while (!fState && count++ < 100) { + while (!fState && count++ < WAIT_COUNTER) { usleep(100000); - jack_log("Wait count = %ld", count); + jack_log("Wait count = %d", count); } - + // Remove SR change notification - AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); + AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); } - + return 0; } @@ -698,10 +726,6 @@ int JackCoreAudioAdapter::SetupBuffers(int inchannels) // Prepare buffers fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); - if (fInputData == 0) { - jack_error("Cannot allocate memory for input buffers"); - return -1; - } fInputData->mNumberBuffers = inchannels; for (int i = 0; i < fCaptureChannels; i++) { fInputData->mBuffers[i].mNumberChannels = 1; @@ -722,20 +746,21 @@ void JackCoreAudioAdapter::DisposeBuffers() } int JackCoreAudioAdapter::OpenAUHAL(bool capturing, - bool playing, - int inchannels, - int outchannels, - int in_nChannels, - int out_nChannels, - jack_nframes_t buffer_size, - jack_nframes_t samplerate, - bool strict) + bool playing, + int inchannels, + int outchannels, + int in_nChannels, + int out_nChannels, + jack_nframes_t buffer_size, + jack_nframes_t samplerate) { ComponentResult err1; UInt32 enableIO; AudioStreamBasicDescription srcFormat, dstFormat; + AudioDeviceID currAudioDeviceID; + UInt32 size; - jack_log("OpenAUHAL capturing = %ld playing = %ld inchannels = %ld outchannels = %ld in_nChannels = %ld out_nChannels = %ld ", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); + jack_log("OpenAUHAL capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); if (inchannels == 0 && outchannels == 0) { jack_error("No input and output channels..."); @@ -750,14 +775,14 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling OpenAComponent"); printError(err1); - return -1; + goto error; } err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { jack_error("Cannot initialize AUHAL unit"); printError(err1); - return -1; + goto error; } // Start I/O @@ -773,8 +798,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); printError(err1); - if (strict) - return -1; + goto error; } if (playing && outchannels > 0) { @@ -789,18 +813,15 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); printError(err1); - if (strict) - return -1; + goto error; } - AudioDeviceID currAudioDeviceID; - UInt32 size = sizeof(AudioDeviceID); + size = sizeof(AudioDeviceID); err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); - if (strict) - return -1; + goto error; } else { jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); } @@ -810,28 +831,16 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); - if (strict) - return -1; + goto error; } - - err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); - if (err1 != noErr) { - jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); - printError(err1); - if (strict) - return -1; - } else { - jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); - } - + // Set buffer size if (capturing && inchannels > 0) { err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); - if (strict) - return -1; + goto error; } } @@ -840,8 +849,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); - if (strict) - return -1; + goto error; } } @@ -858,6 +866,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1"); printError(err1); + goto error; } } @@ -873,40 +882,71 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0"); printError(err1); + goto error; } } // Setup stream converters - jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); - srcFormat.mSampleRate = samplerate; - srcFormat.mFormatID = kAudioFormatLinearPCM; - srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - srcFormat.mBytesPerPacket = sizeof(float); - srcFormat.mFramesPerPacket = 1; - srcFormat.mBytesPerFrame = sizeof(float); - srcFormat.mChannelsPerFrame = outchannels; - srcFormat.mBitsPerChannel = 32; - - err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); - printError(err1); + if (capturing && inchannels > 0) { + + size = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); + if (err1 != noErr) { + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + printError(err1); + goto error; + } + PrintStreamDesc(&srcFormat); + + jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); + srcFormat.mSampleRate = samplerate; + srcFormat.mFormatID = kAudioFormatLinearPCM; + srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + srcFormat.mBytesPerPacket = sizeof(float); + srcFormat.mFramesPerPacket = 1; + srcFormat.mBytesPerFrame = sizeof(float); + srcFormat.mChannelsPerFrame = inchannels; + srcFormat.mBitsPerChannel = 32; + PrintStreamDesc(&srcFormat); + + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); + + if (err1 != noErr) { + jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + printError(err1); + goto error; + } } - jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); - dstFormat.mSampleRate = samplerate; - dstFormat.mFormatID = kAudioFormatLinearPCM; - dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - dstFormat.mBytesPerPacket = sizeof(float); - dstFormat.mFramesPerPacket = 1; - dstFormat.mBytesPerFrame = sizeof(float); - dstFormat.mChannelsPerFrame = inchannels; - dstFormat.mBitsPerChannel = 32; - - err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); - printError(err1); + if (playing && outchannels > 0) { + + size = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); + if (err1 != noErr) { + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + printError(err1); + goto error; + } + PrintStreamDesc(&dstFormat); + + jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); + dstFormat.mSampleRate = samplerate; + dstFormat.mFormatID = kAudioFormatLinearPCM; + dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + dstFormat.mBytesPerPacket = sizeof(float); + dstFormat.mFramesPerPacket = 1; + dstFormat.mBytesPerFrame = sizeof(float); + dstFormat.mChannelsPerFrame = outchannels; + dstFormat.mBitsPerChannel = 32; + PrintStreamDesc(&dstFormat); + + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); + + if (err1 != noErr) { + jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + printError(err1); + goto error; + } } // Setup callbacks @@ -918,7 +958,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1"); printError(err1); - return -1; + goto error; } } else { AURenderCallbackStruct output; @@ -928,11 +968,448 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0"); printError(err1); - return -1; + goto error; } } return 0; + +error: + CloseAUHAL(); + return -1; +} + +OSStatus JackCoreAudioAdapter::DestroyAggregateDevice() +{ + OSStatus osErr = noErr; + AudioObjectPropertyAddress pluginAOPA; + pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice; + pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; + pluginAOPA.mElement = kAudioObjectPropertyElementMaster; + UInt32 outDataSize; + + osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); + printError(osErr); + return osErr; + } + + osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error"); + printError(osErr); + return osErr; + } + + return noErr; +} + +static CFStringRef GetDeviceName(AudioDeviceID id) +{ + UInt32 size = sizeof(CFStringRef); + CFStringRef UIname; + OSStatus err = AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceUID, &size, &UIname); + return (err == noErr) ? UIname : NULL; +} + +OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) +{ + OSStatus err = noErr; + AudioObjectID sub_device[32]; + UInt32 outSize = sizeof(sub_device); + + err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); + vector captureDeviceIDArray; + + if (err != noErr) { + jack_log("Input device does not have subdevices"); + captureDeviceIDArray.push_back(captureDeviceID); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Input device has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + captureDeviceIDArray.push_back(sub_device[i]); + } + } + + err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); + vector playbackDeviceIDArray; + + if (err != noErr) { + jack_log("Output device does not have subdevices"); + playbackDeviceIDArray.push_back(playbackDeviceID); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Output device has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + playbackDeviceIDArray.push_back(sub_device[i]); + } + } + + return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); +} + +OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) +{ + OSStatus osErr = noErr; + UInt32 outSize; + Boolean outWritable; + + // Prepare sub-devices for clock drift compensation + // Workaround for bug in the HAL : until 10.6.2 + AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + UInt32 theQualifierDataSize = sizeof(AudioObjectID); + AudioClassID inClass = kAudioSubDeviceClassID; + void* theQualifierData = &inClass; + UInt32 subDevicesNum = 0; + + //--------------------------------------------------------------------------- + // Setup SR of both devices otherwise creating AD may fail... + //--------------------------------------------------------------------------- + UInt32 keptclockdomain = 0; + UInt32 clockdomain = 0; + outSize = sizeof(UInt32); + bool need_clock_drift_compensation = false; + + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); + } else { + // Check clock domain + osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); + if (osErr != 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + printError(osErr); + } else { + keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; + jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); + if (clockdomain != 0 && clockdomain != keptclockdomain) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); + need_clock_drift_compensation = true; + } + } + } + } + + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); + } else { + // Check clock domain + osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); + if (osErr != 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + printError(osErr); + } else { + keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; + jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); + if (clockdomain != 0 && clockdomain != keptclockdomain) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); + need_clock_drift_compensation = true; + } + } + } + } + + // If no valid clock domain was found, then assume we have to compensate... + if (keptclockdomain == 0) { + need_clock_drift_compensation = true; + } + + //--------------------------------------------------------------------------- + // Start to create a new aggregate by getting the base audio hardware plugin + //--------------------------------------------------------------------------- + + char device_name[256]; + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + GetDeviceNameFromID(captureDeviceID[i], device_name); + jack_info("Separated input = '%s' ", device_name); + } + + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + GetDeviceNameFromID(playbackDeviceID[i], device_name); + jack_info("Separated output = '%s' ", device_name); + } + + osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); + printError(osErr); + return osErr; + } + + AudioValueTranslation pluginAVT; + + CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); + + pluginAVT.mInputData = &inBundleRef; + pluginAVT.mInputDataSize = sizeof(inBundleRef); + pluginAVT.mOutputData = &fPluginID; + pluginAVT.mOutputDataSize = sizeof(fPluginID); + + osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); + printError(osErr); + return osErr; + } + + //------------------------------------------------- + // Create a CFDictionary for our aggregate device + //------------------------------------------------- + + CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); + CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); + + // add the name of the device to the dictionary + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); + + // add our choice of UID for the aggregate device to the dictionary + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); + + // add a "private aggregate key" to the dictionary + int value = 1; + CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); + + SInt32 system; + Gestalt(gestaltSystemVersion, &system); + + jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); + + // Starting with 10.5.4 systems, the AD can be internal... (better) + if (system < 0x00001054) { + jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); + } else { + jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); + } + + // Prepare sub-devices for clock drift compensation + CFMutableArrayRef subDevicesArrayClock = NULL; + + /* + if (fClockDriftCompensate) { + if (need_clock_drift_compensation) { + jack_info("Clock drift compensation activated..."); + subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + CFStringRef UID = GetDeviceName(captureDeviceID[i]); + if (UID) { + CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); + //CFRelease(UID); + CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); + } + } + + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + CFStringRef UID = GetDeviceName(playbackDeviceID[i]); + if (UID) { + CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); + //CFRelease(UID); + CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); + } + } + + // add sub-device clock array for the aggregate device to the dictionary + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); + } else { + jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); + } + } + */ + + //------------------------------------------------- + // Create a CFMutableArray for our sub-device list + //------------------------------------------------- + + // we need to append the UID for each device to a CFMutableArray, so create one here + CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + vector captureDeviceUID; + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + CFStringRef ref = GetDeviceName(captureDeviceID[i]); + if (ref == NULL) + return -1; + captureDeviceUID.push_back(ref); + // input sub-devices in this example, so append the sub-device's UID to the CFArray + CFArrayAppendValue(subDevicesArray, ref); + } + + vector playbackDeviceUID; + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + CFStringRef ref = GetDeviceName(playbackDeviceID[i]); + if (ref == NULL) + return -1; + playbackDeviceUID.push_back(ref); + // output sub-devices in this example, so append the sub-device's UID to the CFArray + CFArrayAppendValue(subDevicesArray, ref); + } + + //----------------------------------------------------------------------- + // Feed the dictionary to the plugin, to create a blank aggregate device + //----------------------------------------------------------------------- + + AudioObjectPropertyAddress pluginAOPA; + pluginAOPA.mSelector = kAudioPlugInCreateAggregateDevice; + pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; + pluginAOPA.mElement = kAudioObjectPropertyElementMaster; + UInt32 outDataSize; + + osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); + printError(osErr); + goto error; + } + + osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error"); + printError(osErr); + goto error; + } + + // pause for a bit to make sure that everything completed correctly + // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); + + //------------------------- + // Set the sub-device list + //------------------------- + + pluginAOPA.mSelector = kAudioAggregateDevicePropertyFullSubDeviceList; + pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; + pluginAOPA.mElement = kAudioObjectPropertyElementMaster; + outDataSize = sizeof(CFMutableArrayRef); + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); + printError(osErr); + goto error; + } + + // pause again to give the changes time to take effect + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); + + //----------------------- + // Set the master device + //----------------------- + + // set the master device manually (this is the device which will act as the master clock for the aggregate device) + // pass in the UID of the device you want to use + pluginAOPA.mSelector = kAudioAggregateDevicePropertyMasterSubDevice; + pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; + pluginAOPA.mElement = kAudioObjectPropertyElementMaster; + outDataSize = sizeof(CFStringRef); + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); + printError(osErr); + goto error; + } + + // pause again to give the changes time to take effect + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); + + // Prepare sub-devices for clock drift compensation + // Workaround for bug in the HAL : until 10.6.2 + + if (fClockDriftCompensate) { + if (need_clock_drift_compensation) { + jack_info("Clock drift compensation activated..."); + + // Get the property data size + osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); + printError(osErr); + } + + // Calculate the number of object IDs + subDevicesNum = outSize / sizeof(AudioObjectID); + jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); + AudioObjectID subDevices[subDevicesNum]; + outSize = sizeof(subDevices); + + osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); + printError(osErr); + } + + // Set kAudioSubDevicePropertyDriftCompensation property... + for (UInt32 index = 0; index < subDevicesNum; ++index) { + UInt32 theDriftCompensationValue = 1; + osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); + printError(osErr); + } + } + } else { + jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); + } + } + + // pause again to give the changes time to take effect + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); + + //---------- + // Clean up + //---------- + + // release the private AD key + CFRelease(AggregateDeviceNumberRef); + + // release the CF objects we have created - we don't need them any more + CFRelease(aggDeviceDict); + CFRelease(subDevicesArray); + + if (subDevicesArrayClock) + CFRelease(subDevicesArrayClock); + + // release the device UID + for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { + CFRelease(captureDeviceUID[i]); + } + + for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { + CFRelease(playbackDeviceUID[i]); + } + + jack_log("New aggregate device %ld", *outAggregateDevice); + return noErr; + +error: + DestroyAggregateDevice(); + return -1; +} + + +bool JackCoreAudioAdapter::IsAggregateDevice(AudioDeviceID device) +{ + OSStatus err = noErr; + AudioObjectID sub_device[32]; + UInt32 outSize = sizeof(sub_device); + err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); + + if (err != noErr) { + jack_log("Device does not have subdevices"); + return false; + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Device does has %d subdevices", num_devices); + return true; + } } void JackCoreAudioAdapter::CloseAUHAL() @@ -955,6 +1432,8 @@ int JackCoreAudioAdapter::Close() DisposeBuffers(); CloseAUHAL(); RemoveListeners(); + if (fPluginID > 0) + DestroyAggregateDevice(); return 0; } @@ -986,47 +1465,45 @@ extern "C" strcpy(desc->name, "audioadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "netjack audio <==> net backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 12; + desc->nparams = 13; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; strcpy(desc->params[i].name, "channels"); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of channels. If -1, max possible number of channels will be used"); i++; strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of input channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of input channels. If -1, max possible number of input channels will be used"); i++; strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of output channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of output channels. If -1, max possible number of output channels will be used"); i++; strcpy(desc->params[i].name, "capture"); desc->params[i].character = 'C'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio input device"); - strcpy(desc->params[i].short_desc, "Provide capture ports. Optionally set CoreAudio device name"); + strcpy(desc->params[i].short_desc, "Input CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; strcpy(desc->params[i].name, "playback"); desc->params[i].character = 'P'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio output device"); - strcpy(desc->params[i].short_desc, "Provide playback ports. Optionally set CoreAudio device name"); + strcpy(desc->params[i].short_desc, "Output CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; @@ -1038,11 +1515,11 @@ extern "C" strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; - strcpy(desc->params[i].name, "periodsize"); + strcpy(desc->params[i].name, "period"); desc->params[i].character = 'p'; desc->params[i].type = JackDriverParamUInt; desc->params[i].value.ui = 512U; - strcpy(desc->params[i].short_desc, "Period size"); + strcpy(desc->params[i].short_desc, "Frames per period"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; @@ -1057,7 +1534,6 @@ extern "C" strcpy(desc->params[i].name, "device"); desc->params[i].character = 'd'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio device name"); strcpy(desc->params[i].short_desc, "CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -1084,7 +1560,15 @@ extern "C" desc->params[i].value.ui = 32768; strcpy(desc->params[i].short_desc, "Fixed ringbuffer size"); strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)"); - + + i++; + strcpy(desc->params[i].name, "clock-drift"); + desc->params[i].character = 's'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = FALSE; + strcpy(desc->params[i].short_desc, "Clock drift compensation"); + strcpy(desc->params[i].long_desc, "Whether to compensate clock drift in dynamically created aggregate device"); + return desc; } diff --git a/macosx/coreaudio/JackCoreAudioAdapter.h b/macosx/coreaudio/JackCoreAudioAdapter.h index b40f7b65..8ef6e4d2 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.h +++ b/macosx/coreaudio/JackCoreAudioAdapter.h @@ -27,6 +27,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include +#include + +using namespace std; + namespace Jack { @@ -36,6 +40,8 @@ typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) +#define WAIT_COUNTER 60 + /*! \brief Audio adapter using CoreAudio API. */ @@ -54,11 +60,14 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface bool fCapturing; bool fPlaying; - AudioDeviceID fDeviceID; + AudioDeviceID fDeviceID; // Used "duplex" device + AudioObjectID fPluginID; // Used for aggregate device + bool fState; AudioUnitRenderActionFlags* fActionFags; AudioTimeStamp* fCurrentTime; + bool fClockDriftCompensate; static OSStatus Render(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, @@ -86,10 +95,16 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); // Setup + OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); + OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); + OSStatus DestroyAggregateDevice(); + bool IsAggregateDevice(AudioDeviceID device); + int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, - char* playback_driver_name); + char* playback_driver_name, + jack_nframes_t samplerate); int SetupChannels(bool capturing, bool playing, @@ -106,10 +121,12 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface int in_nChannels, int out_nChannels, jack_nframes_t buffer_size, - jack_nframes_t samplerate, - bool strict); + jack_nframes_t samplerate); - int SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size, jack_nframes_t samplerate); + int SetupBufferSize(jack_nframes_t buffer_size); + int SetupSampleRate(jack_nframes_t samplerate); + int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate); + int SetupBuffers(int inchannels); void DisposeBuffers(); void CloseAUHAL(); diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 6c2222e7..e540a164 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -25,15 +25,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackClientControl.h" #include "JackDriverLoader.h" #include "JackGlobals.h" +#include "JackTools.h" #include "JackCompilerDeps.h" #include #include +#include namespace Jack { -static void Print4CharCode(char* msg, long c) +static void Print4CharCode(const char* msg, long c) { UInt32 __4CC_number = (c); char __4CC_string[5]; @@ -42,6 +44,20 @@ static void Print4CharCode(char* msg, long c) jack_log("%s'%s'", (msg), __4CC_string); } +static void PrintStreamDesc(AudioStreamBasicDescription *inDesc) +{ + jack_log("- - - - - - - - - - - - - - - - - - - -"); + jack_log(" Sample Rate:%f", inDesc->mSampleRate); + jack_log(" Format ID:%.*s", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID); + jack_log(" Format Flags:%lX", inDesc->mFormatFlags); + jack_log(" Bytes per Packet:%ld", inDesc->mBytesPerPacket); + jack_log(" Frames per Packet:%ld", inDesc->mFramesPerPacket); + jack_log(" Bytes per Frame:%ld", inDesc->mBytesPerFrame); + jack_log(" Channels per Frame:%ld", inDesc->mChannelsPerFrame); + jack_log(" Bits per Channel:%ld", inDesc->mBitsPerChannel); + jack_log("- - - - - - - - - - - - - - - - - - - -\n"); +} + static void printError(OSStatus err) { switch (err) { @@ -218,7 +234,15 @@ OSStatus JackCoreAudioDriver::MeasureCallback(AudioDeviceID inDevice, AudioDeviceStop(driver->fDeviceID, MeasureCallback); jack_log("JackCoreAudioDriver::MeasureCallback called"); - JackMachThread::GetParams(&driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); + JackMachThread::GetParams(pthread_self(), &driver->fEngineControl->fPeriod, &driver->fEngineControl->fComputation, &driver->fEngineControl->fConstraint); + + if (driver->fComputationGrain > 0) { + jack_log("JackCoreAudioDriver::MeasureCallback : RT thread computation setup to %d percent of period", int(driver->fComputationGrain * 100)); + driver->fEngineControl->fComputation = driver->fEngineControl->fPeriod * driver->fComputationGrain; + } + + // Signal waiting start function... + driver->fState = true; // Setup threadded based log function set_threaded_log_function(); @@ -245,8 +269,7 @@ OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, return noErr; } -// A better implementation would try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) - +// A better implementation would possibly try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, @@ -256,87 +279,30 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { - + case kAudioDeviceProcessorOverload: { jack_error("JackCoreAudioDriver::DeviceNotificationCallback kAudioDeviceProcessorOverload"); jack_time_t cur_time = GetMicroSeconds(); driver->NotifyXRun(cur_time, float(cur_time - driver->fBeginDateUst)); // Better this value than nothing... break; - } - + } + case kAudioDevicePropertyStreamConfiguration: { - jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration : server may not work correctly anymore..."); - return kAudioHardwareUnsupportedOperationError; - } - - case kAudioDevicePropertyNominalSampleRate: { - jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate : server may not work correctly anymore..."); + jack_error("Cannot handle kAudioDevicePropertyStreamConfiguration : server will quit..."); + driver->NotifyFailure(JackBackendError, "Another application has changed the device configuration."); // Message length limited to JACK_MESSAGE_SIZE + driver->CloseAUHAL(); + kill(JackTools::GetPID(), SIGINT); return kAudioHardwareUnsupportedOperationError; - } - - /* + } + case kAudioDevicePropertyNominalSampleRate: { - - UInt32 outSize = sizeof(Float64); - Float64 sampleRate; - int in_nChannels = 0; - int out_nChannels = 0; - char capture_driver_name[256]; - char playback_driver_name[256]; - CFStringRef ref; - - // Stop and restart - driver->Stop(); - driver->RemoveListeners(); - driver->CloseAUHAL(); - - OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); - if (err != noErr) { - jack_error("Cannot get current sample rate"); - printError(err); - } - jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyNominalSampleRate %ld", long(sampleRate)); - - if (driver->SetupDevices(driver->fCaptureUID, driver->fPlaybackUID, capture_driver_name, playback_driver_name) < 0) - return -1; - - if (driver->SetupChannels(driver->fCapturing, driver->fPlaying, driver->fInChannels, driver->fOutChannels, in_nChannels, out_nChannels, false) < 0) - return -1; - - if (driver->SetupBufferSizeAndSampleRate(driver->fEngineControl->fBufferSize, sampleRate) < 0) - return -1; - - if (driver->OpenAUHAL(driver->fCapturing, - driver->fPlaying, - driver->fInChannels, - driver->fOutChannels, - in_nChannels, - out_nChannels, - driver->fEngineControl->fBufferSize, - sampleRate, - false) < 0) - goto error; - - if (driver->AddListeners() < 0) - goto error; - - driver->Start(); - - // Send notification to be used in JackPilot or JackRouter plugin - jack_error("Device restart..."); - ref = CFStringCreateWithCString(NULL, driver->fEngineControl->fServerName, kCFStringEncodingMacRoman); - CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(), - CFSTR("com.grame.jackserver.restart"), - ref, - NULL, - kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions); - CFRelease(ref); - return noErr; -error: + jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate : server will quit..."); + driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE driver->CloseAUHAL(); - break; - } - */ + kill(JackTools::GetPID(), SIGINT); + return kAudioHardwareUnsupportedOperationError; + } + } return noErr; } @@ -372,7 +338,7 @@ OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID* id) jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); - // Get the device only if default input and ouput are the same + // Get the device only if default input and output are the same if (inDefault == outDefault) { *id = inDefault; return noErr; @@ -421,92 +387,306 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe OSStatus err = noErr; UInt32 outSize; Boolean outWritable; - AudioBufferList* bufferList = 0; - + channelCount = 0; err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); if (err == noErr) { - bufferList = (AudioBufferList*)malloc(outSize); + AudioBufferList bufferList[outSize]; err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); if (err == noErr) { for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) channelCount += bufferList->mBuffers[i].mNumberChannels; } - - if (bufferList) - free(bufferList); } - return err; } JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackAudioDriver(name, alias, engine, table), fJackInputData(NULL), fDriverOutputData(NULL), fState(false), fIOUsage(1.f) + : JackAudioDriver(name, alias, engine, table), + fJackInputData(NULL), + fDriverOutputData(NULL), + fPluginID(0), + fState(false), + fHogged(false), + fIOUsage(1.f), + fComputationGrain(-1.f), + fClockDriftCompensate(false) {} JackCoreAudioDriver::~JackCoreAudioDriver() {} -OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, AudioDeviceID* outAggregateDevice) +OSStatus JackCoreAudioDriver::DestroyAggregateDevice() +{ + OSStatus osErr = noErr; + AudioObjectPropertyAddress pluginAOPA; + pluginAOPA.mSelector = kAudioPlugInDestroyAggregateDevice; + pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; + pluginAOPA.mElement = kAudioObjectPropertyElementMaster; + UInt32 outDataSize; + + if (fPluginID > 0) { + + osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyDataSize error"); + printError(osErr); + return osErr; + } + + osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, 0, NULL, &outDataSize, &fDeviceID); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::DestroyAggregateDevice : AudioObjectGetPropertyData error"); + printError(osErr); + return osErr; + } + + } + + return noErr; +} + +OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) +{ + OSStatus err = noErr; + AudioObjectID sub_device[32]; + UInt32 outSize = sizeof(sub_device); + + err = AudioDeviceGetProperty(captureDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); + vector captureDeviceIDArray; + + if (err != noErr) { + jack_log("Input device does not have subdevices"); + captureDeviceIDArray.push_back(captureDeviceID); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Input device has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + captureDeviceIDArray.push_back(sub_device[i]); + } + } + + err = AudioDeviceGetProperty(playbackDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); + vector playbackDeviceIDArray; + + if (err != noErr) { + jack_log("Output device does not have subdevices"); + playbackDeviceIDArray.push_back(playbackDeviceID); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Output device has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + playbackDeviceIDArray.push_back(sub_device[i]); + } + } + + return CreateAggregateDeviceAux(captureDeviceIDArray, playbackDeviceIDArray, samplerate, outAggregateDevice); +} + +OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice) { OSStatus osErr = noErr; UInt32 outSize; Boolean outWritable; + + // Prepare sub-devices for clock drift compensation + // Workaround for bug in the HAL : until 10.6.2 + AudioObjectPropertyAddress theAddressOwned = { kAudioObjectPropertyOwnedObjects, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + AudioObjectPropertyAddress theAddressDrift = { kAudioSubDevicePropertyDriftCompensation, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + UInt32 theQualifierDataSize = sizeof(AudioObjectID); + AudioClassID inClass = kAudioSubDeviceClassID; + void* theQualifierData = &inClass; + UInt32 subDevicesNum = 0; + + //--------------------------------------------------------------------------- + // Setup SR of both devices otherwise creating AD may fail... + //--------------------------------------------------------------------------- + UInt32 keptclockdomain = 0; + UInt32 clockdomain = 0; + outSize = sizeof(UInt32); + bool need_clock_drift_compensation = false; + + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + if (SetupSampleRateAux(captureDeviceID[i], samplerate) < 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device"); + } else { + // Check clock domain + osErr = AudioDeviceGetProperty(captureDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); + if (osErr != 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + printError(osErr); + } else { + keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; + jack_log("JackCoreAudioDriver::CreateAggregateDevice : input clockdomain = %d", clockdomain); + if (clockdomain != 0 && clockdomain != keptclockdomain) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); + need_clock_drift_compensation = true; + } + } + } + } + + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + if (SetupSampleRateAux(playbackDeviceID[i], samplerate) < 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device"); + } else { + // Check clock domain + osErr = AudioDeviceGetProperty(playbackDeviceID[i], 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyClockDomain, &outSize, &clockdomain); + if (osErr != 0) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : kAudioDevicePropertyClockDomain error"); + printError(osErr); + } else { + keptclockdomain = (keptclockdomain == 0) ? clockdomain : keptclockdomain; + jack_log("JackCoreAudioDriver::CreateAggregateDevice : output clockdomain = %d", clockdomain); + if (clockdomain != 0 && clockdomain != keptclockdomain) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : devices do not share the same clock!! clock drift compensation would be needed..."); + need_clock_drift_compensation = true; + } + } + } + } + + // If no valid clock domain was found, then assume we have to compensate... + if (keptclockdomain == 0) { + need_clock_drift_compensation = true; + } - //----------------------- + //--------------------------------------------------------------------------- // Start to create a new aggregate by getting the base audio hardware plugin - //----------------------- - + //--------------------------------------------------------------------------- + + char device_name[256]; + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + GetDeviceNameFromID(captureDeviceID[i], device_name); + jack_info("Separated input = '%s' ", device_name); + } + + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + GetDeviceNameFromID(playbackDeviceID[i], device_name); + jack_info("Separated output = '%s' ", device_name); + } + osErr = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyPlugInForBundleID, &outSize, &outWritable); - if (osErr != noErr) + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetPropertyInfo kAudioHardwarePropertyPlugInForBundleID error"); + printError(osErr); return osErr; + } AudioValueTranslation pluginAVT; CFStringRef inBundleRef = CFSTR("com.apple.audio.CoreAudio"); - AudioObjectID pluginID; - + pluginAVT.mInputData = &inBundleRef; pluginAVT.mInputDataSize = sizeof(inBundleRef); - pluginAVT.mOutputData = &pluginID; - pluginAVT.mOutputDataSize = sizeof(pluginID); + pluginAVT.mOutputData = &fPluginID; + pluginAVT.mOutputDataSize = sizeof(fPluginID); osErr = AudioHardwareGetProperty(kAudioHardwarePropertyPlugInForBundleID, &outSize, &pluginAVT); - if (osErr != noErr) + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioHardwareGetProperty kAudioHardwarePropertyPlugInForBundleID error"); + printError(osErr); return osErr; + } - //----------------------- + //------------------------------------------------- // Create a CFDictionary for our aggregate device - //----------------------- + //------------------------------------------------- CFMutableDictionaryRef aggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFStringRef AggregateDeviceNameRef = CFSTR("JackDuplex"); CFStringRef AggregateDeviceUIDRef = CFSTR("com.grame.JackDuplex"); - + // add the name of the device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceNameKey), AggregateDeviceNameRef); // add our choice of UID for the aggregate device to the dictionary CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceUIDKey), AggregateDeviceUIDRef); - + + // add a "private aggregate key" to the dictionary + int value = 1; + CFNumberRef AggregateDeviceNumberRef = CFNumberCreate(NULL, kCFNumberIntType, &value); + + SInt32 system; + Gestalt(gestaltSystemVersion, &system); + + jack_log("JackCoreAudioDriver::CreateAggregateDevice : system version = %x limit = %x", system, 0x00001054); + + // Starting with 10.5.4 systems, the AD can be internal... (better) + if (system < 0x00001054) { + jack_log("JackCoreAudioDriver::CreateAggregateDevice : public aggregate device...."); + } else { + jack_log("JackCoreAudioDriver::CreateAggregateDevice : private aggregate device...."); + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceIsPrivateKey), AggregateDeviceNumberRef); + } + + // Prepare sub-devices for clock drift compensation + CFMutableArrayRef subDevicesArrayClock = NULL; + + /* + if (fClockDriftCompensate) { + if (need_clock_drift_compensation) { + jack_info("Clock drift compensation activated..."); + subDevicesArrayClock = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + CFStringRef UID = GetDeviceName(captureDeviceID[i]); + if (UID) { + CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); + //CFRelease(UID); + CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); + } + } + + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + CFStringRef UID = GetDeviceName(playbackDeviceID[i]); + if (UID) { + CFMutableDictionaryRef subdeviceAggDeviceDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceUIDKey), UID); + CFDictionaryAddValue(subdeviceAggDeviceDict, CFSTR(kAudioSubDeviceDriftCompensationKey), AggregateDeviceNumberRef); + //CFRelease(UID); + CFArrayAppendValue(subDevicesArrayClock, subdeviceAggDeviceDict); + } + } + + // add sub-device clock array for the aggregate device to the dictionary + CFDictionaryAddValue(aggDeviceDict, CFSTR(kAudioAggregateDeviceSubDeviceListKey), subDevicesArrayClock); + } else { + jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); + } + } + */ + //------------------------------------------------- // Create a CFMutableArray for our sub-device list //------------------------------------------------- - CFStringRef captureDeviceUID = GetDeviceName(captureDeviceID); - CFStringRef playbackDeviceUID = GetDeviceName(playbackDeviceID); - - if (captureDeviceUID == NULL || playbackDeviceUID == NULL) - return -1; - // we need to append the UID for each device to a CFMutableArray, so create one here CFMutableArrayRef subDevicesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - - // two sub-devices in this example, so append the sub-device's UID to the CFArray - CFArrayAppendValue(subDevicesArray, captureDeviceUID); - CFArrayAppendValue(subDevicesArray, playbackDeviceUID); - + + vector captureDeviceUID; + for (UInt32 i = 0; i < captureDeviceID.size(); i++) { + CFStringRef ref = GetDeviceName(captureDeviceID[i]); + if (ref == NULL) + return -1; + captureDeviceUID.push_back(ref); + // input sub-devices in this example, so append the sub-device's UID to the CFArray + CFArrayAppendValue(subDevicesArray, ref); + } + + vector playbackDeviceUID; + for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { + CFStringRef ref = GetDeviceName(playbackDeviceID[i]); + if (ref == NULL) + return -1; + playbackDeviceUID.push_back(ref); + // output sub-devices in this example, so append the sub-device's UID to the CFArray + CFArrayAppendValue(subDevicesArray, ref); + } + //----------------------------------------------------------------------- // Feed the dictionary to the plugin, to create a blank aggregate device //----------------------------------------------------------------------- @@ -517,13 +697,19 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI pluginAOPA.mElement = kAudioObjectPropertyElementMaster; UInt32 outDataSize; - osErr = AudioObjectGetPropertyDataSize(pluginID, &pluginAOPA, 0, NULL, &outDataSize); - if (osErr != noErr) - return osErr; - - osErr = AudioObjectGetPropertyData(pluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); - if (osErr != noErr) - return osErr; + osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyDataSize error"); + printError(osErr); + goto error; + } + + osErr = AudioObjectGetPropertyData(fPluginID, &pluginAOPA, sizeof(aggDeviceDict), &aggDeviceDict, &outDataSize, outAggregateDevice); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectGetPropertyData error"); + printError(osErr); + goto error; + } // pause for a bit to make sure that everything completed correctly // this is to work around a bug in the HAL where a new aggregate device seems to disappear briefly after it is created @@ -538,12 +724,15 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFMutableArrayRef); osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &subDevicesArray); - if (osErr != noErr) - return osErr; - + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for sub-device list error"); + printError(osErr); + goto error; + } + // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); - + //----------------------- // Set the master device //----------------------- @@ -554,48 +743,103 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI pluginAOPA.mScope = kAudioObjectPropertyScopeGlobal; pluginAOPA.mElement = kAudioObjectPropertyElementMaster; outDataSize = sizeof(CFStringRef); - osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID); // capture is master... - if (osErr != noErr) - return osErr; - + osErr = AudioObjectSetPropertyData(*outAggregateDevice, &pluginAOPA, 0, NULL, outDataSize, &captureDeviceUID[0]); // First apture is master... + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice : AudioObjectSetPropertyData for master device error"); + printError(osErr); + goto error; + } + // pause again to give the changes time to take effect CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); - + + // Prepare sub-devices for clock drift compensation + // Workaround for bug in the HAL : until 10.6.2 + + if (fClockDriftCompensate) { + if (need_clock_drift_compensation) { + jack_info("Clock drift compensation activated..."); + + // Get the property data size + osErr = AudioObjectGetPropertyDataSize(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); + printError(osErr); + } + + // Calculate the number of object IDs + subDevicesNum = outSize / sizeof(AudioObjectID); + jack_info("JackCoreAudioDriver::CreateAggregateDevice clock drift compensation, number of sub-devices = %d", subDevicesNum); + AudioObjectID subDevices[subDevicesNum]; + outSize = sizeof(subDevices); + + osErr = AudioObjectGetPropertyData(*outAggregateDevice, &theAddressOwned, theQualifierDataSize, theQualifierData, &outSize, subDevices); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioObjectPropertyOwnedObjects error"); + printError(osErr); + } + + // Set kAudioSubDevicePropertyDriftCompensation property... + for (UInt32 index = 0; index < subDevicesNum; ++index) { + UInt32 theDriftCompensationValue = 1; + osErr = AudioObjectSetPropertyData(subDevices[index], &theAddressDrift, 0, NULL, sizeof(UInt32), &theDriftCompensationValue); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::CreateAggregateDevice kAudioSubDevicePropertyDriftCompensation error"); + printError(osErr); + } + } + } else { + jack_info("Clock drift compensation was asked but is not needed (devices use the same clock domain)"); + } + } + + // pause again to give the changes time to take effect + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false); + //---------- // Clean up //---------- + + // release the private AD key + CFRelease(AggregateDeviceNumberRef); // release the CF objects we have created - we don't need them any more CFRelease(aggDeviceDict); CFRelease(subDevicesArray); + + if (subDevicesArrayClock) + CFRelease(subDevicesArrayClock); // release the device UID - CFRelease(captureDeviceUID); - CFRelease(playbackDeviceUID); + for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { + CFRelease(captureDeviceUID[i]); + } + + for (UInt32 i = 0; i < playbackDeviceUID.size(); i++) { + CFRelease(playbackDeviceUID[i]); + } jack_log("New aggregate device %ld", *outAggregateDevice); return noErr; + +error: + DestroyAggregateDevice(); + return -1; } -int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, char* playback_driver_name) +int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, + const char* playback_driver_uid, + char* capture_driver_name, + char* playback_driver_name, + jack_nframes_t samplerate) { capture_driver_name[0] = 0; playback_driver_name[0] = 0; - + // Duplex if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::Open duplex"); - - /* - AudioDeviceID captureID, playbackID; - if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) - return -1; - if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) - return -1; - if (CreateAggregateDevice(captureID, playbackID, &fDeviceID) != noErr) - return -1; - */ - + // Same device for capture and playback... if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { @@ -613,17 +857,30 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char } else { - // Creates agregate device + // Creates aggregate device AudioDeviceID captureID, playbackID; - if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) - return -1; - if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) - return -1; - if (CreateAggregateDevice(captureID, playbackID, &fDeviceID) != noErr) + + if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { + jack_log("Will take default input"); + if (GetDefaultInputDevice(&captureID) != noErr) { + jack_error("Cannot open default device"); + return -1; + } + } + + if (GetDeviceIDFromUID(playback_driver_uid, &playbackID) != noErr) { + jack_log("Will take default output"); + if (GetDefaultOutputDevice(&playbackID) != noErr) { + jack_error("Cannot open default device"); + return -1; + } + } + + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) return -1; } - // Capture only + // Capture only } else if (strcmp(capture_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::Open capture only"); if (GetDeviceIDFromUID(capture_driver_uid, &fDeviceID) != noErr) { @@ -638,7 +895,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char return -1; } - // Playback only + // Playback only } else if (strcmp(playback_driver_uid, "") != 0) { jack_log("JackCoreAudioDriver::Open playback only"); if (GetDeviceIDFromUID(playback_driver_uid, &fDeviceID) != noErr) { @@ -653,7 +910,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char return -1; } - // Use default driver in duplex mode + // Use default driver in duplex mode } else { jack_log("JackCoreAudioDriver::Open default driver"); if (GetDefaultDevice(&fDeviceID) != noErr) { @@ -665,6 +922,14 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, const char return -1; } } + + if (fHogged) { + if (TakeHog()) { + jack_info("Device = %ld has been hogged", fDeviceID); + } else { + jack_error("Cannot hog device = %ld", fDeviceID); + } + } return 0; } @@ -699,48 +964,58 @@ int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchan } if (inchannels > in_nChannels) { - jack_error("This device hasn't required input channels inchannels = %ld in_nChannels = %ld", inchannels, in_nChannels); + jack_error("This device hasn't required input channels inchannels = %d in_nChannels = %d", inchannels, in_nChannels); if (strict) return -1; } if (outchannels > out_nChannels) { - jack_error("This device hasn't required output channels outchannels = %ld out_nChannels = %ld", outchannels, out_nChannels); + jack_error("This device hasn't required output channels outchannels = %d out_nChannels = %d", outchannels, out_nChannels); if (strict) return -1; } - if (inchannels == 0) { - jack_log("Setup max in channels = %ld", in_nChannels); + if (inchannels == -1) { + jack_log("Setup max in channels = %d", in_nChannels); inchannels = in_nChannels; } - if (outchannels == 0) { - jack_log("Setup max out channels = %ld", out_nChannels); + if (outchannels == -1) { + jack_log("Setup max out channels = %d", out_nChannels); outchannels = out_nChannels; } return 0; } -int JackCoreAudioDriver::SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size, jack_nframes_t samplerate) +int JackCoreAudioDriver::SetupBufferSize(jack_nframes_t buffer_size) { - OSStatus err = noErr; - UInt32 outSize; - Float64 sampleRate; - // Setting buffer size - outSize = sizeof(UInt32); - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); + UInt32 outSize = sizeof(UInt32); + OSStatus err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &buffer_size); if (err != noErr) { jack_error("Cannot set buffer size %ld", buffer_size); printError(err); return -1; } + return 0; +} + +int JackCoreAudioDriver::SetupSampleRate(jack_nframes_t samplerate) +{ + return SetupSampleRateAux(fDeviceID, samplerate); +} + +int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate) +{ + OSStatus err = noErr; + UInt32 outSize; + Float64 sampleRate; + // Get sample rate outSize = sizeof(Float64); - err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); if (err != noErr) { jack_error("Cannot get current sample rate"); printError(err); @@ -752,13 +1027,13 @@ int JackCoreAudioDriver::SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size sampleRate = (Float64)samplerate; // To get SR change notification - err = AudioDeviceAddPropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); + err = AudioDeviceAddPropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback, this); if (err != noErr) { jack_error("Error calling AudioDeviceAddPropertyListener with kAudioDevicePropertyNominalSampleRate"); printError(err); return -1; } - err = AudioDeviceSetProperty(fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); + err = AudioDeviceSetProperty(inDevice, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outSize, &sampleRate); if (err != noErr) { jack_error("Cannot set sample rate = %ld", samplerate); printError(err); @@ -767,13 +1042,13 @@ int JackCoreAudioDriver::SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size // Waiting for SR change notification int count = 0; - while (!fState && count++ < 100) { + while (!fState && count++ < WAIT_COUNTER) { usleep(100000); - jack_log("Wait count = %ld", count); + jack_log("Wait count = %d", count); } // Remove SR change notification - AudioDeviceRemovePropertyListener(fDeviceID, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); + AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); } return 0; @@ -786,14 +1061,15 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, int in_nChannels, int out_nChannels, jack_nframes_t buffer_size, - jack_nframes_t samplerate, - bool strict) + jack_nframes_t samplerate) { ComponentResult err1; UInt32 enableIO; AudioStreamBasicDescription srcFormat, dstFormat; + AudioDeviceID currAudioDeviceID; + UInt32 size; - jack_log("OpenAUHAL capturing = %ld playing = %ld inchannels = %ld outchannels = %ld in_nChannels = %ld out_nChannels = %ld ", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); + jack_log("OpenAUHAL capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels); if (inchannels == 0 && outchannels == 0) { jack_error("No input and output channels..."); @@ -808,14 +1084,14 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling OpenAComponent"); printError(err1); - return -1; + goto error; } err1 = AudioUnitInitialize(fAUHAL); if (err1 != noErr) { jack_error("Cannot initialize AUHAL unit"); printError(err1); - return -1; + goto error; } // Start I/O @@ -831,8 +1107,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input"); printError(err1); - if (strict) - return -1; + goto error; } if (playing && outchannels > 0) { @@ -847,18 +1122,15 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Output"); printError(err1); - if (strict) - return -1; + goto error; } - AudioDeviceID currAudioDeviceID; - UInt32 size = sizeof(AudioDeviceID); + size = sizeof(AudioDeviceID); err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); if (err1 != noErr) { jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); - if (strict) - return -1; + goto error; } else { jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); } @@ -868,28 +1140,16 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice"); printError(err1); - if (strict) - return -1; - } - - err1 = AudioUnitGetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &currAudioDeviceID, &size); - if (err1 != noErr) { - jack_error("Error calling AudioUnitGetProperty - kAudioOutputUnitProperty_CurrentDevice"); - printError(err1); - if (strict) - return -1; - } else { - jack_log("AudioUnitGetPropertyCurrentDevice = %d", currAudioDeviceID); + goto error; } - + // Set buffer size if (capturing && inchannels > 0) { err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&buffer_size, sizeof(UInt32)); if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); - if (strict) - return -1; + goto error; } } @@ -898,8 +1158,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice"); printError(err1); - if (strict) - return -1; + goto error; } } @@ -916,6 +1175,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1"); printError(err1); + goto error; } } @@ -931,40 +1191,71 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0"); printError(err1); + goto error; } } // Setup stream converters - jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); - srcFormat.mSampleRate = samplerate; - srcFormat.mFormatID = kAudioFormatLinearPCM; - srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - srcFormat.mBytesPerPacket = sizeof(float); - srcFormat.mFramesPerPacket = 1; - srcFormat.mBytesPerFrame = sizeof(float); - srcFormat.mChannelsPerFrame = outchannels; - srcFormat.mBitsPerChannel = 32; - - err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &srcFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); - printError(err1); + if (capturing && inchannels > 0) { + + size = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); + if (err1 != noErr) { + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + printError(err1); + goto error; + } + PrintStreamDesc(&srcFormat); + + jack_log("Setup AUHAL input stream converter SR = %ld", samplerate); + srcFormat.mSampleRate = samplerate; + srcFormat.mFormatID = kAudioFormatLinearPCM; + srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + srcFormat.mBytesPerPacket = sizeof(float); + srcFormat.mFramesPerPacket = 1; + srcFormat.mBytesPerFrame = sizeof(float); + srcFormat.mChannelsPerFrame = inchannels; + srcFormat.mBitsPerChannel = 32; + PrintStreamDesc(&srcFormat); + + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); + + if (err1 != noErr) { + jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + printError(err1); + goto error; + } } - jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); - dstFormat.mSampleRate = samplerate; - dstFormat.mFormatID = kAudioFormatLinearPCM; - dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; - dstFormat.mBytesPerPacket = sizeof(float); - dstFormat.mFramesPerPacket = 1; - dstFormat.mBytesPerFrame = sizeof(float); - dstFormat.mChannelsPerFrame = inchannels; - dstFormat.mBitsPerChannel = 32; - - err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &dstFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); - printError(err1); + if (playing && outchannels > 0) { + + size = sizeof(AudioStreamBasicDescription); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); + if (err1 != noErr) { + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + printError(err1); + goto error; + } + PrintStreamDesc(&dstFormat); + + jack_log("Setup AUHAL output stream converter SR = %ld", samplerate); + dstFormat.mSampleRate = samplerate; + dstFormat.mFormatID = kAudioFormatLinearPCM; + dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; + dstFormat.mBytesPerPacket = sizeof(float); + dstFormat.mFramesPerPacket = 1; + dstFormat.mBytesPerFrame = sizeof(float); + dstFormat.mChannelsPerFrame = outchannels; + dstFormat.mBitsPerChannel = 32; + PrintStreamDesc(&dstFormat); + + err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); + + if (err1 != noErr) { + jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + printError(err1); + goto error; + } } // Setup callbacks @@ -976,7 +1267,7 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1"); printError(err1); - return -1; + goto error; } } else { AURenderCallbackStruct output; @@ -986,21 +1277,21 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (err1 != noErr) { jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0"); printError(err1); - return -1; + goto error; } } return 0; + +error: + CloseAUHAL(); + return -1; } int JackCoreAudioDriver::SetupBuffers(int inchannels) { // Prepare buffers fJackInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inchannels * sizeof(AudioBuffer)); - if (fJackInputData == 0) { - jack_error("Cannot allocate memory for input buffers"); - return -1; - } fJackInputData->mNumberBuffers = inchannels; for (int i = 0; i < fCaptureChannels; i++) { fJackInputData->mBuffers[i].mNumberChannels = 1; @@ -1103,7 +1394,10 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - int async_output_latency) + int async_output_latency, + int computation_grain, + bool hogged, + bool clock_drift) { int in_nChannels = 0; int out_nChannels = 0; @@ -1120,22 +1414,44 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, strcpy(fPlaybackUID, playback_driver_uid); fCaptureLatency = capture_latency; fPlaybackLatency = playback_latency; - fIOUsage = float(async_output_latency)/ 100.f; + fIOUsage = float(async_output_latency) / 100.f; + fComputationGrain = float(computation_grain) / 100.f; + fHogged = hogged; + fClockDriftCompensate = clock_drift; + + SInt32 major; + SInt32 minor; + Gestalt(gestaltSystemVersionMajor, &major); + Gestalt(gestaltSystemVersionMinor, &minor); + + // Starting with 10.6 systems, the HAL notification thread is created internally + if (major == 10 && minor >= 6) { + CFRunLoopRef theRunLoop = NULL; + AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; + OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); + if (osErr != noErr) { + jack_error("JackCoreAudioDriver::Open kAudioHardwarePropertyRunLoop error"); + printError(osErr); + } + } - if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name) < 0) - return -1; + if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, samplerate) < 0) + goto error; // Generic JackAudioDriver Open if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0) - return -1; + goto error; if (SetupChannels(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, true) < 0) - return -1; - - if (SetupBufferSizeAndSampleRate(buffer_size, samplerate) < 0) - return -1; + goto error; - if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, buffer_size, samplerate, true) < 0) + if (SetupBufferSize(buffer_size) < 0) + goto error; + + if (SetupSampleRate(samplerate) < 0) + goto error; + + if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, buffer_size, samplerate) < 0) goto error; if (capturing && inchannels > 0) @@ -1144,7 +1460,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size, if (AddListeners() < 0) goto error; - + // Core driver may have changed the in/out values fCaptureChannels = inchannels; fPlaybackChannels = outchannels; @@ -1163,6 +1479,7 @@ int JackCoreAudioDriver::Close() RemoveListeners(); DisposeBuffers(); CloseAUHAL(); + DestroyAggregateDevice(); return 0; } @@ -1259,12 +1576,13 @@ int JackCoreAudioDriver::Attach() // Monitor ports if (fWithMonitorPorts) { jack_log("Create monitor port "); - snprintf(name, sizeof(name) - 1, "%s:%s:monitor_%u", fAliasName, fPlaybackDriverName, i + 1); + snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { jack_error("Cannot register monitor port for %s", name); return -1; } else { port = fGraphManager->GetPort(port_index); + port->SetAlias(alias); port->SetLatency(fEngineControl->fBufferSize); fMonitorPortList[i] = port_index; } @@ -1304,8 +1622,22 @@ int JackCoreAudioDriver::Start() printError(err); return -1; } - - return 0; + + // Waiting for Measure callback to be called ( = driver has started) + fState = false; + int count = 0; + while (!fState && count++ < WAIT_COUNTER) { + usleep(100000); + jack_log("JackCoreAudioDriver::Start wait count = %d", count); + } + + if (count < WAIT_COUNTER) { + jack_info("CoreAudio driver is running..."); + return 0; + } else { + jack_error("CoreAudio driver cannot start..."); + return -1; + } } int JackCoreAudioDriver::Stop() @@ -1347,6 +1679,66 @@ int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) return 0; } +bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) +{ + pid_t hog_pid; + OSStatus err; + + UInt32 propSize = sizeof(hog_pid); + err = AudioDeviceGetProperty(deviceID, 0, isInput, kAudioDevicePropertyHogMode, &propSize, &hog_pid); + if (err) { + jack_error("Cannot read hog state..."); + printError(err); + } + + if (hog_pid != getpid()) { + hog_pid = getpid(); + err = AudioDeviceSetProperty(deviceID, 0, 0, isInput, kAudioDevicePropertyHogMode, propSize, &hog_pid); + if (err != noErr) { + jack_error("Can't hog device = %d because it's being hogged by another program", deviceID); + return false; + } + } + + return true; +} + +bool JackCoreAudioDriver::TakeHog() +{ + OSStatus err = noErr; + AudioObjectID sub_device[32]; + UInt32 outSize = sizeof(sub_device); + err = AudioDeviceGetProperty(fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioAggregateDevicePropertyActiveSubDeviceList, &outSize, sub_device); + + if (err != noErr) { + jack_log("Device does not have subdevices"); + return TakeHogAux(fDeviceID, true); + } else { + int num_devices = outSize / sizeof(AudioObjectID); + jack_log("Device does has %d subdevices", num_devices); + for (int i = 0; i < num_devices; i++) { + if (!TakeHogAux(sub_device[i], true)) { + return false; + } + } + return true; + } +} + +bool JackCoreAudioDriver::IsAggregateDevice(AudioDeviceID device) +{ + UInt32 deviceType, outSize = sizeof(UInt32); + OSStatus err = AudioDeviceGetProperty(device, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyTransportType, &outSize, &deviceType); + + if (err != noErr) { + jack_log("JackCoreAudioDriver::IsAggregateDevice kAudioDevicePropertyTransportType error"); + return false; + } else { + return (deviceType == kAudioDeviceTransportTypeAggregate); + } +} + + } // end of namespace @@ -1364,47 +1756,45 @@ extern "C" strcpy(desc->name, "coreaudio"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "Apple CoreAudio API based audio backend"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 14; + desc->nparams = 17; desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t)); i = 0; strcpy(desc->params[i].name, "channels"); desc->params[i].character = 'c'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of channels. If -1, max possible number of channels will be used"); i++; strcpy(desc->params[i].name, "inchannels"); desc->params[i].character = 'i'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of input channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of input channels. If -1, max possible number of input channels will be used"); i++; strcpy(desc->params[i].name, "outchannels"); desc->params[i].character = 'o'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; + desc->params[i].value.ui = -1; strcpy(desc->params[i].short_desc, "Maximum number of output channels"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + strcpy(desc->params[i].long_desc, "Maximum number of output channels. If -1, max possible number of output channels will be used"); i++; strcpy(desc->params[i].name, "capture"); desc->params[i].character = 'C'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio input device"); - strcpy(desc->params[i].short_desc, "Provide capture ports. Optionally set CoreAudio device name"); + strcpy(desc->params[i].short_desc, "Input CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; strcpy(desc->params[i].name, "playback"); desc->params[i].character = 'P'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio output device"); - strcpy(desc->params[i].short_desc, "Provide playback ports. Optionally set CoreAudio device name"); + strcpy(desc->params[i].short_desc, "Output CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); i++; @@ -1443,7 +1833,6 @@ extern "C" strcpy(desc->params[i].name, "device"); desc->params[i].character = 'd'; desc->params[i].type = JackDriverParamString; - strcpy(desc->params[i].value.str, "will take default CoreAudio device name"); strcpy(desc->params[i].short_desc, "CoreAudio device name"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -1467,17 +1856,41 @@ extern "C" strcpy(desc->params[i].name, "list-devices"); desc->params[i].character = 'l'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = FALSE; strcpy(desc->params[i].short_desc, "Display available CoreAudio devices"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + i++; + strcpy(desc->params[i].name, "hog"); + desc->params[i].character = 'H'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = FALSE; + strcpy(desc->params[i].short_desc, "Take exclusive access of the audio device"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + i++; strcpy(desc->params[i].name, "async-latency"); desc->params[i].character = 'L'; desc->params[i].type = JackDriverParamUInt; desc->params[i].value.i = 100; - strcpy(desc->params[i].short_desc, "Extra output latency in aynchronous mode (percent)"); + strcpy(desc->params[i].short_desc, "Extra output latency in asynchronous mode (percent)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "grain"); + desc->params[i].character = 'G'; + desc->params[i].type = JackDriverParamUInt; + desc->params[i].value.i = 100; + strcpy(desc->params[i].short_desc, "Computation grain in RT thread (percent)"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy(desc->params[i].name, "clock-drift"); + desc->params[i].character = 's'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = FALSE; + strcpy(desc->params[i].short_desc, "Clock drift compensation"); + strcpy(desc->params[i].long_desc, "Whether to compensate clock drift in dynamically created aggregate device"); return desc; } @@ -1486,10 +1899,10 @@ extern "C" { jack_nframes_t srate = 44100; jack_nframes_t frames_per_interrupt = 128; - int capture = FALSE; - int playback = FALSE; - int chan_in = 0; - int chan_out = 0; + bool capture = false; + bool playback = false; + int chan_in = -1; // Default: if not explicitely set, then max possible will be used... + int chan_out = -1; // Default: ifà not explicitely set, then max possible will be used... bool monitor = false; const char* capture_driver_uid = ""; const char* playback_driver_uid = ""; @@ -1498,6 +1911,9 @@ extern "C" jack_nframes_t systemic_input_latency = 0; jack_nframes_t systemic_output_latency = 0; int async_output_latency = 100; + int computation_grain = -1; + bool hogged = false; + bool clock_drift = false; for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t *) node->data; @@ -1510,31 +1926,31 @@ extern "C" break; case 'D': - capture = TRUE; - playback = TRUE; + capture = true; + playback = true; break; case 'c': - chan_in = chan_out = (int) param->value.ui; + chan_in = chan_out = (int)param->value.ui; break; case 'i': - chan_in = (int) param->value.ui; + chan_in = (int)param->value.ui; break; case 'o': - chan_out = (int) param->value.ui; + chan_out = (int)param->value.ui; break; case 'C': - capture = TRUE; + capture = true; if (strcmp(param->value.str, "none") != 0) { capture_driver_uid = strdup(param->value.str); } break; case 'P': - playback = TRUE; + playback = true; if (strcmp(param->value.str, "none") != 0) { playback_driver_uid = strdup(param->value.str); } @@ -1549,7 +1965,7 @@ extern "C" break; case 'p': - frames_per_interrupt = (unsigned int) param->value.ui; + frames_per_interrupt = (unsigned int)param->value.ui; break; case 'I': @@ -1564,21 +1980,33 @@ extern "C" Jack::DisplayDeviceNames(); break; + case 'H': + hogged = true; + break; + case 'L': async_output_latency = param->value.ui; break; + + case 'G': + computation_grain = param->value.ui; + break; + + case 's': + clock_drift = true; + break; } } /* duplex is the default */ if (!capture && !playback) { - capture = TRUE; - playback = TRUE; + capture = true; + playback = true; } Jack::JackCoreAudioDriver* driver = new Jack::JackCoreAudioDriver("system", "coreaudio", engine, table); if (driver->Open(frames_per_interrupt, srate, capture, playback, chan_in, chan_out, monitor, capture_driver_uid, - playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency) == 0) { + playback_driver_uid, systemic_input_latency, systemic_output_latency, async_output_latency, computation_grain, hogged, clock_drift) == 0) { return driver; } else { delete driver; diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index 62de09fb..f17bbf19 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -26,6 +26,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackAudioDriver.h" #include "JackTime.h" +#include + +using namespace std; + namespace Jack { @@ -36,6 +40,8 @@ typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) + +#define WAIT_COUNTER 60 /*! \brief The CoreAudio driver. @@ -53,12 +59,14 @@ class JackCoreAudioDriver : public JackAudioDriver AudioBufferList* fJackInputData; AudioBufferList* fDriverOutputData; - AudioDeviceID fDeviceID; + AudioDeviceID fDeviceID; // Used "duplex" device + AudioObjectID fPluginID; // Used for aggregate device AudioUnitRenderActionFlags* fActionFags; AudioTimeStamp* fCurrentTime; bool fState; + bool fHogged; // Initial state bool fCapturing; @@ -72,6 +80,8 @@ class JackCoreAudioDriver : public JackAudioDriver bool fMonitor; float fIOUsage; + float fComputationGrain; + bool fClockDriftCompensate; /* #ifdef MAC_OS_X_VERSION_10_5 @@ -100,7 +110,6 @@ class JackCoreAudioDriver : public JackAudioDriver AudioDevicePropertyID inPropertyID, void* inClientData); - static OSStatus SRNotificationCallback(AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, @@ -113,13 +122,18 @@ class JackCoreAudioDriver : public JackAudioDriver OSStatus GetDefaultOutputDevice(AudioDeviceID* id); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); - + // Setup - OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, AudioDeviceID* outAggregateDevice); + OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); + OSStatus CreateAggregateDeviceAux(vector captureDeviceID, vector playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); + OSStatus DestroyAggregateDevice(); + bool IsAggregateDevice(AudioDeviceID device); + int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, - char* playback_driver_name); + char* playback_driver_name, + jack_nframes_t samplerate); int SetupChannels(bool capturing, bool playing, @@ -132,7 +146,9 @@ class JackCoreAudioDriver : public JackAudioDriver int SetupBuffers(int inchannels); void DisposeBuffers(); - int SetupBufferSizeAndSampleRate(jack_nframes_t buffer_size, jack_nframes_t samplerate); + int SetupBufferSize(jack_nframes_t buffer_size); + int SetupSampleRate(jack_nframes_t samplerate); + int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate); int OpenAUHAL(bool capturing, bool playing, @@ -141,12 +157,14 @@ class JackCoreAudioDriver : public JackAudioDriver int in_nChannels, int out_nChannels, jack_nframes_t nframes, - jack_nframes_t samplerate, - bool strict); + jack_nframes_t samplerate); void CloseAUHAL(); int AddListeners(); void RemoveListeners(); + + bool TakeHogAux(AudioDeviceID deviceID, bool isInput); + bool TakeHog(); public: @@ -164,7 +182,10 @@ class JackCoreAudioDriver : public JackAudioDriver const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - int async_output_latency); + int async_output_latency, + int computation_grain, + bool hogged, + bool clock_drift); int Close(); int Attach(); diff --git a/macosx/install_jackdmp b/macosx/install_jackdmp index 7e171b76..e1c50075 100755 --- a/macosx/install_jackdmp +++ b/macosx/install_jackdmp @@ -11,6 +11,7 @@ sudo install -d /usr/local/bin sudo cp jackdmp /usr/local/bin [ -f jack_load ] && sudo cp jack_load /usr/local/bin [ -f jack_unload ] && sudo cp jack_unload /usr/local/bin +[ -f jack_netsource ] && sudo cp jack_netsource /usr/local/bin # Copy drivers sudo install -d /usr/local/lib/jackmp @@ -19,6 +20,7 @@ sudo cp jack_coremidi.so /usr/local/lib/jackmp sudo cp jack_dummy.so /usr/local/lib/jackmp sudo cp jack_loopback.so /usr/local/lib/jackmp [ -f jack_net.so ] && sudo cp jack_net.so /usr/local/lib/jackmp +[ -f jack_netone.so ] && sudo cp jack_netone.so /usr/local/lib/jackmp # Copy tools [ -f netmanager.so ] && sudo cp netmanager.so /usr/local/lib/jackmp diff --git a/macosx/wscript b/macosx/wscript index 843874bc..8fa9bd37 100644 --- a/macosx/wscript +++ b/macosx/wscript @@ -6,6 +6,12 @@ def create_jack_driver_obj(bld, target, sources, uselib = None): driver.features.append('cc') driver.env['shlib_PATTERN'] = 'jack_%s.so' driver.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] + # Seems uneeded here... + #if bld.env['HAVE_CELT']: + #if bld.env['HAVE_CELT_API_0_5']: + # driver.defines += ['HAVE_CELT', 'HAVE_CELT_API_0_5'] + #elif bld.env['HAVE_CELT_API_0_7']: + # driver.defines += ['HAVE_CELT', 'HAVE_CELT_API_0_7'] driver.includes = ['.', '../macosx', '../posix', '../common', '../common/jack'] driver.target = target driver.source = sources @@ -73,3 +79,6 @@ def build(bld): create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') + create_jack_driver_obj(bld, 'netone', [ '../common/JackNetOneDriver.cpp', + '../common/netjack.c', + '../common/netjack_packet.c' ], "SAMPLERATE CELT" ) diff --git a/posix/JackPosixMutex.h b/posix/JackPosixMutex.h index 8fc6ea06..91d21132 100644 --- a/posix/JackPosixMutex.h +++ b/posix/JackPosixMutex.h @@ -33,6 +33,47 @@ namespace Jack \brief Mutex abstraction. */ + +class JackBasePosixMutex +{ + + protected: + + pthread_mutex_t fMutex; + + public: + + JackBasePosixMutex() + { + pthread_mutex_init(&fMutex, NULL); + } + + virtual ~JackBasePosixMutex() + { + pthread_mutex_destroy(&fMutex); + } + + void Lock() + { + int res = pthread_mutex_lock(&fMutex); + if (res != 0) + jack_error("JackBasePosixMutex::Lock res = %d", res); + } + + bool Trylock() + { + return (pthread_mutex_trylock(&fMutex) == 0); + } + + void Unlock() + { + int res = pthread_mutex_unlock(&fMutex); + if (res != 0) + jack_error("JackBasePosixMutex::Unlock res = %d", res); + } + +}; + class JackPosixMutex { diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index aa1d0fbd..67d2d0c8 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -25,8 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include // for memset #include // for _POSIX_PRIORITY_SCHEDULING check -#define JACK_SCHED_POLICY SCHED_RR -//#define JACK_SCHED_POLICY SCHED_FIFO +//#define JACK_SCHED_POLICY SCHED_RR +#define JACK_SCHED_POLICY SCHED_FIFO namespace Jack { @@ -101,12 +101,12 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi int res; if ((res = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_JOINABLE))) { - jack_error("Cannot request joinable thread creation for RT thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot request joinable thread creation for thread res = %d", res); return -1; } if ((res = pthread_attr_setscope(&attributes, PTHREAD_SCOPE_SYSTEM))) { - jack_error("Cannot set scheduling scope for RT thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot set scheduling scope for thread res = %d", res); return -1; } @@ -115,33 +115,34 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi jack_log("Create RT thread"); if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) { - jack_error("Cannot request explicit scheduling for RT thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot request explicit scheduling for RT thread res = %d", res); return -1; } if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) { - jack_error("Cannot set RR scheduling class for RT thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot set RR scheduling class for RT thread res = %d", res); return -1; } - } else { - jack_log("Create non RT thread"); - } + + memset(&rt_param, 0, sizeof(rt_param)); + rt_param.sched_priority = priority; - memset(&rt_param, 0, sizeof(rt_param)); - rt_param.sched_priority = priority; + if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { + jack_error("Cannot set scheduling priority for RT thread res = %d", res); + return -1; + } - if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { - jack_error("Cannot set scheduling priority for RT thread res = %d err = %s", res, strerror(errno)); - return -1; + } else { + jack_log("Create non RT thread"); } if ((res = pthread_attr_setstacksize(&attributes, THREAD_STACK))) { - jack_error("Cannot set thread stack size res = %d err = %s", res, strerror(errno)); + jack_error("Cannot set thread stack size res = %d", res); return -1; } if ((res = JackGlobals::fJackThreadCreator(thread, &attributes, start_routine, arg))) { - jack_error("Cannot create thread res = %d err = %s", res, strerror(errno)); + jack_error("Cannot create thread res = %d", res); return -1; } @@ -208,12 +209,22 @@ int JackPosixThread::AcquireRealTime() return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; } +int JackPosixThread::AcquireSelfRealTime() +{ + return AcquireRealTimeImp(pthread_self(), fPriority); +} + int JackPosixThread::AcquireRealTime(int priority) { fPriority = priority; return AcquireRealTime(); } +int JackPosixThread::AcquireSelfRealTime(int priority) +{ + fPriority = priority; + return AcquireSelfRealTime(); +} int JackPosixThread::AcquireRealTimeImp(pthread_t thread, int priority) { struct sched_param rtparam; @@ -235,6 +246,11 @@ int JackPosixThread::DropRealTime() return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1; } +int JackPosixThread::DropSelfRealTime() +{ + return DropRealTimeImp(pthread_self()); +} + int JackPosixThread::DropRealTimeImp(pthread_t thread) { struct sched_param rtparam; @@ -303,7 +319,7 @@ bool jack_tls_allocate_key(jack_tls_key *key_ptr) ret = pthread_key_create(key_ptr, NULL); if (ret != 0) { - jack_error("pthread_key_create() failed with error %d errno %s", ret, strerror(errno)); + jack_error("pthread_key_create() failed with error %d", ret); return false; } @@ -317,7 +333,7 @@ bool jack_tls_free_key(jack_tls_key key) ret = pthread_key_delete(key); if (ret != 0) { - jack_error("pthread_key_delete() failed with error %d errno %s", ret, strerror(errno)); + jack_error("pthread_key_delete() failed with error %d", ret); return false; } @@ -331,7 +347,7 @@ bool jack_tls_set(jack_tls_key key, void *data_ptr) ret = pthread_setspecific(key, (const void *)data_ptr); if (ret != 0) { - jack_error("pthread_setspecific() failed with error %d errno %s", ret, strerror(errno)); + jack_error("pthread_setspecific() failed with error %d", ret); return false; } diff --git a/posix/JackPosixThread.h b/posix/JackPosixThread.h index a0cec26a..73345e17 100644 --- a/posix/JackPosixThread.h +++ b/posix/JackPosixThread.h @@ -58,9 +58,14 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface int Stop(); void Terminate(); - int AcquireRealTime(); - int AcquireRealTime(int priority); - int DropRealTime(); + int AcquireRealTime(); // Used when called from another thread + int AcquireSelfRealTime(); // Used when called from thread itself + + int AcquireRealTime(int priority); // Used when called from another thread + int AcquireSelfRealTime(int priority); // Used when called from thread itself + + int DropRealTime(); // Used when called from another thread + int DropSelfRealTime(); // Used when called from thread itself pthread_t GetThreadID(); diff --git a/posix/JackProcessSync.cpp b/posix/JackProcessSync.cpp index 7c0763b4..2daa49b7 100644 --- a/posix/JackProcessSync.cpp +++ b/posix/JackProcessSync.cpp @@ -104,6 +104,7 @@ bool JackProcessSync::TimedWait(long usec) gettimeofday(&T1, 0); jack_log("JackProcessSync::TimedWait finished delta = %5.1lf", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); + return (res == 0); } @@ -112,11 +113,11 @@ bool JackProcessSync::LockedTimedWait(long usec) struct timeval T0, T1; timespec time; struct timeval now; - int res; + int res1, res2; - res = pthread_mutex_lock(&fMutex); - if (res != 0) - jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res)); + res1 = pthread_mutex_lock(&fMutex); + if (res1 != 0) + jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); jack_log("JackProcessSync::TimedWait time out = %ld", usec); gettimeofday(&T0, 0); @@ -125,19 +126,19 @@ bool JackProcessSync::LockedTimedWait(long usec) unsigned int next_date_usec = now.tv_usec + usec; time.tv_sec = now.tv_sec + (next_date_usec / 1000000); time.tv_nsec = (next_date_usec % 1000000) * 1000; - res = pthread_cond_timedwait(&fCond, &fMutex, &time); - if (res != 0) - jack_error("JackProcessSync::LockedTimedWait error usec = %ld err = %s", usec, strerror(res)); + res2 = pthread_cond_timedwait(&fCond, &fMutex, &time); + if (res2 != 0) + jack_error("JackProcessSync::LockedTimedWait error usec = %ld err = %s", usec, strerror(res2)); gettimeofday(&T1, 0); - - res = pthread_mutex_unlock(&fMutex); - if (res != 0) - jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res)); + res1 = pthread_mutex_unlock(&fMutex); + if (res1 != 0) + jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); jack_log("JackProcessSync::TimedWait finished delta = %5.1lf", (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); - return (res == 0); + + return (res2 == 0); } diff --git a/posix/JackProcessSync.h b/posix/JackProcessSync.h index 4cf82850..5f45a01e 100644 --- a/posix/JackProcessSync.h +++ b/posix/JackProcessSync.h @@ -32,7 +32,7 @@ namespace Jack \brief A synchronization primitive built using a condition variable. */ -class JackProcessSync : public JackPosixMutex +class JackProcessSync : public JackBasePosixMutex { private: @@ -41,12 +41,12 @@ class JackProcessSync : public JackPosixMutex public: - JackProcessSync():JackPosixMutex() + JackProcessSync():JackBasePosixMutex() { pthread_cond_init(&fCond, NULL); } - ~JackProcessSync() + virtual ~JackProcessSync() { pthread_cond_destroy(&fCond); } diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index a14e4cc3..d2d4b676 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -168,9 +168,9 @@ void JackSocketClientChannel::ClientClose(int refnum, int* result) ServerSyncCall(&req, &res, result); } -void JackSocketClientChannel::ClientActivate(int refnum, int state, int* result) +void JackSocketClientChannel::ClientActivate(int refnum, int is_real_time, int* result) { - JackActivateRequest req(refnum, state); + JackActivateRequest req(refnum, is_real_time); JackResult res; ServerSyncCall(&req, &res, result); } @@ -320,7 +320,7 @@ bool JackSocketClientChannel::Execute() goto error; } - res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fValue1, event.fValue2); + res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); if (event.fSync) { if (res.Write(fNotificationSocket) < 0) { diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h index d51857d8..c9004293 100644 --- a/posix/JackSocketClientChannel.h +++ b/posix/JackSocketClientChannel.h @@ -66,7 +66,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi {} void ClientClose(int refnum, int* result); - void ClientActivate(int refnum, int state, int* result); + void ClientActivate(int refnum, int is_real_time, int* result); void ClientDeactivate(int refnum, 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); diff --git a/posix/JackSocketNotifyChannel.cpp b/posix/JackSocketNotifyChannel.cpp index b0c44867..35737b0d 100644 --- a/posix/JackSocketNotifyChannel.cpp +++ b/posix/JackSocketNotifyChannel.cpp @@ -47,9 +47,9 @@ void JackSocketNotifyChannel::Close() fNotifySocket.Close(); } -void JackSocketNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result) +void JackSocketNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) { - JackClientNotification event(name, refnum, notify, sync, value1, value2); + JackClientNotification event(name, refnum, notify, sync, message, value1, value2); JackResult res; // Send notification diff --git a/posix/JackSocketNotifyChannel.h b/posix/JackSocketNotifyChannel.h index 9a40bbcb..5d532919 100644 --- a/posix/JackSocketNotifyChannel.h +++ b/posix/JackSocketNotifyChannel.h @@ -45,7 +45,7 @@ class JackSocketNotifyChannel int Open(const char* name); // Open the Server/Client connection void Close(); // Close the Server/Client connection - void ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result); + void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); }; } // end of namespace diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index b04fdb0a..a5625219 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -22,7 +22,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackServer.h" #include "JackLockedEngine.h" #include "JackGlobals.h" +#include "JackServerGlobals.h" #include "JackClient.h" +#include "JackTools.h" #include "JackNotification.h" #include #include @@ -46,9 +48,8 @@ JackSocketServerChannel::~JackSocketServerChannel() int JackSocketServerChannel::Open(const char* server_name, JackServer* server) { - jack_log("JackSocketServerChannel::Open "); - fServer = server; - + jack_log("JackSocketServerChannel::Open"); + // Prepare request socket if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) { jack_log("JackSocketServerChannel::Open : cannot create result listen socket"); @@ -57,18 +58,8 @@ int JackSocketServerChannel::Open(const char* server_name, JackServer* server) // Prepare for poll BuildPoolTable(); - - // Start listening - if (fThread.Start() != 0) { - jack_error("Cannot start Jack server listener"); - goto error; - } - + fServer = server; return 0; - -error: - fRequestListenSocket.Close(); - return -1; } void JackSocketServerChannel::Close() @@ -86,6 +77,16 @@ void JackSocketServerChannel::Close() delete socket; } } + +int JackSocketServerChannel::Start() +{ + if (fThread.Start() != 0) { + jack_error("Cannot start Jack server listener"); + return -1; + } + + return 0; +} void JackSocketServerChannel::ClientCreate() { @@ -201,7 +202,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) JackResult res; jack_log("JackRequest::ActivateClient"); if (req.Read(socket) == 0) - res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fState); + res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); if (res.Write(socket) < 0) jack_error("JackRequest::ActivateClient write error ref = %d", req.fRefNum); break; @@ -395,7 +396,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) jack_error("Unknown request %ld", header.fType); break; } - + return true; } diff --git a/posix/JackSocketServerChannel.h b/posix/JackSocketServerChannel.h index 98a812aa..60b86325 100644 --- a/posix/JackSocketServerChannel.h +++ b/posix/JackSocketServerChannel.h @@ -59,8 +59,10 @@ class JackSocketServerChannel : public JackRunnableInterface JackSocketServerChannel(); ~JackSocketServerChannel(); - int Open(const char* server_name, JackServer* server); // Open the Server/Client connection - void Close(); // Close the Server/Client connection + int Open(const char* server_name, JackServer* server); // Open the Server/Client connection + void Close(); // Close the Server/Client connection + + int Start(); // JackRunnableInterface interface bool Init(); diff --git a/posix/JackSocketServerNotifyChannel.cpp b/posix/JackSocketServerNotifyChannel.cpp index b147fe06..c4e4888a 100644 --- a/posix/JackSocketServerNotifyChannel.cpp +++ b/posix/JackSocketServerNotifyChannel.cpp @@ -51,7 +51,7 @@ void JackSocketServerNotifyChannel::Notify(int refnum, int notify, int value) { JackClientNotificationRequest req(refnum, notify, value); if (req.Write(&fRequestSocket) < 0) { - jack_error("Could not write request ref = %ld notify = %ld", refnum, notify); + jack_error("Could not write request ref = %d notify = %d", refnum, notify); } } diff --git a/solaris/oss/JackBoomerDriver.cpp b/solaris/oss/JackBoomerDriver.cpp index 12c4fdaa..25056326 100644 --- a/solaris/oss/JackBoomerDriver.cpp +++ b/solaris/oss/JackBoomerDriver.cpp @@ -68,51 +68,51 @@ int gCycleWriteCount = 0; inline int int2pow2(int x) { int r = 0; while ((1 << r) < x) r++; return r; } -static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int chcount, int bits) +static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframes, int channel, int byte_skip, int bits) { switch (bits) { case 16: { signed short *s16src = (signed short*)src; s16src += channel; - sample_move_dS_s16(dst, (char*)s16src, nframes, chcount<<1); + sample_move_dS_s16(dst, (char*)s16src, nframes, byte_skip); break; } case 24: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; - sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); + sample_move_dS_s24(dst, (char*)s32src, nframes, byte_skip); break; } case 32: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; - sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); + sample_move_dS_s32u24(dst, (char*)s32src, nframes, byte_skip); break; } } } -static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int chcount, int bits) +static inline void CopyAndConvertOut(void *dst, jack_sample_t *src, size_t nframes, int channel, int byte_skip, int bits) { switch (bits) { case 16: { signed short *s16dst = (signed short*)dst; s16dst += channel; - sample_move_d16_sS((char*)s16dst, src, nframes, chcount<<1, NULL); // No dithering for now... + sample_move_d16_sS((char*)s16dst, src, nframes, byte_skip, NULL); // No dithering for now... break; } case 24: { signed int *s32dst = (signed int*)dst; s32dst += channel; - sample_move_d24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); // No dithering for now... + sample_move_d24_sS((char*)s32dst, src, nframes, byte_skip, NULL); break; } case 32: { signed int *s32dst = (signed int*)dst; s32dst += channel; - sample_move_d32u24_sS((char*)s32dst, src, nframes, chcount<<2, NULL); + sample_move_d32u24_sS((char*)s32dst, src, nframes, byte_skip, NULL); break; } } @@ -124,16 +124,16 @@ void JackBoomerDriver::SetSampleFormat() case 24: /* native-endian LSB aligned 24-bits in 32-bits integer */ fSampleFormat = AFMT_S24_NE; - fSampleSize = sizeof(int); + fSampleSize = 4; break; case 32: /* native-endian 32-bit integer */ fSampleFormat = AFMT_S32_NE; - fSampleSize = sizeof(int); + fSampleSize = 4; break; case 16: /* native-endian 16-bit integer */ default: fSampleFormat = AFMT_S16_NE; - fSampleSize = sizeof(short); + fSampleSize = 2; break; } } @@ -171,6 +171,7 @@ void JackBoomerDriver::DisplayDeviceInfo() } else { jack_info("output space info: fragments = %d, fragstotal = %d, fragsize = %d, bytes = %d", info.fragments, info.fragstotal, info.fragsize, info.bytes); + fFragmentSize = info.fragsize; } if (ioctl(fOutFD, SNDCTL_DSP_GETCAPS, &cap) == -1) { @@ -233,7 +234,8 @@ void JackBoomerDriver::DisplayDeviceInfo() JackBoomerDriver::JackBoomerDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) : JackAudioDriver(name, alias, engine, table), fInFD(-1), fOutFD(-1), fBits(0), - fSampleFormat(0), fNperiods(0), fRWMode(0), fExcl(false), + fSampleFormat(0), fNperiods(0), fSampleSize(0), fFragmentSize(0), + fRWMode(0), fExcl(false), fSyncIO(false), fInputBufferSize(0), fOutputBufferSize(0), fInputBuffer(NULL), fOutputBuffer(NULL), fInputThread(&fInputHandler), fOutputThread(&fOutputHandler), @@ -401,7 +403,7 @@ int JackBoomerDriver::Open(jack_nframes_t nframes, const char* playback_driver_uid, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - int bits) + int bits, bool syncio) { // Generic JackAudioDriver Open if (JackAudioDriver::Open(nframes, samplerate, capturing, playing, inchannels, outchannels, monitor, @@ -418,7 +420,8 @@ int JackBoomerDriver::Open(jack_nframes_t nframes, fRWMode |= ((playing) ? kWrite : 0); fBits = bits; fExcl = excl; - fNperiods = user_nperiods; + fNperiods = (user_nperiods == 0) ? 1 : user_nperiods ; + fSyncIO = syncio; #ifdef JACK_MONITOR // Force memory page in @@ -506,12 +509,12 @@ int JackBoomerDriver::OpenAux() void JackBoomerDriver::CloseAux() { - if (fRWMode & kRead && fInFD > 0) { + if (fRWMode & kRead && fInFD >= 0) { close(fInFD); fInFD = -1; } - if (fRWMode & kWrite && fOutFD > 0) { + if (fRWMode & kWrite && fOutFD >= 0) { close(fOutFD); fOutFD = -1; } @@ -530,8 +533,61 @@ int JackBoomerDriver::Start() jack_log("JackBoomerDriver::Start"); JackAudioDriver::Start(); + // Input/output synchronisation + if (fInFD >= 0 && fOutFD >= 0 && fSyncIO) { + + jack_log("JackBoomerDriver::Start sync input/output"); + + // Create and fill synch group + int id; + oss_syncgroup group; + group.id = 0; + + group.mode = PCM_ENABLE_INPUT; + if (ioctl(fInFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) + jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); + + group.mode = PCM_ENABLE_OUTPUT; + if (ioctl(fOutFD, SNDCTL_DSP_SYNCGROUP, &group) == -1) + jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCGROUP : %s@%i, errno = %d", __FILE__, __LINE__, errno); + + // Prefill output buffer : 2 fragments of silence as described in http://manuals.opensound.com/developer/synctest.c.html#LOC6 + char* silence_buf = (char*)malloc(fFragmentSize); + memset(silence_buf, 0, fFragmentSize); + + jack_log ("JackBoomerDriver::Start prefill size = %d", fFragmentSize); + + for (int i = 0; i < 2; i++) { + ssize_t count = ::write(fOutFD, silence_buf, fFragmentSize); + if (count < (int)fFragmentSize) { + jack_error("JackBoomerDriver::Start error bytes written = %ld", count); + } + } + + free(silence_buf); + + // Start input/output in sync + id = group.id; + + if (ioctl(fInFD, SNDCTL_DSP_SYNCSTART, &id) == -1) + jack_error("JackBoomerDriver::Start failed to use SNDCTL_DSP_SYNCSTART : %s@%i, errno = %d", __FILE__, __LINE__, errno); + + } else if (fOutFD >= 0) { + + // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html + memset(fOutputBuffer, 0, fOutputBufferSize); + + // Prefill ouput buffer + for (int i = 0; i < fNperiods; i++) { + ssize_t count = ::write(fOutFD, fOutputBuffer, fOutputBufferSize); + if (count < (int)fOutputBufferSize) { + jack_error("JackBoomerDriver::Start error bytes written = %ld", count); + } + } + } + // Start input thread only when needed - if (fInFD > 0) { + if (fInFD >= 0) { if (fInputThread.StartSync() < 0) { jack_error("Cannot start input thread"); return -1; @@ -539,7 +595,7 @@ int JackBoomerDriver::Start() } // Start output thread only when needed - if (fOutFD > 0) { + if (fOutFD >= 0) { if (fOutputThread.StartSync() < 0) { jack_error("Cannot start output thread"); return -1; @@ -552,12 +608,12 @@ int JackBoomerDriver::Start() int JackBoomerDriver::Stop() { // Stop input thread only when needed - if (fInFD > 0) { + if (fInFD >= 0) { fInputThread.Kill(); } // Stop output thread only when needed - if (fOutFD > 0) { + if (fOutFD >= 0) { fOutputThread.Kill(); } @@ -574,7 +630,7 @@ bool JackBoomerDriver::JackBoomerDriverInput::Init() set_threaded_log_function(); } } - + return true; } @@ -618,7 +674,12 @@ bool JackBoomerDriver::JackBoomerDriverInput::Execute() fDriver->CycleTakeBeginTime(); for (int i = 0; i < fDriver->fCaptureChannels; i++) { if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fCapturePortList[i]) > 0) { - CopyAndConvertIn(fDriver->GetInputBuffer(i), fDriver->fInputBuffer, fDriver->fEngineControl->fBufferSize, i, fDriver->fCaptureChannels, fDriver->fBits); + CopyAndConvertIn(fDriver->GetInputBuffer(i), + fDriver->fInputBuffer, + fDriver->fEngineControl->fBufferSize, + i, + fDriver->fCaptureChannels * fDriver->fSampleSize, + fDriver->fBits); } } @@ -629,7 +690,7 @@ bool JackBoomerDriver::JackBoomerDriverInput::Execute() } // Duplex : sync with write thread - if (fDriver->fInFD > 0 && fDriver->fOutFD > 0) { + if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { fDriver->SynchronizeRead(); } else { // Otherwise direct process @@ -648,27 +709,14 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Init() set_threaded_log_function(); } } - - // Maybe necessary to write an empty output buffer first time : see http://manuals.opensound.com/developer/fulldup.c.html - memset(fDriver->fOutputBuffer, 0, fDriver->fOutputBufferSize); - - // Prefill ouput buffer - if (fDriver->fOutFD > 0) { - for (int i = 0; i < fDriver->fNperiods; i++) { - ssize_t count = ::write(fDriver->fOutFD, fDriver->fOutputBuffer, fDriver->fOutputBufferSize); - if (count < (int)fDriver->fOutputBufferSize) { - jack_error("JackBoomerDriver::Write error bytes written = %ld", count); - } - } - - int delay; - if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { - jack_error("JackBoomerDriver::Write error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); - } - - delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; - jack_info("JackBoomerDriver::Write output latency frames = %ld", delay); + + int delay; + if (ioctl(fDriver->fOutFD, SNDCTL_DSP_GETODELAY, &delay) == -1) { + jack_error("JackBoomerDriverOutput::Init error get out delay : %s@%i, errno = %d", __FILE__, __LINE__, errno); } + + delay /= fDriver->fSampleSize * fDriver->fPlaybackChannels; + jack_info("JackBoomerDriverOutput::Init output latency frames = %ld", delay); return true; } @@ -683,7 +731,12 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Execute() for (int i = 0; i < fDriver->fPlaybackChannels; i++) { if (fDriver->fGraphManager->GetConnectionsNum(fDriver->fPlaybackPortList[i]) > 0) { - CopyAndConvertOut(fDriver->fOutputBuffer, fDriver->GetOutputBuffer(i), fDriver->fEngineControl->fBufferSize, i, fDriver->fPlaybackChannels, fDriver->fBits); + CopyAndConvertOut(fDriver->fOutputBuffer, + fDriver->GetOutputBuffer(i), + fDriver->fEngineControl->fBufferSize, + i, + fDriver->fPlaybackChannels * fDriver->fSampleSize, + fDriver->fBits); } } @@ -722,7 +775,7 @@ bool JackBoomerDriver::JackBoomerDriverOutput::Execute() } // Duplex : sync with read thread - if (fDriver->fInFD > 0 && fDriver->fOutFD > 0) { + if (fDriver->fInFD >= 0 && fDriver->fOutFD >= 0) { fDriver->SynchronizeWrite(); } else { // Otherwise direct process @@ -868,6 +921,14 @@ SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor() strcpy(desc->params[i].short_desc, "Extra output latency"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + i++; + strcpy(desc->params[i].name, "sync-io"); + desc->params[i].character = 'S'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = false; + strcpy(desc->params[i].short_desc, "In duplex mode, synchronize input and output"); + strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + return desc; } @@ -884,6 +945,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine int chan_out = 0; bool monitor = false; bool excl = false; + bool syncio = false; unsigned int nperiods = OSS_DRIVER_DEF_NPERIODS; const JSList *node; const jack_driver_param_t *param; @@ -950,6 +1012,10 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine case 'O': systemic_output_latency = param->value.ui; break; + + case 'S': + syncio = true; + break; } } @@ -963,7 +1029,7 @@ EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine // Special open for Boomer driver... if (boomer_driver->Open(frames_per_interrupt, nperiods, srate, capture, playback, chan_in, chan_out, excl, - monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits) == 0) { + monitor, capture_pcm_name, playback_pcm_name, systemic_input_latency, systemic_output_latency, bits, syncio) == 0) { return boomer_driver; } else { delete boomer_driver; // Delete the driver diff --git a/solaris/oss/JackBoomerDriver.h b/solaris/oss/JackBoomerDriver.h index c3281e1f..61fc5c50 100644 --- a/solaris/oss/JackBoomerDriver.h +++ b/solaris/oss/JackBoomerDriver.h @@ -30,7 +30,7 @@ namespace Jack typedef jack_default_audio_sample_t jack_sample_t; -#define OSS_DRIVER_N_PARAMS 12 +#define OSS_DRIVER_N_PARAMS 13 #define OSS_DRIVER_DEF_DEV "/dev/dsp" #define OSS_DRIVER_DEF_FS 48000 #define OSS_DRIVER_DEF_BLKSIZE 1024 @@ -91,9 +91,11 @@ class JackBoomerDriver : public JackAudioDriver int fSampleFormat; int fNperiods; unsigned int fSampleSize; + unsigned int fFragmentSize; int fRWMode; bool fExcl; - + bool fSyncIO; + unsigned int fInputBufferSize; unsigned int fOutputBufferSize; @@ -136,7 +138,7 @@ class JackBoomerDriver : public JackAudioDriver const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency, - int bits); + int bits, bool syncio); int Close(); diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index 3fffe425..de3fe89f 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -44,13 +44,13 @@ static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframe break; } case 24: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); break; } case 32: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); break; diff --git a/solaris/oss/JackOSSDriver.cpp b/solaris/oss/JackOSSDriver.cpp index f4d8507c..af0ed43b 100644 --- a/solaris/oss/JackOSSDriver.cpp +++ b/solaris/oss/JackOSSDriver.cpp @@ -78,13 +78,13 @@ static inline void CopyAndConvertIn(jack_sample_t *dst, void *src, size_t nframe break; } case 24: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s24(dst, (char*)s32src, nframes, chcount<<2); break; } case 32: { - signed short *s32src = (signed short*)src; + signed int *s32src = (signed int*)src; s32src += channel; sample_move_dS_s32u24(dst, (char*)s32src, nframes, chcount<<2); break; diff --git a/tests/test.cpp b/tests/test.cpp index 2358a891..e77edf49 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -220,6 +220,12 @@ void jack_shutdown(void *arg) exit(1); } +void jack_info_shutdown(jack_status_t code, const char* reason, void *arg) +{ + printf("JACK server failure : %s\n", reason); + exit(1); +} + void Jack_Port_Register(jack_port_id_t port, int mode, void *arg) { port_callback_reg++; @@ -679,6 +685,7 @@ int main (int argc, char *argv[]) } jack_on_shutdown(client1, jack_shutdown, 0); + jack_on_info_shutdown(client1, jack_info_shutdown, 0); if (jack_set_buffer_size_callback(client1, Jack_Update_Buffer_Size, 0) != 0) { printf("Error when calling buffer_size_callback !\n"); diff --git a/windows/JackShmMem_os.h b/windows/JackShmMem_os.h index 24fffb6a..37a419f2 100644 --- a/windows/JackShmMem_os.h +++ b/windows/JackShmMem_os.h @@ -21,7 +21,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackShmMem_WIN32__ #define __JackShmMem_WIN32__ -#include +#include + +// See GetProcessWorkingSetSize and SetProcessWorkingSetSize #define CHECK_MLOCK(ptr, size) (VirtualLock((ptr), (size)) != 0) #define CHECK_MUNLOCK(ptr, size) (VirtualUnlock((ptr), (size)) != 0) diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index b36f03e1..fedc1095 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -167,9 +167,9 @@ void JackWinNamedPipeClientChannel::ClientClose(int refnum, int* result) ServerSyncCall(&req, &res, result); } -void JackWinNamedPipeClientChannel::ClientActivate(int refnum, int state, int* result) +void JackWinNamedPipeClientChannel::ClientActivate(int refnum, int is_real_time, int* result) { - JackActivateRequest req(refnum, state); + JackActivateRequest req(refnum, is_real_time); JackResult res; ServerSyncCall(&req, &res, result); } @@ -315,7 +315,7 @@ bool JackWinNamedPipeClientChannel::Execute() goto error; } - res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fValue1, event.fValue2); + res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); if (event.fSync) { if (res.Write(&fNotificationListenPipe) < 0) { diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h index a2a3969b..32bf6a5d 100644 --- a/windows/JackWinNamedPipeClientChannel.h +++ b/windows/JackWinNamedPipeClientChannel.h @@ -64,7 +64,7 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, {} void ClientClose(int refnum, int* result); - void ClientActivate(int refnum, int state, int* result); + void ClientActivate(int refnum, int is_real_time, int* result); void ClientDeactivate(int refnum, 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); diff --git a/windows/JackWinNamedPipeNotifyChannel.cpp b/windows/JackWinNamedPipeNotifyChannel.cpp index 991f260c..a7375085 100644 --- a/windows/JackWinNamedPipeNotifyChannel.cpp +++ b/windows/JackWinNamedPipeNotifyChannel.cpp @@ -46,9 +46,9 @@ void JackWinNamedPipeNotifyChannel::Close() fNotifyPipe.Close(); } -void JackWinNamedPipeNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result) +void JackWinNamedPipeNotifyChannel::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result) { - JackClientNotification event(name, refnum, notify, sync, value1, value2); + JackClientNotification event(name, refnum, notify, sync, message, value1, value2); JackResult res; // Send notification diff --git a/windows/JackWinNamedPipeNotifyChannel.h b/windows/JackWinNamedPipeNotifyChannel.h index 0ade63d1..9d90e26b 100644 --- a/windows/JackWinNamedPipeNotifyChannel.h +++ b/windows/JackWinNamedPipeNotifyChannel.h @@ -44,7 +44,7 @@ class JackWinNamedPipeNotifyChannel int Open(const char* name); // Open the Server/Client connection void Close(); // Close the Server/Client connection - void ClientNotify(int refnum, const char* name, int notify, int sync, int value1, int value2, int* result); + void ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2, int* result); }; } // end of namespace diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index f3f2c288..da0da443 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -31,15 +31,17 @@ using namespace std; namespace Jack { -HANDLE JackClientPipeThread::fMutex = NULL; // never released.... +HANDLE JackClientPipeThread::fMutex = NULL; // Never released.... // fRefNum = -1 correspond to already removed client JackClientPipeThread::JackClientPipeThread(JackWinNamedPipeClient* pipe) - : fPipe(pipe), fServer(NULL), fThread(this), fRefNum(0) + :fPipe(pipe), fServer(NULL), fThread(this), fRefNum(0) { - if (fMutex == NULL) + // First one allocated the static fMutex + if (fMutex == NULL) { fMutex = CreateMutex(NULL, FALSE, NULL); + } } JackClientPipeThread::~JackClientPipeThread() @@ -50,15 +52,14 @@ JackClientPipeThread::~JackClientPipeThread() int JackClientPipeThread::Open(JackServer* server) // Open the Server/Client connection { - fServer = server; - // Start listening if (fThread.Start() != 0) { jack_error("Cannot start Jack server listener\n"); return -1; - } else { - return 0; } + + fServer = server; + return 0; } void JackClientPipeThread::Close() // Close the Server/Client connection @@ -74,7 +75,7 @@ void JackClientPipeThread::Close() // Close the Server/Client connection fPipe->Close(); fRefNum = -1; } - + bool JackClientPipeThread::Execute() { jack_log("JackClientPipeThread::Execute"); @@ -138,7 +139,7 @@ bool JackClientPipeThread::HandleRequest() JackResult res; jack_log("JackRequest::ActivateClient"); if (req.Read(fPipe) == 0) - res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fState); + res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); res.Write(fPipe); break; } @@ -316,7 +317,7 @@ bool JackClientPipeThread::HandleRequest() break; } } - + // Unlock the global mutex ReleaseMutex(fMutex); return ret; @@ -371,29 +372,18 @@ JackWinNamedPipeServerChannel::~JackWinNamedPipeServerChannel() int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* server) { jack_log("JackWinNamedPipeServerChannel::Open "); - - fServer = server; snprintf(fServerName, sizeof(fServerName), server_name); - + // Needed for internal connection from JackWinNamedPipeServerNotifyChannel object if (fRequestListenPipe.Bind(jack_server_dir, server_name, 0) < 0) { jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe"); - return false; - } - - // Start listening - if (fThread.Start() != 0) { - jack_error("Cannot start Jack server listener\n"); - goto error; + return -1; } - + + fServer = server; return 0; - -error: - fRequestListenPipe.Close(); - return -1; } - + void JackWinNamedPipeServerChannel::Close() { /* TODO : solve WIN32 thread Kill issue @@ -408,6 +398,16 @@ void JackWinNamedPipeServerChannel::Close() fRequestListenPipe.Close(); } +int JackWinNamedPipeServerChannel::Start() +{ + if (fThread.Start() != 0) { + jack_error("Cannot start Jack server listener"); + return -1; + } + + return 0; +} + bool JackWinNamedPipeServerChannel::Init() { jack_log("JackWinNamedPipeServerChannel::Init "); diff --git a/windows/JackWinNamedPipeServerChannel.h b/windows/JackWinNamedPipeServerChannel.h index 4026b541..7404f04d 100644 --- a/windows/JackWinNamedPipeServerChannel.h +++ b/windows/JackWinNamedPipeServerChannel.h @@ -50,9 +50,9 @@ class JackClientPipeThread : public JackRunnableInterface JackClientPipeThread(JackWinNamedPipeClient* pipe); virtual ~JackClientPipeThread(); - int Open(JackServer* server); // Open the Server/Client connection - void Close(); // Close the Server/Client connection - + int Open(JackServer* server); // Open the Server/Client connection + void Close(); // Close the Server/Client connection + bool HandleRequest(); // JackRunnableInterface interface @@ -88,8 +88,10 @@ class JackWinNamedPipeServerChannel : public JackRunnableInterface JackWinNamedPipeServerChannel(); ~JackWinNamedPipeServerChannel(); - int Open(const char* server_name, JackServer* server); // Open the Server/Client connection - void Close(); // Close the Server/Client connection + int Open(const char* server_name, JackServer* server); // Open the Server/Client connection + void Close(); // Close the Server/Client connection + + int Start(); // JackRunnableInterface interface bool Init(); diff --git a/windows/JackWinNamedPipeServerNotifyChannel.cpp b/windows/JackWinNamedPipeServerNotifyChannel.cpp index 7f2f14cf..1e3c4e21 100644 --- a/windows/JackWinNamedPipeServerNotifyChannel.cpp +++ b/windows/JackWinNamedPipeServerNotifyChannel.cpp @@ -50,7 +50,7 @@ void JackWinNamedPipeServerNotifyChannel::Notify(int refnum, int notify, int val { JackClientNotificationRequest req(refnum, notify, value); if (req.Write(&fRequestPipe) < 0) { - jack_error("Could not write request ref = %ld notify = %ld", refnum, notify); + jack_error("Could not write request ref = %d notify = %d", refnum, notify); } } diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index 4042f573..3893d220 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -58,7 +58,7 @@ JackWinThread::JackWinThread(JackRunnableInterface* runnable) : JackThreadInterface(runnable, 0, false, 0) { fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - fThread = NULL; + fThread = (HANDLE)NULL; assert(fEvent); } @@ -126,12 +126,12 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa int JackWinThread::Kill() { - if (fThread) { // If thread has been started + if (fThread != (HANDLE)NULL) { // If thread has been started TerminateThread(fThread, 0); WaitForSingleObject(fThread, INFINITE); CloseHandle(fThread); jack_log("JackWinThread::Kill"); - fThread = NULL; + fThread = (HANDLE)NULL; fStatus = kIdle; return 0; } else { @@ -141,12 +141,12 @@ int JackWinThread::Kill() int JackWinThread::Stop() { - if (fThread) { // If thread has been started + if (fThread != (HANDLE)NULL) { // If thread has been started jack_log("JackWinThread::Stop"); fStatus = kIdle; // Request for the thread to stop WaitForSingleObject(fEvent, INFINITE); CloseHandle(fThread); - fThread = NULL; + fThread = (HANDLE)NULL; return 0; } else { return -1; @@ -155,7 +155,7 @@ int JackWinThread::Stop() int JackWinThread::KillImp(pthread_t thread) { - if (thread) { // If thread has been started + if (thread != (HANDLE)NULL) { // If thread has been started TerminateThread(thread, 0); WaitForSingleObject(thread, INFINITE); CloseHandle(thread); @@ -178,7 +178,12 @@ int JackWinThread::StopImp(pthread_t thread) int JackWinThread::AcquireRealTime() { - return (fThread) ? AcquireRealTimeImp(fThread, fPriority) : -1; + return (fThread != (HANDLE)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; +} + +int JackWinThread::AcquireSelfRealTime() +{ + return AcquireRealTimeImp(GetCurrentThread(), fPriority); } int JackWinThread::AcquireRealTime(int priority) @@ -187,6 +192,12 @@ int JackWinThread::AcquireRealTime(int priority) return AcquireRealTime(); } +int JackWinThread::AcquireSelfRealTime(int priority) +{ + fPriority = priority; + return AcquireSelfRealTime(); +} + int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority) { jack_log("JackWinThread::AcquireRealTime"); @@ -198,9 +209,15 @@ int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority) return -1; } } + int JackWinThread::DropRealTime() { - return DropRealTimeImp(fThread); + return (fThread != (HANDLE)NULL) ? DropRealTimeImp(fThread) : -1; +} + +int JackWinThread::DropSelfRealTime() +{ + return DropRealTimeImp(GetCurrentThread()); } int JackWinThread::DropRealTimeImp(pthread_t thread) diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index 11ab8af5..a3a5a25c 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -57,10 +57,15 @@ class SERVER_EXPORT JackWinThread : public detail::JackThreadInterface int Stop(); void Terminate(); - int AcquireRealTime(); - int AcquireRealTime(int priority) ; - int DropRealTime(); - + int AcquireRealTime(); // Used when called from another thread + int AcquireSelfRealTime(); // Used when called from thread itself + + int AcquireRealTime(int priority); // Used when called from another thread + int AcquireSelfRealTime(int priority); // Used when called from thread itself + + int DropRealTime(); // Used when called from another thread + int DropSelfRealTime(); // Used when called from thread itself + pthread_t GetThreadID(); static int AcquireRealTimeImp(pthread_t thread, int priority); diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index df435bed..226ea667 100644 Binary files a/windows/Setup/JackRouter.dll and b/windows/Setup/JackRouter.dll differ diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index a0ae1a66..2c3eb9a0 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -1,9 +1,9 @@ <*project version = 4 civer = "Free v4.14.5" winver = "2.6/5.1.2600" > . - Jack_v1.9.3_setup.exe + Jack_v1.9.4_setup.exe - Jack v1.9.3 + Jack v1.9.4 Default - 2 diff --git a/windows/Setup/src/README b/windows/Setup/src/README index e9424a26..a33ec512 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -20,9 +20,9 @@ It is compiled from the latest CVS version which is using QT4 framework. To uses - in Setup/Misc, check the "Start JACK audio server at application startup" box -- quit qjackctl.exe and start is again, it should now launch the jack server. Quitting the qjackctl.exe will now close the jack server. +- quit QJACKCTL and start is again, it should now launch the jack server. Quitting QJACKCTL will now close the jack server. -Starting the jack server with another audio device installed on the machine (like an ASIO card) can now be done directly in qjackctl. +Starting the jack server with another audio device installed on the machine (like an ASIO card) can now be done directly in QJACKCTL. A ">" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "DirectSound", or "ASIO". Alternatively using the following command allows to display the names of available devices: @@ -30,7 +30,7 @@ Alternatively using the following command allows to display the names of availab Then start jackd with the device you want, by using its name, for example: -- jackd -R -S -d portaudio -d "ASIO::MOTU Audio ASIO", then start qjackctl. qjackctl will see the jackd server already running and then can be used normally. +- jackd -R -S -d portaudio -d "ASIO::MOTU Audio ASIO", then start QJACKCTL. QJACKCTL will see the jackd server already running and then can be used normally. ============================================= @@ -47,9 +47,9 @@ QJACKCTL MIDI connection windows can then be used. JackRouter JACK/ASIO driver ============================================= -JackRouter is an ASIO driver that allows any ASIO compatible application to become a JACK client, thus exchange audio with any other "native" or "Jackified" application. This driver is registered in the system by the installer and becomes available in the list of ASIO drivers when the JACK server is running. A "JackRouter.ini" configuration file allows the application to confgiure how the JackRouter driver behaves. +JackRouter is an ASIO driver that allows any ASIO compatible application to become a JACK client, thus exchange audio with any other "native" or "Jackified" application. This driver is registered in the system by the installer and becomes available in the list of ASIO drivers when the JACK server is running. A "JackRouter.ini" configuration file allows the application to configure how the JackRouter driver behaves. - - [IO]: the application can obtain any number if JACK input/output ports (not necessarilly equal to the audio card input/output number). [Note that some applications force their input/output channel number]. + - [IO]: the application can obtain any number if JACK input/output ports (not necessarily equal to the audio card input/output number). [Note that some applications force their input/output channel number]. - [AUTO_CONNECT] : when 1, the application JACK port will automatically be connected to the machine input/output JACK ports. diff --git a/wscript b/wscript index f5b69855..a9128cca 100644 --- a/wscript +++ b/wscript @@ -68,7 +68,7 @@ def set_options(opt): opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=1024, type="int", dest="ports", help='Maximum number of ports') + opt.add_option('--ports', default=2048, type="int", dest="ports", help='Maximum number of ports') opt.add_option('--ports-per-application', default=512, type="int", dest="application_ports", help='Maximum number of ports per application') opt.sub_options('dbus') @@ -114,6 +114,19 @@ def configure(conf): conf.sub_config('dbus') conf.sub_config('example-clients') + if conf.check_cfg(package='celt', atleast_version='0.7.0', args='--cflags --libs'): + conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_7', 1) + conf.define('HAVE_CELT_API_0_5', 0) + elif conf.check_cfg(package='celt', atleast_version='0.5.0', args='--cflags --libs', required=True): + conf.define('HAVE_CELT', 1) + conf.define('HAVE_CELT_API_0_5', 1) + conf.define('HAVE_CELT_API_0_7', 0) + else: + conf.define('HAVE_CELT', 0) + conf.define('HAVE_CELT_API_0_5', 0) + conf.define('HAVE_CELT_API_0_7', 0) + conf.env['LIB_PTHREAD'] = ['pthread'] conf.env['LIB_DL'] = ['dl'] conf.env['LIB_RT'] = ['rt'] @@ -218,11 +231,11 @@ def configure(conf): conf.env.append_unique('CXXFLAGS', '-m32') conf.env.append_unique('CCFLAGS', '-m32') conf.env.append_unique('LINKFLAGS', '-m32') - conf.write_config_header('config.h') if Options.options.libdir32: conf.env['LIBDIR'] = conf.env['PREFIX'] + Options.options.libdir32 else: conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib32' + conf.write_config_header('config.h') def build(bld): print ("make[1]: Entering directory `" + os.getcwd() + "/" + blddir + "'" )