summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsletz <sletz@0c269be4-1314-0410-8aa9-9f06e86f4224>2009-11-19 10:49:03 +0000
committersletz <sletz@0c269be4-1314-0410-8aa9-9f06e86f4224>2009-11-19 10:49:03 +0000
commit6b765f01687b55584eadb52bf51074a815f7e9b5 (patch)
tree9175b82e627265368e89157dd9b2aa7e63301e1f
parent224c41eb59c0a8d547bd7e322b0e1185a1558cde (diff)
downloadjack2-6b765f01687b55584eadb52bf51074a815f7e9b5.tar.gz
rebase from trunk 3684:3813
git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3814 0c269be4-1314-0410-8aa9-9f06e86f4224
-rw-r--r--ChangeLog69
-rw-r--r--README1
-rw-r--r--common/JackAPI.cpp31
-rw-r--r--common/JackArgParser.cpp4
-rw-r--r--common/JackClient.cpp60
-rw-r--r--common/JackConstants.h2
-rw-r--r--common/JackControlAPI.cpp5
-rw-r--r--common/JackEngine.cpp12
-rw-r--r--common/JackEngineControl.h2
-rw-r--r--common/JackException.h20
-rw-r--r--common/JackGraphManager.cpp36
-rw-r--r--common/JackLibAPI.cpp24
-rw-r--r--common/JackLockedEngine.h89
-rw-r--r--common/JackMessageBuffer.cpp2
-rw-r--r--common/JackNetAdapter.cpp6
-rw-r--r--common/JackNetOneDriver.cpp1143
-rw-r--r--common/JackNetOneDriver.h96
-rw-r--r--common/JackRestartThreadedDriver.cpp2
-rw-r--r--common/JackServerAPI.cpp24
-rw-r--r--common/JackServerGlobals.cpp1
-rw-r--r--common/JackServerGlobals.h1
-rw-r--r--common/JackShmMem.cpp11
-rw-r--r--common/JackShmMem.h26
-rw-r--r--common/JackThread.h11
-rw-r--r--common/JackThreadedDriver.cpp4
-rw-r--r--common/JackTools.cpp42
-rw-r--r--common/JackTools.h9
-rw-r--r--common/JackTransportEngine.cpp3
-rw-r--r--common/JackWaitThreadedDriver.cpp6
-rw-r--r--common/JackWeakAPI.cpp187
-rw-r--r--common/Jackdmp.cpp58
-rw-r--r--common/jack/jack.h37
-rw-r--r--common/jack/jslist.h12
-rw-r--r--common/jack/types.h41
-rw-r--r--common/netjack.c746
-rw-r--r--common/netjack.h147
-rw-r--r--common/netjack_packet.c1520
-rw-r--r--common/netjack_packet.h165
-rw-r--r--common/ringbuffer.c382
-rw-r--r--dbus/sigsegv.c4
-rw-r--r--example-clients/alsa_in.c757
-rw-r--r--example-clients/alsa_out.c755
-rw-r--r--example-clients/bufsize.c21
-rw-r--r--example-clients/internal_metro.cpp2
-rw-r--r--example-clients/netsource.c780
-rw-r--r--example-clients/samplerate.c85
-rw-r--r--example-clients/wait.c136
-rw-r--r--example-clients/wscript48
-rw-r--r--example-clients/zombie.c3
-rw-r--r--linux/wscript10
-rw-r--r--macosx/JackMachServerChannel.cpp4
-rw-r--r--macosx/JackMachServerNotifyChannel.cpp2
-rw-r--r--macosx/JackMachThread.cpp32
-rw-r--r--macosx/JackMachThread.h12
-rw-r--r--macosx/Jackdmp.xcodeproj/project.pbxproj1696
-rw-r--r--macosx/coreaudio/JackCoreAudioAdapter.cpp370
-rw-r--r--macosx/coreaudio/JackCoreAudioAdapter.h6
-rw-r--r--macosx/coreaudio/JackCoreAudioDriver.cpp330
-rw-r--r--macosx/coreaudio/JackCoreAudioDriver.h11
-rwxr-xr-xmacosx/install_jackdmp2
-rw-r--r--macosx/wscript9
-rw-r--r--posix/JackPosixThread.cpp50
-rw-r--r--posix/JackPosixThread.h11
-rw-r--r--posix/JackSocketServerChannel.cpp7
-rw-r--r--posix/JackSocketServerNotifyChannel.cpp2
-rw-r--r--tests/test.cpp2
-rw-r--r--windows/JackShmMem_os.h4
-rw-r--r--windows/JackWinNamedPipeServerChannel.cpp9
-rw-r--r--windows/JackWinNamedPipeServerNotifyChannel.cpp2
-rw-r--r--windows/JackWinThread.cpp33
-rw-r--r--windows/JackWinThread.h13
-rw-r--r--windows/Setup/JackRouter.dllbin32768 -> 32768 bytes
-rw-r--r--windows/Setup/jack.ci4
-rw-r--r--wscript15
74 files changed, 9358 insertions, 906 deletions
diff --git a/ChangeLog b/ChangeLog
index f5aed4c9..00471db2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,62 @@ Paul Davis
Jackdmp changes log
---------------------------
+2009-11-18 Stephane Letz <letz@grame.fr>
+
+ * Sync JackCoreAudioAdapter code with JackCoreAudioDriver.
+
+2009-11-17 Stephane Letz <letz@grame.fr>
+
+ * 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 <letz@grame.fr>
+
+ * In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices.
+
+2009-11-14 Stephane Letz <letz@grame.fr>
+
+ * 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 <letz@grame.fr>
+
+ * 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 <letz@grame.fr>
+
+ * Better memory allocation error checking on client (library) side.
+
+2009-11-11 Stephane Letz <letz@grame.fr>
+
+ * Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter.
+
+2009-11-10 Stephane Letz <letz@grame.fr>
+
+ * Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code.
+
+2009-11-09 Stephane Letz <letz@grame.fr>
+
+ * Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied.
+
+2009-11-07 Stephane Letz <letz@grame.fr>
+
+ * 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 <letz@grame.fr>
+
+ * Correctly save and restore RT mode state in freewheel mode.
+ * Correct freewheel code on client side.
+
+2009-11-05 Stephane Letz <letz@grame.fr>
+
+ * 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 <letz@grame.fr>
* In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value.
@@ -32,6 +88,7 @@ Paul Davis
* 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 <letz@grame.fr>
@@ -398,12 +455,12 @@ Paul Davis
2009-01-05 Stephane Letz <letz@grame.fr>
- * 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 <letz@grame.fr>
- * 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.
@@ -437,13 +494,13 @@ Paul Davis
2008-11-27 Stephane Letz <letz@grame.fr>
* Add timing profiling code in JackOSSDriver.
- * Report ringbuffer.c fixes from jack1.
+ * Report ringbuffer.c fixes from JACK1.
2008-11-21 Stephane Letz <letz@grame.fr>
- * 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 <letz@grame.fr>
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 34e591e4..97e58833 100644
--- a/common/JackAPI.cpp
+++ b/common/JackAPI.cpp
@@ -290,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)
@@ -814,7 +822,6 @@ EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback cal
JackLibGlobals::CheckContext();
#endif
JackClient* client = (JackClient*)ext_client;
- jack_error("jack_on_shutdown: deprecated, use jack_on_info_shutdown");
if (client == NULL) {
jack_error("jack_on_shutdown called with a NULL client");
} else {
@@ -1944,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/JackClient.cpp b/common/JackClient.cpp
index 7cfb50ef..e6469267 100644
--- a/common/JackClient.cpp
+++ b/common/JackClient.cpp
@@ -170,90 +170,105 @@ 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(value1, message, fInfoShutdownArg);
+ fInfoShutdown((jack_status_t)value1, message, fInfoShutdownArg);
fInfoShutdown = NULL;
}
break;
@@ -454,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();
@@ -465,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();
@@ -973,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/JackConstants.h b/common/JackConstants.h
index 00a0be99..aa6e0ce5 100644
--- a/common/JackConstants.h
+++ b/common/JackConstants.h
@@ -41,7 +41,7 @@
#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 488046c9..37eeb88a 100644
--- a/common/JackControlAPI.cpp
+++ b/common/JackControlAPI.cpp
@@ -611,6 +611,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/JackEngine.cpp b/common/JackEngine.cpp
index 83a22ad4..537c4160 100644
--- a/common/JackEngine.cpp
+++ b/common/JackEngine.cpp
@@ -119,7 +119,7 @@ void JackEngine::ReleaseRefnum(int ref)
// last client and temporay case: quit the server
jack_log("JackEngine::ReleaseRefnum server quit");
fEngineControl->fTemporary = false;
- JackServerGlobals::fKilled = true;
+ throw JackTemporaryException();
}
}
}
@@ -305,7 +305,15 @@ void JackEngine::NotifyFailure(int code, const char* reason)
void JackEngine::NotifyFreewheel(bool onoff)
{
- fEngineControl->fRealTime = !onoff;
+ 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);
}
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/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/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/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/JackLockedEngine.h b/common/JackLockedEngine.h
index d1d9d3d1..c2de8512 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 is_real_time)
{
+ TRY_CALL
JackLock lock(this);
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,48 +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 bc380a52..8dacfe67 100644
--- a/common/JackMessageBuffer.cpp
+++ b/common/JackMessageBuffer.cpp
@@ -46,7 +46,7 @@ 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;
diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp
index c1817848..8eff6900 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/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 <malloc.h>
+#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<JackPortFlags> ( 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<JackPortFlags> ( 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<JackPortFlags> ( 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<JackPortFlags> ( 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; r<netj.redundancy; r++ )
+ netjack_sendto(netj.sockfd, (char *)packet_buf, packet_size,
+ flag, (struct sockaddr*)&(netj.syncsource_address), sizeof(struct sockaddr_in), netj.mtu);
+ }
+ return 0;
+ }
+
+void
+JackNetOneDriver::FreePorts ()
+{
+ JSList *node = netj.capture_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.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/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/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.cpp b/common/JackServerGlobals.cpp
index 18dfaf66..7698c640 100644
--- a/common/JackServerGlobals.cpp
+++ b/common/JackServerGlobals.cpp
@@ -28,7 +28,6 @@ static char* server_name = NULL;
namespace Jack
{
-bool JackServerGlobals::fKilled = false;
JackServer* JackServerGlobals::fInstance;
unsigned int JackServerGlobals::fUserCount;
bool (* JackServerGlobals::on_device_acquire)(const char * device_name) = NULL;
diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h
index e037f69b..00d8b0ff 100644
--- a/common/JackServerGlobals.h
+++ b/common/JackServerGlobals.h
@@ -36,7 +36,6 @@ class JackClient;
struct SERVER_EXPORT JackServerGlobals
{
- static bool fKilled;
static JackServer* fInstance;
static unsigned int fUserCount;
static bool (* on_device_acquire)(const char * device_name);
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 df2b6d27..52e49197 100644
--- a/common/JackThreadedDriver.cpp
+++ b/common/JackThreadedDriver.cpp
@@ -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/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 <string>
#include <algorithm>
@@ -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(): JackAtomicArrayState<jack_position_t
{
fTransportState = JackTransportStopped;
fTransportCmd = fPreviousCmd = TransportCommandStop;
- fSyncTimeout = 2000000; /* 2 second default */
+ fSyncTimeout = 10000000; /* 10 seconds default...
+ in case of big netjack1 roundtrip */
fSyncTimeLeft = 0;
fTimeBaseMaster = -1;
fWriteCounter = 0;
diff --git a/common/JackWaitThreadedDriver.cpp b/common/JackWaitThreadedDriver.cpp
index 7d0eee73..0da831fa 100644
--- a/common/JackWaitThreadedDriver.cpp
+++ b/common/JackWaitThreadedDriver.cpp
@@ -48,8 +48,8 @@ bool JackWaitThreadedDriver::Execute()
// 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();
}
@@ -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 <jack/jack.h>
+#include <jack/thread.h>
+#include <jack/midiport.h>
#include <math.h>
#include <dlfcn.h>
#include <stdlib.h>
@@ -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 a414b8b4..9045827c 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,11 +176,12 @@ 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;
#ifdef __linux__
- const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:c:L:";
+ const char *options = "-ad:X:P:uvshVrRL:STFl:t:mn:p:c:L:";
#else
- const char *options = "-ad:X:P:uvrshVRL:STFl:t:mn:p:L:";
+ const char *options = "-ad:X:P:uvshVrRL:STFl:t:mn:p:L:";
#endif
struct option long_options[] = {
@@ -184,7 +198,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' },
@@ -224,8 +239,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,
@@ -315,11 +338,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;
@@ -361,7 +384,14 @@ int main(int argc, char* argv[])
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
diff --git a/common/jack/jack.h b/common/jack/jack.h
index ebdded77..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
* @{
@@ -282,7 +301,7 @@ int jack_set_thread_init_callback (jack_client_t *client,
* @param function The jack_shutdown function pointer.
* @param arg The arguments for the jack_shutdown function.
*
- * @deprecated Register a function (and argument) to be called if and when the
+ * 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
@@ -294,14 +313,19 @@ 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_shutdown function pointer.
- * @param arg The arguments for the jack_shutdown function.
+ * @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
@@ -315,6 +339,11 @@ void jack_on_shutdown (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_info_shutdown (jack_client_t *client,
JackInfoShutdownCallback shutdown_callback, void *arg);
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 f7e03d3c..fd71ceac 100644
--- a/common/jack/types.h
+++ b/common/jack/types.h
@@ -214,7 +214,7 @@ typedef int (*JackPortRenameCallback)(jack_port_id_t port, const char* new_name,
typedef void (*JackFreewheelCallback)(int starting, void *arg);
/**
- * @deprecated Prototype for the client supplied function that is called
+ * 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()
@@ -227,21 +227,6 @@ typedef void (*JackFreewheelCallback)(int starting, void *arg);
typedef void (*JackShutdownCallback)(void *arg);
/**
- * 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 shuntdown code
- * @param reason a string discribing the shuntdown reason (backend failure, server crash... etc...)
- * @param arg pointer to a client supplied structure
- */
-typedef void (*JackInfoShutdownCallback)(int code, const char* reason, void *arg);
-
-/**
* Used for the type argument of jack_port_register() for default
* audio ports and midi ports.
*/
@@ -437,9 +422,14 @@ enum JackStatus {
JackVersionError = 0x400,
/**
- * Backend failure
+ * Backend error
+ */
+ JackBackendError = 0x800,
+
+ /**
+ * Client zombified failure
*/
- JackBackendError = 0x800
+ JackClientZombie = 0x1000
};
/**
@@ -664,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/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 <pieterpalmers@users.sourceforge.net>
+Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
+Copyright (C) 2003 Robert Ham <rah@bash.sh>
+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 <math.h>
+#include <stdio.h>
+#include <memory.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdarg.h>
+
+#include <jack/types.h>
+#include "jack/jslist.h"
+
+#include <sys/types.h>
+
+#ifdef WIN32
+#include <winsock.h>
+#include <malloc.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+#include "netjack.h"
+
+//#include "config.h"
+
+#if HAVE_SAMPLERATE
+#include <samplerate.h>
+#endif
+
+#if HAVE_CELT
+#include <celt/celt.h>
+#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; r<netj->redundancy; 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 <rah@bash.sh>
+ Copyright (C) 2005 Torben Hohn <torbenh@gmx.de>
+
+ 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 <unistd.h>
+
+#include <jack/types.h>
+//#include <jack/driver.h>
+#include <jack/jack.h>
+#include <jack/transport.h>
+
+#include "jack/jslist.h"
+
+//#include <netinet/in.h>
+
+#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 <marco@marcochapeau.org>
+ * Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
+ * Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
+ *
+ * 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 <math.h>
+#include <stdio.h>
+#include <memory.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdarg.h>
+
+#include <jack/types.h>
+
+#include <sys/types.h>
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <malloc.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <poll.h>
+#endif
+
+#include <errno.h>
+#include <signal.h>
+
+#if HAVE_SAMPLERATE
+#include <samplerate.h>
+#endif
+
+#if HAVE_CELT
+#include <celt/celt.h>
+#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 <torbenh@gmx.de>
+ *
+ * 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 <jack/jack.h>
+#include <jack/types.h>
+//#include <jack/engine.h>
+#include <jack/jslist.h>
+
+#include <jack/midiport.h>
+
+//#include <netinet/in.h>
+// 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/sigsegv.c b/dbus/sigsegv.c
index 46645408..26bc204f 100644
--- a/dbus/sigsegv.c
+++ b/dbus/sigsegv.c
@@ -26,12 +26,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
-#include <ucontext.h>
#include <dlfcn.h>
#include <execinfo.h>
#include <errno.h>
#ifndef NO_CPP_DEMANGLE
-//#include <cxxabi.h>
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 <ucontext.h>
+
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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#include <alloca.h>
+#include <math.h>
+
+#include <jack/jack.h>
+#include <jack/jslist.h>
+#include <memops.h>
+
+#include "alsa/asoundlib.h"
+
+#include <samplerate.h>
+
+// 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<NUMFORMATS; i++ ) {
+ /* set the sample format */
+ err = snd_pcm_hw_params_set_format(handle, params, formats[i].format_id);
+ if (err == 0) {
+ format = i;
+ return 0;
+ }
+ }
+
+ return err;
+}
+
+static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) {
+ int err, dir=0;
+ unsigned int buffer_time;
+ unsigned int period_time;
+ unsigned int rrate;
+ unsigned int rchannels;
+
+ /* choose all parameters */
+ err = snd_pcm_hw_params_any(handle, params);
+ if (err < 0) {
+ printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* set the interleaved read/write format */
+ err = snd_pcm_hw_params_set_access(handle, params, access);
+ if (err < 0) {
+ printf("Access type not available for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+
+ /* set the sample format */
+ err = set_hwformat(handle, params);
+ if (err < 0) {
+ printf("Sample format not available for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* set the count of channels */
+ rchannels = channels;
+ err = snd_pcm_hw_params_set_channels_near(handle, params, &rchannels);
+ if (err < 0) {
+ printf("Channels count (%i) not available for record: %s\n", channels, snd_strerror(err));
+ return err;
+ }
+ if (rchannels != channels) {
+ printf("WARNING: chennel count does not match (requested %d got %d)\n", channels, rchannels);
+ num_channels = rchannels;
+ }
+ /* set the stream rate */
+ rrate = rate;
+ err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
+ if (err < 0) {
+ printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
+ return err;
+ }
+ if (rrate != rate) {
+ printf("WARNING: Rate doesn't match (requested %iHz, get %iHz)\n", rate, rrate);
+ sample_rate = rrate;
+ }
+ /* set the buffer time */
+
+ buffer_time = 1000000*period*nperiods/rate;
+ err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
+ if (err < 0) {
+ printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_hw_params_get_buffer_size( params, &real_buffer_size );
+ if (err < 0) {
+ printf("Unable to get buffer size back: %s\n", snd_strerror(err));
+ return err;
+ }
+ if( real_buffer_size != nperiods * period ) {
+ printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size );
+ }
+ /* set the period time */
+ period_time = 1000000*period/rate;
+ err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
+ if (err < 0) {
+ printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_hw_params_get_period_size(params, &real_period_size, NULL );
+ if (err < 0) {
+ printf("Unable to get period size back: %s\n", snd_strerror(err));
+ return err;
+ }
+ if( real_period_size != period ) {
+ printf( "WARNING: period size does not match: (requested %i, got %i)\n", period, (int)real_period_size );
+ }
+ /* write the parameters to device */
+ err = snd_pcm_hw_params(handle, params);
+ if (err < 0) {
+ printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ return 0;
+}
+
+static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int period) {
+ int err;
+
+ /* get the current swparams */
+ err = snd_pcm_sw_params_current(handle, swparams);
+ if (err < 0) {
+ printf("Unable to determine current swparams for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* start the transfer when the buffer is full */
+ err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period );
+ if (err < 0) {
+ printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, -1 );
+ if (err < 0) {
+ printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* allow the transfer when at least period_size samples can be processed */
+ err = snd_pcm_sw_params_set_avail_min(handle, swparams, 2*period );
+ if (err < 0) {
+ printf("Unable to set avail min for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* align all transfers to 1 sample */
+ err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
+ if (err < 0) {
+ printf("Unable to set transfer align for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* write the parameters to the playback device */
+ err = snd_pcm_sw_params(handle, swparams);
+ if (err < 0) {
+ printf("Unable to set sw params for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ return 0;
+}
+
+// ok... i only need this function to communicate with the alsa bloat api...
+
+static snd_pcm_t *open_audiofd( char *device_name, int capture, int rate, int channels, int period, int nperiods ) {
+ int err;
+ snd_pcm_t *handle;
+ snd_pcm_hw_params_t *hwparams;
+ snd_pcm_sw_params_t *swparams;
+
+ snd_pcm_hw_params_alloca(&hwparams);
+ snd_pcm_sw_params_alloca(&swparams);
+
+ if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) {
+ printf("Capture open error: %s\n", snd_strerror(err));
+ return NULL;
+ }
+
+ if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) {
+ printf("Setting of hwparams failed: %s\n", snd_strerror(err));
+ return NULL;
+ }
+ if ((err = set_swparams(handle, swparams, period)) < 0) {
+ printf("Setting of swparams failed: %s\n", snd_strerror(err));
+ return NULL;
+ }
+
+ snd_pcm_start( handle );
+ snd_pcm_wait( handle, 200 );
+
+ return handle;
+}
+
+double hann( double x )
+{
+ return 0.5 * (1.0 - cos( 2*M_PI * x ) );
+}
+
+/**
+ * The process callback for this JACK application.
+ * It is called by JACK at the appropriate times.
+ */
+int process (jack_nframes_t nframes, void *arg) {
+
+ char *outbuf;
+ float *resampbuf;
+ int rlen;
+ int err;
+ snd_pcm_sframes_t delay = target_delay;
+ int put_back_samples=0;
+ int i;
+
+ delay = snd_pcm_avail( alsa_handle );
+
+ delay -= jack_frames_since_cycle_start( client );
+ // Do it the hard way.
+ // this is for compensating xruns etc...
+
+ if( delay > (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<smooth_size; i++ )
+ offset_array[i] = 0.0;
+ }
+ if( delay < (target_delay-max_diff) ) {
+ snd_pcm_rewind( alsa_handle, target_delay - delay );
+ output_new_delay = (int) delay;
+ delay = target_delay;
+
+ // Set the resample_rate... we need to adjust the offset integral, to do this.
+ 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<smooth_size; i++ )
+ offset_array[i] = 0.0;
+ }
+ /* ok... now we should have target_delay +- max_diff on the alsa side.
+ *
+ * calculate the number of frames, we want to get.
+ */
+
+ double offset = delay - target_delay;
+
+ // Save offset.
+ offset_array[(offset_differential_index++)% smooth_size ] = offset;
+
+ // Build the mean of the windowed offset array
+ // basically fir lowpassing.
+ double smooth_offset = 0.0;
+ for( i=0; i<smooth_size; i++ )
+ smooth_offset +=
+ offset_array[ (i + offset_differential_index-1) % smooth_size] * window_array[i];
+ smooth_offset /= (double) smooth_size;
+
+ // this is the integral of the smoothed_offset
+ offset_integral += smooth_offset;
+
+ // Clamp offset.
+ // the smooth offset still contains unwanted noise
+ // which would go straigth onto the resample coeff.
+ // it only used in the P component and the I component is used for the fine tuning anyways.
+ if( fabs( smooth_offset ) < pclamp )
+ smooth_offset = 0.0;
+
+ // ok. now this is the PI controller.
+ // u(t) = K * ( e(t) + 1/T \int e(t') dt' )
+ // K = 1/catch_factor and T = catch_factor2
+ double current_resample_factor = static_resample_factor - smooth_offset / (double) catch_factor - offset_integral / (double) catch_factor / (double)catch_factor2;
+
+ // now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt.
+ current_resample_factor = floor( (current_resample_factor - resample_mean) * controlquant + 0.5 ) / controlquant + resample_mean;
+
+ // Output "instrumentatio" gonna change that to real instrumentation in a few.
+ output_resampling_factor = (float) current_resample_factor;
+ output_diff = (float) smooth_offset;
+ output_integral = (float) offset_integral;
+ output_offset = (float) offset;
+
+ // Clamp a bit.
+ if( current_resample_factor < 0.25 ) current_resample_factor = 0.25;
+ if( current_resample_factor > 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 <jack name> - client name\n"
+ " -d <alsa_device> \n"
+ " -c <channels> \n"
+ " -p <period_size> \n"
+ " -n <num_period> \n"
+ " -r <sample_rate> \n"
+ " -q <sample_rate quality [0..4]\n"
+ " -m <max_diff> \n"
+ " -t <target_delay> \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<smooth_size; i++ ) {
+ offset_array[i] = 0.0;
+ window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) );
+ }
+
+ jack_buffer_size = jack_get_buffer_size( client );
+ // Setup target delay and max_diff for the normal user, who does not play with them...
+ if( !target_delay )
+ target_delay = (num_periods*period_size / 2) + jack_buffer_size/2;
+
+ if( !max_diff )
+ max_diff = num_periods*period_size - target_delay ;
+
+ if( max_diff > 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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#include <alloca.h>
+#include <math.h>
+
+#include <jack/jack.h>
+#include <jack/jslist.h>
+#include <memops.h>
+
+#include "alsa/asoundlib.h"
+
+#include <samplerate.h>
+
+// 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<NUMFORMATS; i++ ) {
+ /* set the sample format */
+ err = snd_pcm_hw_params_set_format(handle, params, formats[i].format_id);
+ if (err == 0) {
+ format = i;
+ return 0;
+ }
+ }
+
+ return err;
+}
+
+static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access, int rate, int channels, int period, int nperiods ) {
+ int err, dir=0;
+ unsigned int buffer_time;
+ unsigned int period_time;
+ unsigned int rrate;
+ unsigned int rchannels;
+
+ /* choose all parameters */
+ err = snd_pcm_hw_params_any(handle, params);
+ if (err < 0) {
+ printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* set the interleaved read/write format */
+ err = snd_pcm_hw_params_set_access(handle, params, access);
+ if (err < 0) {
+ printf("Access type not available for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+
+ /* set the sample format */
+ err = set_hwformat(handle, params);
+ if (err < 0) {
+ printf("Sample format not available for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* set the count of channels */
+ rchannels = channels;
+ err = snd_pcm_hw_params_set_channels_near(handle, params, &rchannels);
+ if (err < 0) {
+ printf("Channels count (%i) not available for record: %s\n", channels, snd_strerror(err));
+ return err;
+ }
+ if (rchannels != channels) {
+ printf("WARNING: chennel count does not match (requested %d got %d)\n", channels, rchannels);
+ num_channels = rchannels;
+ }
+ /* set the stream rate */
+ rrate = rate;
+ err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, 0);
+ if (err < 0) {
+ printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
+ return err;
+ }
+ if (rrate != rate) {
+ printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, rrate);
+ return -EINVAL;
+ }
+ /* set the buffer time */
+
+ buffer_time = 1000000*period*nperiods/rate;
+ err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir);
+ if (err < 0) {
+ printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_hw_params_get_buffer_size( params, &real_buffer_size );
+ if (err < 0) {
+ printf("Unable to get buffer size back: %s\n", snd_strerror(err));
+ return err;
+ }
+ if( real_buffer_size != nperiods * period ) {
+ printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size );
+ }
+ /* set the period time */
+ period_time = 1000000*period/rate;
+ err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir);
+ if (err < 0) {
+ printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_hw_params_get_period_size(params, &real_period_size, NULL );
+ if (err < 0) {
+ printf("Unable to get period size back: %s\n", snd_strerror(err));
+ return err;
+ }
+ if( real_period_size != period ) {
+ printf( "WARNING: period size does not match: (requested %i, got %i)\n", period, (int)real_period_size );
+ }
+ /* write the parameters to device */
+ err = snd_pcm_hw_params(handle, params);
+ if (err < 0) {
+ printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
+ return err;
+ }
+ return 0;
+}
+
+static int set_swparams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams, int period, int nperiods) {
+ int err;
+
+ /* get the current swparams */
+ err = snd_pcm_sw_params_current(handle, swparams);
+ if (err < 0) {
+ printf("Unable to determine current swparams for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* start the transfer when the buffer is full */
+ err = snd_pcm_sw_params_set_start_threshold(handle, swparams, period );
+ if (err < 0) {
+ printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, -1 );
+ if (err < 0) {
+ printf("Unable to set start threshold mode for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* allow the transfer when at least period_size samples can be processed */
+ err = snd_pcm_sw_params_set_avail_min(handle, swparams, 1 );
+ if (err < 0) {
+ printf("Unable to set avail min for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* align all transfers to 1 sample */
+ err = snd_pcm_sw_params_set_xfer_align(handle, swparams, 1);
+ if (err < 0) {
+ printf("Unable to set transfer align for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ /* write the parameters to the playback device */
+ err = snd_pcm_sw_params(handle, swparams);
+ if (err < 0) {
+ printf("Unable to set sw params for capture: %s\n", snd_strerror(err));
+ return err;
+ }
+ return 0;
+}
+
+// ok... i only need this function to communicate with the alsa bloat api...
+
+static snd_pcm_t *open_audiofd( char *device_name, int capture, int rate, int channels, int period, int nperiods ) {
+ int err;
+ snd_pcm_t *handle;
+ snd_pcm_hw_params_t *hwparams;
+ snd_pcm_sw_params_t *swparams;
+
+ snd_pcm_hw_params_alloca(&hwparams);
+ snd_pcm_sw_params_alloca(&swparams);
+
+ if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) {
+ printf("Capture open error: %s\n", snd_strerror(err));
+ return NULL;
+ }
+
+ if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) {
+ printf("Setting of hwparams failed: %s\n", snd_strerror(err));
+ return NULL;
+ }
+ if ((err = set_swparams(handle, swparams, period, nperiods)) < 0) {
+ printf("Setting of swparams failed: %s\n", snd_strerror(err));
+ return NULL;
+ }
+
+ //snd_pcm_start( handle );
+ //snd_pcm_wait( handle, 200 );
+ int num_null_samples = nperiods * period * channels;
+ char *tmp = alloca( num_null_samples * formats[format].sample_size );
+ memset( tmp, 0, num_null_samples * formats[format].sample_size );
+ snd_pcm_writei( handle, tmp, num_null_samples );
+
+
+ return handle;
+}
+
+double hann( double x )
+{
+ return 0.5 * (1.0 - cos( 2*M_PI * x ) );
+}
+
+/**
+ * The process callback for this JACK application.
+ * It is called by JACK at the appropriate times.
+ */
+int process (jack_nframes_t nframes, void *arg) {
+
+ char *outbuf;
+ float *resampbuf;
+ int rlen;
+ int err;
+ snd_pcm_sframes_t delay = target_delay;
+ int i;
+
+ delay = (num_periods*period_size)-snd_pcm_avail( alsa_handle ) ;
+
+ delay -= jack_frames_since_cycle_start( client );
+ delay += jack_get_buffer_size( client ) / 2;
+ // Do it the hard way.
+ // this is for compensating xruns etc...
+
+ if( delay > (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<smooth_size; i++ )
+ offset_array[i] = 0.0;
+ }
+ if( delay < (target_delay-max_diff) ) {
+ char *tmp = alloca( (target_delay-delay) * formats[format].sample_size * num_channels );
+ memset( tmp, 0, formats[format].sample_size * num_channels * (target_delay-delay) );
+ snd_pcm_writei( alsa_handle, tmp, target_delay-delay );
+
+ output_new_delay = (int) delay;
+
+ delay = target_delay;
+
+ // Set the resample_rate... we need to adjust the offset integral, to do this.
+ 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<smooth_size; i++ )
+ offset_array[i] = 0.0;
+ }
+ /* ok... now we should have target_delay +- max_diff on the alsa side.
+ *
+ * calculate the number of frames, we want to get.
+ */
+
+ double offset = delay - target_delay;
+
+ // Save offset.
+ offset_array[(offset_differential_index++)% smooth_size ] = offset;
+
+ // Build the mean of the windowed offset array
+ // basically fir lowpassing.
+ double smooth_offset = 0.0;
+ for( i=0; i<smooth_size; i++ )
+ smooth_offset +=
+ offset_array[ (i + offset_differential_index-1) % smooth_size] * window_array[i];
+ smooth_offset /= (double) smooth_size;
+
+ // this is the integral of the smoothed_offset
+ offset_integral += smooth_offset;
+
+ // Clamp offset.
+ // the smooth offset still contains unwanted noise
+ // which would go straigth onto the resample coeff.
+ // it only used in the P component and the I component is used for the fine tuning anyways.
+ if( fabs( smooth_offset ) < pclamp )
+ smooth_offset = 0.0;
+
+ // ok. now this is the PI controller.
+ // u(t) = K * ( e(t) + 1/T \int e(t') dt' )
+ // K = 1/catch_factor and T = catch_factor2
+ double current_resample_factor = static_resample_factor - smooth_offset / (double) catch_factor - offset_integral / (double) catch_factor / (double)catch_factor2;
+
+ // now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt.
+ current_resample_factor = floor( (current_resample_factor - resample_mean) * controlquant + 0.5 ) / controlquant + resample_mean;
+
+ // Output "instrumentatio" gonna change that to real instrumentation in a few.
+ output_resampling_factor = (float) current_resample_factor;
+ output_diff = (float) smooth_offset;
+ output_integral = (float) offset_integral;
+ output_offset = (float) offset;
+
+ // Clamp a bit.
+ if( current_resample_factor < 0.25 ) current_resample_factor = 0.25;
+ if( current_resample_factor > 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 <jack name> - client name\n"
+ " -d <alsa_device> \n"
+ " -c <channels> \n"
+ " -p <period_size> \n"
+ " -n <num_period> \n"
+ " -r <sample_rate> \n"
+ " -q <sample_rate quality [0..4]\n"
+ " -m <max_diff> \n"
+ " -t <target_delay> \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<smooth_size; i++ ) {
+ offset_array[i] = 0.0;
+ window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) );
+ }
+
+ jack_buffer_size = jack_get_buffer_size( client );
+ // Setup target delay and max_diff for the normal user, who does not play with them...
+ if( !target_delay )
+ target_delay = (num_periods*period_size / 2) - jack_buffer_size/2;
+
+ if( !max_diff )
+ max_diff = target_delay;
+
+ if( max_diff > 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 <bufsize>\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 <marco@marcochapeau.org>
+Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
+Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
+
+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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <malloc.h>
+#else
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#endif
+
+/* These two required by FreeBSD. */
+#include <sys/types.h>
+
+
+#include <jack/jack.h>
+
+//#include <net_driver.h>
+#include <netjack_packet.h>
+#if HAVE_SAMPLERATE
+#include <samplerate.h>
+#endif
+
+#if HAVE_CELT
+#include <celt/celt.h>
+#endif
+
+#include <math.h>
+
+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<redundancy; r++ )
+ netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
+ }
+ else if (cont_miss > 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<redundancy; r++ )
+ netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
+ }
+ else if (cont_miss > 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 <slave host> - Host name of the slave JACK\n"
+ " -o <num channels> - Number of audio playback channels\n"
+ " -i <num channels> - Number of audio capture channels\n"
+ " -O <num channels> - Number of midi playback channels\n"
+ " -I <num channels> - Number of midi capture channels\n"
+ " -n <periods> - Network latency in JACK periods\n"
+ " -p <port> - UDP port that the slave is listening on\n"
+ " -r <reply port> - UDP port that we are listening on\n"
+ " -B <bind port> - reply port, for use in NAT environments\n"
+ " -b <bitdepth> - Set transport to use 16bit or 8bit\n"
+ " -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n"
+ " -m <mtu> - Assume this mtu for the link\n"
+ " -R <N> - Redundancy: send out packets N times.\n"
+ " -e - skip host-to-network endianness conversion\n"
+ " -N <jack name> - Reports a different name to jack\n"
+ " -s <server name> - 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 <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <jack/jack.h>
+#include <jack/transport.h>
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <time.h>
+
+#include <jack/jack.h>
+
+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 <name> Connect to the jack server named <name>\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 c8310d41..152c737d 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',
@@ -32,9 +34,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'):
@@ -49,6 +58,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']
@@ -80,8 +91,7 @@ def build(bld):
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'
@@ -96,7 +106,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'
@@ -112,6 +122,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/JackMachServerChannel.cpp b/macosx/JackMachServerChannel.cpp
index 5b646c56..19295f79 100644
--- a/macosx/JackMachServerChannel.cpp
+++ b/macosx/JackMachServerChannel.cpp
@@ -143,10 +143,6 @@ boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach
channel->ClientKill(Request->msgh_local_port);
} else {
JackRPCEngine_server(Request, Reply);
- // Issued by JackEngine::ReleaseRefnum when temporary mode is used
- if (JackServerGlobals::fKilled) {
- kill(JackTools::GetPID(), SIGINT);
- }
}
return true;
}
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 fa836fb4..9692bdb9 100644
--- a/macosx/JackMachThread.cpp
+++ b/macosx/JackMachThread.cpp
@@ -160,9 +160,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;
}
@@ -172,7 +174,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)
@@ -181,19 +190,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(thread, &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 e8105803..f7c038c0 100644
--- a/macosx/JackMachThread.h
+++ b/macosx/JackMachThread.h
@@ -105,9 +105,15 @@ 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(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);
diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj
index 4d5d42c8..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 */,
@@ -89,6 +92,7 @@
4B363F250DEB0ABE001F72D9 /* PBXTargetDependency */,
4B363F530DEB0CFE001F72D9 /* PBXTargetDependency */,
4B363F780DEB0D85001F72D9 /* PBXTargetDependency */,
+ 4B32258B10A31A9000838A8E /* PBXTargetDependency */,
);
name = "All Universal 32 bits";
productName = All;
@@ -106,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 */; };
@@ -484,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 */; };
@@ -495,15 +523,126 @@
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 */; };
4BA692D70CBE4CC600EAD520 /* ipunload.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA692D60CBE4CC600EAD520 /* ipunload.c */; };
- 4BA7BE0F0DC232A400AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; };
- 4BA7BE1A0DC2347500AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; };
- 4BA7BE200DC234FB00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; };
- 4BA7BE240DC2350D00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; };
- 4BA7BE270DC2352A00AA3457 /* Jackdmp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */; };
+ 4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; };
+ 4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; };
+ 4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; };
+ 4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; };
+ 4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */; };
4BA7FECA0D8E76650017FF73 /* control.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BA7FEC80D8E76650017FF73 /* control.c */; };
4BAB95B80B9E20B800A0C723 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; };
4BAB95B90B9E20B800A0C723 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; };
@@ -622,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 */; };
@@ -676,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 */;
@@ -1179,7 +1353,7 @@
4B0A28E60D52073D002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; };
4B0A28EC0D520852002EFF74 /* tw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tw.c; path = "../example-clients/tw.c"; sourceTree = SOURCE_ROOT; };
4B0A292D0D52108E002EFF74 /* jack_thread_wait */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_thread_wait; sourceTree = BUILT_PRODUCTS_DIR; };
- 4B19B3000E23620F00DD4A82 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B19B3000E23620F00DD4A82 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; };
4B19B3060E2362E700DD4A82 /* JackAudioAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapter.cpp; path = ../common/JackAudioAdapter.cpp; sourceTree = SOURCE_ROOT; };
4B19B3070E2362E700DD4A82 /* JackAudioAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapter.h; path = ../common/JackAudioAdapter.h; sourceTree = SOURCE_ROOT; };
4B19B3080E2362E700DD4A82 /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; };
@@ -1189,9 +1363,20 @@
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 /* Jackdmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackdmp.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4B35C5140D4731D1000DE7AE /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
4B35C5200D4731D1000DE7AE /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; };
4B35C52C0D4731D1000DE7AE /* jack_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_metro; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1215,29 +1400,29 @@
4B35C6290D4731D2000DE7AE /* jack_portaudio.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_portaudio.so; sourceTree = BUILT_PRODUCTS_DIR; };
4B35C6340D4731D2000DE7AE /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; };
4B35C63E0D4731D3000DE7AE /* inprocess.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = inprocess.so; sourceTree = BUILT_PRODUCTS_DIR; };
- 4B363DD80DEB02F6001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B363DD80DEB02F6001F72D9 /* jack_alias */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_alias; sourceTree = BUILT_PRODUCTS_DIR; };
4B363DDE0DEB034E001F72D9 /* alias.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = alias.c; path = "../example-clients/alias.c"; sourceTree = SOURCE_ROOT; };
- 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B363E1A0DEB03C5001F72D9 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; };
4B363E200DEB0401001F72D9 /* evmon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = evmon.c; path = "../example-clients/evmon.c"; sourceTree = SOURCE_ROOT; };
- 4B363E4E0DEB0775001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B363E4E0DEB0775001F72D9 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; };
4B363E710DEB0808001F72D9 /* bufsize.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bufsize.c; path = "../example-clients/bufsize.c"; sourceTree = SOURCE_ROOT; };
- 4B363EE90DEB091C001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B363EE90DEB091C001F72D9 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; };
4B363EED0DEB094B001F72D9 /* capture_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = capture_client.c; path = "../example-clients/capture_client.c"; sourceTree = SOURCE_ROOT; };
- 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; };
4B363F220DEB0AB0001F72D9 /* monitor_client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = monitor_client.c; path = "../example-clients/monitor_client.c"; sourceTree = SOURCE_ROOT; };
4B363F350DEB0BD1001F72D9 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; };
4B363F3D0DEB0C31001F72D9 /* showtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = showtime.c; path = "../example-clients/showtime.c"; sourceTree = SOURCE_ROOT; };
- 4B363F720DEB0D4E001F72D9 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; };
4B363F750DEB0D7D001F72D9 /* impulse_grabber.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = impulse_grabber.c; path = "../example-clients/impulse_grabber.c"; sourceTree = SOURCE_ROOT; };
4B37C20306DF1FBE0016E567 /* CALatencyLog.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CALatencyLog.cpp; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.cpp; sourceTree = "<absolute>"; };
4B37C20406DF1FBE0016E567 /* CALatencyLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CALatencyLog.h; path = /Developer/Examples/CoreAudio/PublicUtility/CALatencyLog.h; sourceTree = "<absolute>"; };
4B37C20906DF1FE20016E567 /* latency.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = latency.c; path = /Developer/Examples/CoreAudio/PublicUtility/latency.c; sourceTree = "<absolute>"; };
4B3F49070AD8503300491C6E /* cpu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cpu.c; path = ../tests/cpu.c; sourceTree = SOURCE_ROOT; };
4B4259E5076B635E00C1ECE1 /* JackMacEngineRPC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMacEngineRPC.cpp; sourceTree = SOURCE_ROOT; };
- 4B43A8BA10145F6F00E52943 /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B43A8BA10145F6F00E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; };
4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackLoopbackDriver.cpp; path = ../common/JackLoopbackDriver.cpp; sourceTree = SOURCE_ROOT; };
4B43A8C91014605000E52943 /* JackLoopbackDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLoopbackDriver.h; path = ../common/JackLoopbackDriver.h; sourceTree = SOURCE_ROOT; };
- 4B43A8E71014615800E52943 /* jack_dummy.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_dummy.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B43A8E71014615800E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; };
4B464301076CAC7700E5077C /* Jack-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = SOURCE_ROOT; };
4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackRestartThreadedDriver.h; path = ../common/JackRestartThreadedDriver.h; sourceTree = SOURCE_ROOT; };
4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackRestartThreadedDriver.cpp; path = ../common/JackRestartThreadedDriver.cpp; sourceTree = SOURCE_ROOT; };
@@ -1250,7 +1435,7 @@
4B5A1BBD0CD1CC110005BF74 /* midiseq.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midiseq.c; path = "../example-clients/midiseq.c"; sourceTree = SOURCE_ROOT; };
4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midisine; sourceTree = BUILT_PRODUCTS_DIR; };
4B5A1BDC0CD1CD420005BF74 /* midisine.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = midisine.c; path = "../example-clients/midisine.c"; sourceTree = SOURCE_ROOT; };
- 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netadapter.so; sourceTree = BUILT_PRODUCTS_DIR; };
4B5E08DF0E5B676C00BEE4E0 /* JackNetAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetAdapter.cpp; path = ../common/JackNetAdapter.cpp; sourceTree = SOURCE_ROOT; };
4B5E08E00E5B676C00BEE4E0 /* JackNetAdapter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackNetAdapter.h; path = ../common/JackNetAdapter.h; sourceTree = SOURCE_ROOT; };
4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLockedEngine.h; path = ../common/JackLockedEngine.h; sourceTree = SOURCE_ROOT; };
@@ -1295,19 +1480,22 @@
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 = "<absolute>"; };
+ 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 = "<group>"; };
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; };
4BA692B20CBE4C2D00EAD520 /* ipload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipload.c; path = "../example-clients/ipload.c"; sourceTree = SOURCE_ROOT; };
4BA692D40CBE4C9000EAD520 /* jack_unload */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_unload; sourceTree = BUILT_PRODUCTS_DIR; };
4BA692D60CBE4CC600EAD520 /* ipunload.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ipunload.c; path = "../example-clients/ipunload.c"; sourceTree = SOURCE_ROOT; };
- 4BA7FEC30D8E76270017FF73 /* jack_lsp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_lsp; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BA7FEC30D8E76270017FF73 /* jack_server_control */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_server_control; sourceTree = BUILT_PRODUCTS_DIR; };
4BA7FEC80D8E76650017FF73 /* control.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = control.c; path = "../example-clients/control.c"; sourceTree = SOURCE_ROOT; };
4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackPortType.cpp; path = ../common/JackPortType.cpp; sourceTree = SOURCE_ROOT; };
4BAB95B70B9E20B800A0C723 /* JackPortType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackPortType.h; path = ../common/JackPortType.h; sourceTree = SOURCE_ROOT; };
@@ -1352,8 +1540,8 @@
4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_coremidi.so; sourceTree = BUILT_PRODUCTS_DIR; };
4BDCDBC51001FCC000B15929 /* jack_net.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_net.so; sourceTree = BUILT_PRODUCTS_DIR; };
4BDCDBE81001FD2D00B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; };
- 4BDCDBFF1001FD7300B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; };
- 4BDCDC251001FDE300B15929 /* netmanager.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netmanager.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BDCDBFF1001FD7300B15929 /* audioadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = audioadapter.so; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BDCDC251001FDE300B15929 /* netadapter.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = netadapter.so; sourceTree = BUILT_PRODUCTS_DIR; };
4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackTools.cpp; path = ../common/JackTools.cpp; sourceTree = SOURCE_ROOT; };
4BE4CC000CDA153400CCF5BB /* JackTools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTools.h; path = ../common/JackTools.h; sourceTree = SOURCE_ROOT; };
4BE5FECB0E725C090020B576 /* JackCoreAudioDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackCoreAudioDriver.cpp; path = coreaudio/JackCoreAudioDriver.cpp; sourceTree = SOURCE_ROOT; };
@@ -1435,14 +1623,14 @@
4BF8D2470834F20600C94B91 /* testSem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSem.cpp; path = ../tests/testSem.cpp; sourceTree = SOURCE_ROOT; };
4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFrameTimer.cpp; path = ../common/JackFrameTimer.cpp; sourceTree = SOURCE_ROOT; };
4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFrameTimer.h; path = ../common/JackFrameTimer.h; sourceTree = SOURCE_ROOT; };
- 4BFA5E980DEC4D9C00FA4CDB /* testSem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testSem; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BFA5E980DEC4D9C00FA4CDB /* testMutex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testMutex; sourceTree = BUILT_PRODUCTS_DIR; };
4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testMutex.cpp; path = ../tests/testMutex.cpp; sourceTree = SOURCE_ROOT; };
- 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
- 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
- 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
- 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
- 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
- 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midiseq; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_evmon; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_bufsize; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_rec; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_monitor_client; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_showtime; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_impulse_grabber; sourceTree = BUILT_PRODUCTS_DIR; };
4BFA99A20AAAF3B0009E916C /* jdelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jdelay; sourceTree = BUILT_PRODUCTS_DIR; };
4BFA99A90AAAF40C009E916C /* jdelay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = jdelay.cpp; path = ../tests/jdelay.cpp; sourceTree = SOURCE_ROOT; };
4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachServerNotifyChannel.cpp; sourceTree = "<group>"; };
@@ -1490,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;
@@ -1580,7 +1796,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 4BA7BE0F0DC232A400AA3457 /* Jackdmp.framework in Frameworks */,
+ 4BA7BE0F0DC232A400AA3457 /* Jackservermp.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1588,7 +1804,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 4BA7BE1A0DC2347500AA3457 /* Jackdmp.framework in Frameworks */,
+ 4BA7BE1A0DC2347500AA3457 /* Jackservermp.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1631,7 +1847,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 4BA7BE200DC234FB00AA3457 /* Jackdmp.framework in Frameworks */,
+ 4BA7BE200DC234FB00AA3457 /* Jackservermp.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1639,7 +1855,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 4BA7BE240DC2350D00AA3457 /* Jackdmp.framework in Frameworks */,
+ 4BA7BE240DC2350D00AA3457 /* Jackservermp.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1647,7 +1863,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 4BA7BE270DC2352A00AA3457 /* Jackdmp.framework in Frameworks */,
+ 4BA7BE270DC2352A00AA3457 /* Jackservermp.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1891,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;
@@ -2064,6 +2288,7 @@
0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */,
1AB674ADFE9D54B511CA2CBB /* Products */,
4B464301076CAC7700E5077C /* Jack-Info.plist */,
+ 4BA339AD10B2E36800190E3B /* Jack-Info.plist */,
);
name = JackServer;
sourceTree = "<group>";
@@ -2121,7 +2346,7 @@
4B5A1BDA0CD1CCE10005BF74 /* jack_midisine */,
4B35C4250D4731D1000DE7AE /* jackdmp */,
4B35C4830D4731D1000DE7AE /* Jackmp.framework */,
- 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */,
+ 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */,
4B35C5140D4731D1000DE7AE /* jack_midiseq */,
4B35C5200D4731D1000DE7AE /* jack_midisine */,
4B35C52C0D4731D1000DE7AE /* jack_metro */,
@@ -2148,34 +2373,39 @@
4B0A28E60D52073D002EFF74 /* jack_thread_wait */,
4B0A292D0D52108E002EFF74 /* jack_thread_wait */,
4B57F5950D72C27900B4E719 /* jack_thread_wait */,
- 4BA7FEC30D8E76270017FF73 /* jack_lsp */,
+ 4BA7FEC30D8E76270017FF73 /* jack_server_control */,
BA222ACF0DC88132001A17F4 /* jack_net.so */,
BA222AE90DC882DB001A17F4 /* netmanager.so */,
- 4BA7FEC30D8E76270017FF73 /* jack_lsp */,
- 4B363DD80DEB02F6001F72D9 /* jack_midiseq */,
- 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */,
- 4B363E4E0DEB0775001F72D9 /* jack_midiseq */,
- 4B363EE90DEB091C001F72D9 /* jack_midiseq */,
- 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */,
+ 4BA7FEC30D8E76270017FF73 /* jack_server_control */,
+ 4B363DD80DEB02F6001F72D9 /* jack_alias */,
+ 4B363E1A0DEB03C5001F72D9 /* jack_evmon */,
+ 4B363E4E0DEB0775001F72D9 /* jack_bufsize */,
+ 4B363EE90DEB091C001F72D9 /* jack_rec */,
+ 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */,
4B363F350DEB0BD1001F72D9 /* jack_showtime */,
- 4B363F720DEB0D4E001F72D9 /* jack_midiseq */,
- 4BFA5E980DEC4D9C00FA4CDB /* testSem */,
- 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */,
- 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */,
- 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */,
- 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */,
- 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */,
- 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */,
- 4B19B3000E23620F00DD4A82 /* netmanager.so */,
- 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */,
+ 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */,
+ 4BFA5E980DEC4D9C00FA4CDB /* testMutex */,
+ 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */,
+ 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */,
+ 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */,
+ 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */,
+ 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */,
+ 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */,
+ 4B19B3000E23620F00DD4A82 /* audioadapter.so */,
+ 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */,
4BF3390C0F8B864B0080FB5B /* jack_coremidi.so */,
4BDCDB9D1001FB9C00B15929 /* jack_coremidi.so */,
4BDCDBC51001FCC000B15929 /* jack_net.so */,
4BDCDBE81001FD2D00B15929 /* netmanager.so */,
- 4BDCDBFF1001FD7300B15929 /* netmanager.so */,
- 4BDCDC251001FDE300B15929 /* netmanager.so */,
- 4B43A8BA10145F6F00E52943 /* jack_dummy.so */,
- 4B43A8E71014615800E52943 /* jack_dummy.so */,
+ 4BDCDBFF1001FD7300B15929 /* audioadapter.so */,
+ 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 = "<group>";
@@ -2369,6 +2599,7 @@
4B6C73780CC60A6D001AFFD4 /* jack */ = {
isa = PBXGroup;
children = (
+ 4B94334910A5E666002A187F /* systemdeps.h */,
4B9A26000DBF8584006E9FBC /* jslist.h */,
4B95BCAD0D913073000F7695 /* control.h */,
4B6B9EF50CD0958B0051EE5A /* midiport.h */,
@@ -2670,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 */,
@@ -2724,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;
@@ -3159,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;
};
@@ -3228,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;
};
@@ -3340,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;
@@ -3577,9 +3921,81 @@
);
name = "audioadapter Universal";
productName = jack_coreaudio;
- productReference = 4B19B3000E23620F00DD4A82 /* netmanager.so */;
+ 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" */;
@@ -3634,7 +4050,7 @@
);
name = "Jackservermp.framework 64 bits";
productName = Jack;
- productReference = 4B35C4FC0D4731D1000DE7AE /* Jackdmp.framework */;
+ productReference = 4B35C4FC0D4731D1000DE7AE /* Jackservermp.framework */;
productType = "com.apple.product-type.framework";
};
4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */ = {
@@ -4083,7 +4499,7 @@
name = "jack_alias Universal";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4B363DD80DEB02F6001F72D9 /* jack_midiseq */;
+ productReference = 4B363DD80DEB02F6001F72D9 /* jack_alias */;
productType = "com.apple.product-type.tool";
};
4B363E100DEB03C5001F72D9 /* jack_evmon Universal */ = {
@@ -4102,7 +4518,7 @@
name = "jack_evmon Universal";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4B363E1A0DEB03C5001F72D9 /* jack_midiseq */;
+ productReference = 4B363E1A0DEB03C5001F72D9 /* jack_evmon */;
productType = "com.apple.product-type.tool";
};
4B363E440DEB0775001F72D9 /* jack_bufsize Universal */ = {
@@ -4121,7 +4537,7 @@
name = "jack_bufsize Universal";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4B363E4E0DEB0775001F72D9 /* jack_midiseq */;
+ productReference = 4B363E4E0DEB0775001F72D9 /* jack_bufsize */;
productType = "com.apple.product-type.tool";
};
4B363EDF0DEB091C001F72D9 /* jack_rec Universal */ = {
@@ -4140,7 +4556,7 @@
name = "jack_rec Universal";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4B363EE90DEB091C001F72D9 /* jack_midiseq */;
+ productReference = 4B363EE90DEB091C001F72D9 /* jack_rec */;
productType = "com.apple.product-type.tool";
};
4B363F140DEB0A6A001F72D9 /* jack_monitor_client Universal */ = {
@@ -4159,7 +4575,7 @@
name = "jack_monitor_client Universal";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_midiseq */;
+ productReference = 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */;
productType = "com.apple.product-type.tool";
};
4B363F2B0DEB0BD1001F72D9 /* jack_showtime Universal */ = {
@@ -4197,7 +4613,7 @@
name = "jack_impulse_grabber Universal";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4B363F720DEB0D4E001F72D9 /* jack_midiseq */;
+ productReference = 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */;
productType = "com.apple.product-type.tool";
};
4B43A8B010145F6F00E52943 /* jack_loopback Universal */ = {
@@ -4214,7 +4630,7 @@
);
name = "jack_loopback Universal";
productName = jack_coreaudio;
- productReference = 4B43A8BA10145F6F00E52943 /* jack_dummy.so */;
+ productReference = 4B43A8BA10145F6F00E52943 /* jack_loopback.so */;
productType = "com.apple.product-type.library.dynamic";
};
4B43A8DD1014615800E52943 /* jack_loopback 64 bits */ = {
@@ -4231,7 +4647,7 @@
);
name = "jack_loopback 64 bits";
productName = jack_coreaudio;
- productReference = 4B43A8E71014615800E52943 /* jack_dummy.so */;
+ productReference = 4B43A8E71014615800E52943 /* jack_loopback.so */;
productType = "com.apple.product-type.library.dynamic";
};
4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */ = {
@@ -4286,7 +4702,7 @@
);
name = "netadapter Universal";
productName = jack_coreaudio;
- productReference = 4B5E08D50E5B66EE00BEE4E0 /* netmanager.so */;
+ productReference = 4B5E08D50E5B66EE00BEE4E0 /* netadapter.so */;
productType = "com.apple.product-type.library.dynamic";
};
4B699BA7097D421600A18468 /* jackdmp framework Universal */ = {
@@ -4626,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" */;
@@ -4680,7 +5115,7 @@
name = "jack_server_control Universal";
productInstallPath = /usr/local/bin;
productName = jack_lsp;
- productReference = 4BA7FEC30D8E76270017FF73 /* jack_lsp */;
+ productReference = 4BA7FEC30D8E76270017FF73 /* jack_server_control */;
productType = "com.apple.product-type.tool";
};
4BD623ED0CBCF0F000DE782F /* inprocess Universal */ = {
@@ -4765,7 +5200,7 @@
);
name = "audioadapter 64 bits";
productName = jack_coreaudio;
- productReference = 4BDCDBFF1001FD7300B15929 /* netmanager.so */;
+ productReference = 4BDCDBFF1001FD7300B15929 /* audioadapter.so */;
productType = "com.apple.product-type.library.dynamic";
};
4BDCDC0F1001FDE300B15929 /* netadapter 64 bits */ = {
@@ -4782,7 +5217,7 @@
);
name = "netadapter 64 bits";
productName = jack_coreaudio;
- productReference = 4BDCDC251001FDE300B15929 /* netmanager.so */;
+ productReference = 4BDCDC251001FDE300B15929 /* netadapter.so */;
productType = "com.apple.product-type.library.dynamic";
};
4BE6C6910A3E096F005A203A /* jack_test Universal */ = {
@@ -4856,7 +5291,7 @@
name = "testMutex Universal";
productInstallPath = /usr/local/bin;
productName = testSem;
- productReference = 4BFA5E980DEC4D9C00FA4CDB /* testSem */;
+ productReference = 4BFA5E980DEC4D9C00FA4CDB /* testMutex */;
productType = "com.apple.product-type.tool";
};
4BFA82820DF6A9E40087B4E1 /* jack_evmon 64 bits */ = {
@@ -4875,7 +5310,7 @@
name = "jack_evmon 64 bits";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_midiseq */;
+ productReference = 4BFA828C0DF6A9E40087B4E1 /* jack_evmon */;
productType = "com.apple.product-type.tool";
};
4BFA82950DF6A9E40087B4E1 /* jack_bufsize 64 bits */ = {
@@ -4894,7 +5329,7 @@
name = "jack_bufsize 64 bits";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_midiseq */;
+ productReference = 4BFA829F0DF6A9E40087B4E1 /* jack_bufsize */;
productType = "com.apple.product-type.tool";
};
4BFA82A10DF6A9E40087B4E1 /* jack_rec 64 bits */ = {
@@ -4913,7 +5348,7 @@
name = "jack_rec 64 bits";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_midiseq */;
+ productReference = 4BFA82AB0DF6A9E40087B4E1 /* jack_rec */;
productType = "com.apple.product-type.tool";
};
4BFA82AD0DF6A9E40087B4E1 /* jack_monitor_client 64 bits */ = {
@@ -4932,7 +5367,7 @@
name = "jack_monitor_client 64 bits";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_midiseq */;
+ productReference = 4BFA82B70DF6A9E40087B4E1 /* jack_monitor_client */;
productType = "com.apple.product-type.tool";
};
4BFA82B90DF6A9E40087B4E1 /* jack_showtime 64 bits */ = {
@@ -4951,7 +5386,7 @@
name = "jack_showtime 64 bits";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_midiseq */;
+ productReference = 4BFA82C30DF6A9E40087B4E1 /* jack_showtime */;
productType = "com.apple.product-type.tool";
};
4BFA82C50DF6A9E40087B4E1 /* jack_impulse_grabber 64 bits */ = {
@@ -4970,7 +5405,7 @@
name = "jack_impulse_grabber 64 bits";
productInstallPath = /usr/local/bin;
productName = jack_metro;
- productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_midiseq */;
+ productReference = 4BFA82CF0DF6A9E40087B4E1 /* jack_impulse_grabber */;
productType = "com.apple.product-type.tool";
};
4BFA99980AAAF3B0009E916C /* jdelay Universal */ = {
@@ -5003,6 +5438,7 @@
buildRules = (
);
dependencies = (
+ 4B3224E710A3157900838A8E /* PBXTargetDependency */,
);
name = "jack_net Universal";
productName = jack_coreaudio;
@@ -5069,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 */,
@@ -5078,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 */,
@@ -5085,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 */,
@@ -5108,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 */,
@@ -5117,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 */,
@@ -5154,6 +5595,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 4BA3397010B2E36800190E3B /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXRezBuildPhase section */
@@ -5171,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;
@@ -5493,6 +5955,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 4BA339A510B2E36800190E3B /* Rez */ = {
+ isa = PBXRezBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
4BA692AB0CBE4BC700EAD520 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
@@ -5616,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;
@@ -6238,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;
@@ -6460,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 */;
@@ -6876,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;
@@ -7110,6 +7698,475 @@
};
name = Default;
};
+ 4B3224E210A3156800838A8E /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = (
+ 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;
+ };
+ 4B3224E310A3156800838A8E /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = (
+ 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,
+ 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 = {
@@ -7666,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;
@@ -7765,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;
@@ -7864,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;
@@ -7963,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;
@@ -8056,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;
@@ -8149,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;
@@ -8239,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;
@@ -8335,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;
@@ -8428,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;
@@ -8745,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;
@@ -8838,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;
@@ -8930,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;
@@ -9022,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;
@@ -9114,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;
@@ -9552,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;
@@ -9855,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;
@@ -10000,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;
@@ -11027,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;
@@ -11904,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;
@@ -11963,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;
@@ -13818,6 +14801,203 @@
};
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 = (
+ "-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 = (
+ "-framework",
+ Carbon,
+ "-framework",
+ CoreAudio,
+ );
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = Jackservermp;
+ REZ_EXECUTABLE = NO;
+ SDKROOT = "";
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = "-Wmost";
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ 4BA339AB10B2E36800190E3B /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = (
+ ppc64,
+ ppc,
+ i386,
+ x86_64,
+ );
+ 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_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 = (
+ "-framework",
+ Carbon,
+ "-framework",
+ AudioToolBox,
+ "-framework",
+ CoreAudio,
+ );
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = Jackdmp;
+ REZ_EXECUTABLE = NO;
+ SDKROOT = "";
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = "-Wmost";
+ };
+ name = Default;
+ };
4BA692AD0CBE4BC700EAD520 /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -14230,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;
@@ -14378,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;
@@ -14519,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;
@@ -14665,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;
@@ -14809,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;
@@ -15399,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;
@@ -15498,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;
@@ -15595,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;
@@ -15702,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;
@@ -15799,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;
@@ -15820,7 +16974,7 @@
CoreFoundation,
);
OTHER_REZFLAGS = "";
- PRODUCT_NAME = jack_midiseq;
+ PRODUCT_NAME = jack_showtime;
REZ_EXECUTABLE = YES;
SDKROOT = "";
SECTORDER_FLAGS = "";
@@ -15896,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;
@@ -16402,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 = (
@@ -16992,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/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp
index 630366ec..cb05d622 100644
--- a/macosx/coreaudio/JackCoreAudioAdapter.cpp
+++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp
@@ -301,6 +301,7 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra
char playbackName[256];
fCaptureUID[0] = 0;
fPlaybackUID[0] = 0;
+ fClockDriftCompensate = false;
// Default values
fCaptureChannels = -1;
@@ -377,6 +378,10 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra
fRingbufferCurSize = param->value.ui;
fAdaptative = false;
break;
+
+ case 's':
+ fClockDriftCompensate = true;
+ break;
}
}
@@ -721,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;
@@ -1014,65 +1015,159 @@ static CFStringRef GetDeviceName(AudioDeviceID id)
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<AudioDeviceID> 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<AudioDeviceID> 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<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice)
+{
OSStatus osErr = noErr;
UInt32 outSize;
Boolean outWritable;
- // Check devices...
- if (IsAggregateDevice(captureDeviceID) || IsAggregateDevice(playbackDeviceID)) {
- jack_error("JackCoreAudioAdapter::CreateAggregateDevice : cannot agregate devices that are already aggregate devices...");
- return -1;
- }
+ // 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...
//---------------------------------------------------------------------------
- if (SetupSampleRateAux(captureDeviceID, samplerate) < 0) {
- jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device");
+ 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;
+ }
+ }
+ }
}
- if (SetupSampleRateAux(playbackDeviceID, samplerate) < 0) {
- jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device");
+
+ 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 capture_name[256];
- char playback_name[256];
- GetDeviceNameFromID(captureDeviceID, capture_name);
- GetDeviceNameFromID(playbackDeviceID, playback_name);
- jack_info("Separated input = '%s' and output = '%s' devices, create a private aggregate device to handle them...", capture_name, playback_name);
-
+ 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");
-
+
pluginAVT.mInputData = &inBundleRef;
pluginAVT.mInputDataSize = sizeof(inBundleRef);
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);
@@ -1082,7 +1177,7 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDevice
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)
@@ -1092,96 +1187,214 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDevice(AudioDeviceID captureDevice
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<CFStringRef> 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<CFStringRef> 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)
- return osErr;
-
+ 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)
- return osErr;
-
+ 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)
- 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
//-----------------------
-
+
// 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); // 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;
}
+
bool JackCoreAudioAdapter::IsAggregateDevice(AudioDeviceID device)
{
OSStatus err = noErr;
@@ -1252,7 +1465,7 @@ 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;
@@ -1283,16 +1496,14 @@ extern "C"
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++;
@@ -1304,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++;
@@ -1323,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);
@@ -1350,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 d2f61006..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 <CoreAudio/CoreAudio.h>
#include <AudioUnit/AudioUnit.h>
+#include <vector>
+
+using namespace std;
+
namespace Jack
{
@@ -63,6 +67,7 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface
AudioUnitRenderActionFlags* fActionFags;
AudioTimeStamp* fCurrentTime;
+ bool fClockDriftCompensate;
static OSStatus Render(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
@@ -91,6 +96,7 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface
// Setup
OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice);
+ OSStatus CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice);
OSStatus DestroyAggregateDevice();
bool IsAggregateDevice(AudioDeviceID device);
diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp
index 3b2620cb..e540a164 100644
--- a/macosx/coreaudio/JackCoreAudioDriver.cpp
+++ b/macosx/coreaudio/JackCoreAudioDriver.cpp
@@ -297,7 +297,7 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
case kAudioDevicePropertyNominalSampleRate: {
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->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE
driver->CloseAUHAL();
kill(JackTools::GetPID(), SIGINT);
return kAudioHardwareUnsupportedOperationError;
@@ -387,22 +387,17 @@ 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;
}
@@ -414,7 +409,8 @@ JackCoreAudioDriver::JackCoreAudioDriver(const char* name, const char* alias, Ja
fState(false),
fHogged(false),
fIOUsage(1.f),
- fComputationGrain(-1.f)
+ fComputationGrain(-1.f),
+ fClockDriftCompensate(false)
{}
JackCoreAudioDriver::~JackCoreAudioDriver()
@@ -449,39 +445,127 @@ OSStatus JackCoreAudioDriver::DestroyAggregateDevice()
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<AudioDeviceID> 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<AudioDeviceID> 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<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice)
+{
OSStatus osErr = noErr;
UInt32 outSize;
Boolean outWritable;
- // Check devices... (TO IMPROVE)
- if (IsAggregateDevice(captureDeviceID) || IsAggregateDevice(playbackDeviceID)) {
- jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot agregate devices that are already aggregate devices...");
- return -1;
- }
-
+ // 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...
//---------------------------------------------------------------------------
- if (SetupSampleRateAux(captureDeviceID, samplerate) < 0) {
- jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of input device");
+ 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 (SetupSampleRateAux(playbackDeviceID, samplerate) < 0) {
- jack_error("JackCoreAudioDriver::CreateAggregateDevice : cannot set SR of output device");
+
+ // 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 capture_name[256];
- char playback_name[256];
- GetDeviceNameFromID(captureDeviceID, capture_name);
- GetDeviceNameFromID(playbackDeviceID, playback_name);
- jack_info("Separated input = '%s' and output = '%s' devices, create a private aggregate device to handle them...", capture_name, playback_name);
-
+ 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");
@@ -536,24 +620,73 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI
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<CFStringRef> 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<CFStringRef> 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
//-----------------------------------------------------------------------
@@ -599,7 +732,7 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI
// pause again to give the changes time to take effect
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, false);
-
+
//-----------------------
// Set the master device
//-----------------------
@@ -610,7 +743,7 @@ 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...
+ 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);
@@ -619,7 +752,50 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI
// 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
//----------
@@ -630,10 +806,18 @@ OSStatus JackCoreAudioDriver::CreateAggregateDevice(AudioDeviceID captureDeviceI
// 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;
@@ -651,7 +835,7 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
{
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");
@@ -675,10 +859,23 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
// 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 (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;
}
@@ -1095,10 +1292,6 @@ 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;
@@ -1203,7 +1396,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
jack_nframes_t playback_latency,
int async_output_latency,
int computation_grain,
- bool hogged)
+ bool hogged,
+ bool clock_drift)
{
int in_nChannels = 0;
int out_nChannels = 0;
@@ -1223,6 +1417,7 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
fIOUsage = float(async_output_latency) / 100.f;
fComputationGrain = float(computation_grain) / 100.f;
fHogged = hogged;
+ fClockDriftCompensate = clock_drift;
SInt32 major;
SInt32 minor;
@@ -1233,9 +1428,10 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
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) {
+ OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);
+ if (osErr != noErr) {
jack_error("JackCoreAudioDriver::Open kAudioHardwarePropertyRunLoop error");
+ printError(osErr);
}
}
@@ -1560,7 +1756,7 @@ 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 = 16;
+ desc->nparams = 17;
desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
i = 0;
@@ -1591,16 +1787,14 @@ extern "C"
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++;
@@ -1639,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);
@@ -1690,6 +1883,14 @@ extern "C"
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;
}
@@ -1712,6 +1913,7 @@ extern "C"
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;
@@ -1789,6 +1991,10 @@ extern "C"
case 'G':
computation_grain = param->value.ui;
break;
+
+ case 's':
+ clock_drift = true;
+ break;
}
}
@@ -1800,7 +2006,7 @@ extern "C"
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, computation_grain, hogged) == 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 f3d909d2..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 <vector>
+
+using namespace std;
+
namespace Jack
{
@@ -77,6 +81,7 @@ class JackCoreAudioDriver : public JackAudioDriver
bool fMonitor;
float fIOUsage;
float fComputationGrain;
+ bool fClockDriftCompensate;
/*
#ifdef MAC_OS_X_VERSION_10_5
@@ -117,9 +122,10 @@ 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, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice);
+ OSStatus CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice);
OSStatus DestroyAggregateDevice();
bool IsAggregateDevice(AudioDeviceID device);
@@ -178,7 +184,8 @@ class JackCoreAudioDriver : public JackAudioDriver
jack_nframes_t playback_latency,
int async_output_latency,
int computation_grain,
- bool hogged);
+ 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/JackPosixThread.cpp b/posix/JackPosixThread.cpp
index d61eb932..67d2d0c8 100644
--- a/posix/JackPosixThread.cpp
+++ b/posix/JackPosixThread.cpp
@@ -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/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp
index eb988aef..a5625219 100644
--- a/posix/JackSocketServerChannel.cpp
+++ b/posix/JackSocketServerChannel.cpp
@@ -396,12 +396,7 @@ bool JackSocketServerChannel::HandleRequest(int fd)
jack_error("Unknown request %ld", header.fType);
break;
}
-
- // Issued by JackEngine::ReleaseRefnum when temporary mode is used
- if (JackServerGlobals::fKilled) {
- kill(JackTools::GetPID(), SIGINT);
- }
-
+
return true;
}
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/tests/test.cpp b/tests/test.cpp
index 26d4eedf..e77edf49 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -220,7 +220,7 @@ void jack_shutdown(void *arg)
exit(1);
}
-void jack_info_shutdown(int code, const char* reason, void *arg)
+void jack_info_shutdown(jack_status_t code, const char* reason, void *arg)
{
printf("JACK server failure : %s\n", reason);
exit(1);
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 <windows.h>
+#include <windows.h>
+
+// 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/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp
index 03d9effc..da0da443 100644
--- a/windows/JackWinNamedPipeServerChannel.cpp
+++ b/windows/JackWinNamedPipeServerChannel.cpp
@@ -317,14 +317,7 @@ bool JackClientPipeThread::HandleRequest()
break;
}
}
-
- /* TODO
- // Issued by JackEngine::ReleaseRefnum when temporary mode is used
- if (JackServerGlobals::fKilled) {
- kill(JackTools::GetPID(), SIGINT);
- }
- */
-
+
// Unlock the global mutex
ReleaseMutex(fMutex);
return ret;
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
--- a/windows/Setup/JackRouter.dll
+++ b/windows/Setup/JackRouter.dll
Binary files 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" >
<output> .</>
- <exename> Jack_v1.9.3_setup.exe</>
+ <exename> Jack_v1.9.4_setup.exe</>
<digitsign> </>
- <appname> Jack v1.9.3</>
+ <appname> Jack v1.9.4</>
<password> </>
<addlang> </>
<icon> Default - 2</>
diff --git a/wscript b/wscript
index 6fb5c88c..a9128cca 100644
--- a/wscript
+++ b/wscript
@@ -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 + "'" )