Browse Source

Merge branch 'master' into js-dbus

tags/1.9.8
Stephane Letz 14 years ago
parent
commit
80d316ece4
90 changed files with 2358 additions and 2460 deletions
  1. +20
    -0
      ChangeLog
  2. +0
    -17
      common/JackAPI.cpp
  3. +8
    -3
      common/JackAudioAdapter.cpp
  4. +6
    -21
      common/JackAudioDriver.cpp
  5. +0
    -3
      common/JackAudioDriver.h
  6. +1
    -1
      common/JackChannel.h
  7. +2
    -0
      common/JackClient.cpp
  8. +39
    -39
      common/JackControlAPI.cpp
  9. +39
    -39
      common/JackControlAPI.h
  10. +1
    -1
      common/JackDebugClient.h
  11. +3
    -6
      common/JackDriver.cpp
  12. +17
    -19
      common/JackDriver.h
  13. +18
    -35
      common/JackDriverLoader.cpp
  14. +13
    -65
      common/JackDummyDriver.cpp
  15. +5
    -30
      common/JackDummyDriver.h
  16. +6
    -11
      common/JackEngine.cpp
  17. +4
    -4
      common/JackExternalClient.cpp
  18. +2
    -2
      common/JackExternalClient.h
  19. +3
    -3
      common/JackGlobals.h
  20. +7
    -6
      common/JackInternalClient.cpp
  21. +1
    -1
      common/JackInternalClientChannel.h
  22. +1
    -0
      common/JackLibAPI.cpp
  23. +5
    -8
      common/JackLibClient.cpp
  24. +1
    -1
      common/JackLibClient.h
  25. +1
    -1
      common/JackLibGlobals.h
  26. +14
    -7
      common/JackMidiAPI.cpp
  27. +0
    -5
      common/JackMidiDriver.cpp
  28. +0
    -2
      common/JackMidiDriver.h
  29. +109
    -86
      common/JackNetAPI.cpp
  30. +13
    -15
      common/JackNetAdapter.cpp
  31. +64
    -108
      common/JackNetDriver.cpp
  32. +10
    -9
      common/JackNetDriver.h
  33. +321
    -360
      common/JackNetInterface.cpp
  34. +71
    -63
      common/JackNetInterface.h
  35. +257
    -265
      common/JackNetManager.cpp
  36. +15
    -15
      common/JackNetManager.h
  37. +16
    -29
      common/JackNetOneDriver.cpp
  38. +12
    -12
      common/JackNetOneDriver.h
  39. +368
    -244
      common/JackNetTool.cpp
  40. +70
    -516
      common/JackNetTool.h
  41. +1
    -0
      common/JackPort.cpp
  42. +7
    -4
      common/JackRequest.h
  43. +0
    -1
      common/JackServer.cpp
  44. +9
    -12
      common/JackServerAPI.cpp
  45. +12
    -9
      common/JackShmMem.h
  46. +21
    -17
      common/JackThreadedDriver.cpp
  47. +2
    -13
      common/JackThreadedDriver.h
  48. +86
    -0
      common/JackTimedDriver.cpp
  49. +66
    -0
      common/JackTimedDriver.h
  50. +13
    -1
      common/JackTools.h
  51. +19
    -18
      common/JackWaitThreadedDriver.cpp
  52. +3
    -3
      common/JackWaitThreadedDriver.h
  53. +3
    -3
      common/driver_interface.h
  54. +0
    -1
      common/jack/jack.h
  55. +22
    -31
      common/jack/net.h
  56. +1
    -0
      common/wscript
  57. +2
    -2
      example-clients/alias.c
  58. +1
    -1
      example-clients/bufsize.c
  59. +9
    -9
      example-clients/capture_client.c
  60. +1
    -1
      example-clients/connect.c
  61. +2
    -2
      example-clients/freewheel.c
  62. +7
    -7
      example-clients/impulse_grabber.c
  63. +3
    -3
      example-clients/ipunload.c
  64. +2
    -1
      example-clients/lsp.c
  65. +22
    -10
      example-clients/metro.c
  66. +4
    -4
      example-clients/midiseq.c
  67. +6
    -6
      example-clients/midisine.c
  68. +1
    -1
      example-clients/monitor_client.c
  69. +1
    -1
      example-clients/netmaster.c
  70. +23
    -23
      example-clients/netslave.c
  71. +3
    -3
      example-clients/showtime.c
  72. +1
    -1
      example-clients/zombie.c
  73. +1
    -1
      linux/JackLinuxTime.c
  74. +70
    -0
      macosx/Jackdmp.xcodeproj/project.pbxproj
  75. +23
    -15
      macosx/coreaudio/JackCoreAudioAdapter.cpp
  76. +201
    -56
      macosx/coreaudio/JackCoreAudioDriver.cpp
  77. +6
    -2
      macosx/coreaudio/JackCoreAudioDriver.h
  78. +69
    -69
      macosx/iphone/freeverb.mm
  79. +29
    -29
      macosx/iphone/main_master.mm
  80. +26
    -25
      macosx/iphone/main_slave.mm
  81. +1
    -1
      man/jack_connect.0
  82. +1
    -1
      posix/JackPosixSemaphore.cpp
  83. +2
    -0
      posix/JackSocket.cpp
  84. +6
    -5
      posix/JackSocketClientChannel.cpp
  85. +1
    -1
      posix/JackSocketClientChannel.h
  86. +4
    -1
      posix/JackSocketServerChannel.cpp
  87. +13
    -9
      windows/JackWinNamedPipeClientChannel.cpp
  88. +1
    -1
      windows/JackWinNamedPipeClientChannel.h
  89. +7
    -4
      windows/JackWinNamedPipeServerChannel.cpp
  90. +1
    -0
      windows/libjackserver.cbp

+ 20
- 0
ChangeLog View File

@@ -35,6 +35,26 @@ Chris Caudle
Jackdmp changes log Jackdmp changes log
--------------------------- ---------------------------


2011-07-29 Stephane Letz <letz@grame.fr>

* New JackTimedDriver class to be used by JackDummyDriver, JackNetDriver and JackNetOneDriver classes.

2011-07-28 Stephane Letz <letz@grame.fr>

* Enable explicit channel mapping in CoreAudio driver.

2011-07-25 Stephane Letz <letz@grame.fr>

* NetJack2: no more timeout, correct JackWaitThreadedDriver::Execute.

2011-07-25 Stephane Letz <letz@grame.fr>

* NetJack2: improve latency management, cleanup.

2011-07-23 Stephane Letz <letz@grame.fr>

* Possible fix for http://trac.jackaudio.org/ticket/193.

2011-07-22 Stephane Letz <letz@grame.fr> 2011-07-22 Stephane Letz <letz@grame.fr>


* NetJack2: improve error reporting. * NetJack2: improve error reporting.


+ 0
- 17
common/JackAPI.cpp View File

@@ -127,7 +127,6 @@ extern "C"
unsigned long buffer_size); unsigned long buffer_size);
LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *); LIB_EXPORT int jack_port_unregister(jack_client_t *, jack_port_t *);
LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t); LIB_EXPORT void * jack_port_get_buffer(jack_port_t *, jack_nframes_t);
LIB_EXPORT void * jack_port_get_buffer_nulled(jack_port_t *, jack_nframes_t);
LIB_EXPORT const char* jack_port_name(const jack_port_t *port); LIB_EXPORT const char* jack_port_name(const jack_port_t *port);
LIB_EXPORT const char* jack_port_short_name(const jack_port_t *port); LIB_EXPORT const char* jack_port_short_name(const jack_port_t *port);
LIB_EXPORT int jack_port_flags(const jack_port_t *port); LIB_EXPORT int jack_port_flags(const jack_port_t *port);
@@ -350,22 +349,6 @@ LIB_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
} }
} }


LIB_EXPORT void* jack_port_get_buffer_nulled(jack_port_t* port, jack_nframes_t frames)
{
#ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_port_get_buffer_nulled");
#endif
uintptr_t port_aux = (uintptr_t)port;
jack_port_id_t myport = (jack_port_id_t)port_aux;
if (!CheckPort(myport)) {
jack_error("jack_port_get_buffer_nulled called with an incorrect port %ld", myport);
return NULL;
} else {
JackGraphManager* manager = GetGraphManager();
return (manager ? manager->GetBuffer(myport, frames, true) : NULL);
}
}

LIB_EXPORT const char* jack_port_name(const jack_port_t* port) LIB_EXPORT const char* jack_port_name(const jack_port_t* port)
{ {
#ifdef __CLIENTDEBUG__ #ifdef __CLIENTDEBUG__


+ 8
- 3
common/JackAudioAdapter.cpp View File

@@ -42,9 +42,12 @@ namespace Jack
// Always clear output // Always clear output
for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) {
#ifdef OPTIMIZED_PROTOCOL #ifdef OPTIMIZED_PROTOCOL
inputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer_nulled(adapter->fCapturePortList[i], frames);
if (inputBuffer[i])
inputBuffer[i] = (jack_port_connected(adapter->fCapturePortList[i]) > 0)
? (jack_default_audio_sample_t*)(adapter->fCapturePortList[i], frames)
: NULL;
if (inputBuffer[i]) {
memset(inputBuffer[i], 0, frames * sizeof(jack_default_audio_sample_t)); memset(inputBuffer[i], 0, frames * sizeof(jack_default_audio_sample_t));
}
#else #else
inputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); inputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fCapturePortList[i], frames);
memset(inputBuffer[i], 0, frames * sizeof(jack_default_audio_sample_t)); memset(inputBuffer[i], 0, frames * sizeof(jack_default_audio_sample_t));
@@ -53,7 +56,9 @@ namespace Jack


for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) {
#ifdef OPTIMIZED_PROTOCOL #ifdef OPTIMIZED_PROTOCOL
outputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer_nulled(adapter->fPlaybackPortList[i], frames);
outputBuffer[i] = (jack_port_connected(fAudioCapturePorts[audio_port_index] > 0)
? (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames)
: NULL;
#else #else
outputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); outputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames);
#endif #endif


+ 6
- 21
common/JackAudioDriver.cpp View File

@@ -215,23 +215,6 @@ int JackAudioDriver::Write()
return 0; return 0;
} }


int JackAudioDriver::ProcessNull()
{
// Keep begin cycle time
JackDriver::CycleTakeBeginTime();

if (fEngineControl->fSyncMode) {
ProcessGraphSyncMaster();
} else {
ProcessGraphAsyncMaster();
}

// Keep end cycle time
JackDriver::CycleTakeEndTime();
WaitUntilNextCycle();
return 0;
}

int JackAudioDriver::Process() int JackAudioDriver::Process()
{ {
return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
@@ -284,13 +267,13 @@ int JackAudioDriver::ProcessSync()
// Process graph // Process graph
if (fIsMaster) { if (fIsMaster) {
if (ProcessGraphSyncMaster() < 0) { if (ProcessGraphSyncMaster() < 0) {
jack_error("JackAudioDriver::ProcessSync: process error, skip cycle...");
goto end;
//jack_error("JackAudioDriver::ProcessSync: process error, skip cycle...");
//goto end;
} }
} else { } else {
if (ProcessGraphSyncSlave() < 0) { if (ProcessGraphSyncSlave() < 0) {
jack_error("JackAudioDriver::ProcessSync: process error, skip cycle...");
goto end;
//jack_error("JackAudioDriver::ProcessSync: process error, skip cycle...");
//goto end;
} }
} }


@@ -388,6 +371,7 @@ int JackAudioDriver::Stop()
return res; return res;
} }


/*
void JackAudioDriver::WaitUntilNextCycle() void JackAudioDriver::WaitUntilNextCycle()
{ {
int wait_time_usec = (int((float(fEngineControl->fBufferSize) / (float(fEngineControl->fSampleRate))) * 1000000.0f)); int wait_time_usec = (int((float(fEngineControl->fBufferSize) / (float(fEngineControl->fSampleRate))) * 1000000.0f));
@@ -395,6 +379,7 @@ void JackAudioDriver::WaitUntilNextCycle()
if (wait_time_usec > 0) if (wait_time_usec > 0)
JackSleep(wait_time_usec); JackSleep(wait_time_usec);
} }
*/


jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index, bool nulled) jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index, bool nulled)
{ {


+ 0
- 3
common/JackAudioDriver.h View File

@@ -41,8 +41,6 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver
int ProcessGraphSyncMaster(); int ProcessGraphSyncMaster();
int ProcessGraphSyncSlave(); int ProcessGraphSyncSlave();


void WaitUntilNextCycle();

virtual int ProcessAsync(); virtual int ProcessAsync();
virtual int ProcessSync(); virtual int ProcessSync();


@@ -94,7 +92,6 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver
jack_nframes_t playback_latency); jack_nframes_t playback_latency);


virtual int Process(); virtual int Process();
virtual int ProcessNull();


virtual int Attach(); virtual int Attach();
virtual int Detach(); virtual int Detach();


+ 1
- 1
common/JackChannel.h View File

@@ -74,7 +74,7 @@ class JackClientChannelInterface
return -1; return -1;
} }


virtual void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result)
virtual void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open)
{} {}
virtual void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) virtual void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
{} {}


+ 2
- 0
common/JackClient.cpp View File

@@ -151,6 +151,8 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync,
{ {
int res = 0; int res = 0;


jack_log("JackClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify);

// Done all time: redirected on subclass implementation JackLibClient and JackInternalClient // Done all time: redirected on subclass implementation JackLibClient and JackInternalClient
switch (notify) { switch (notify) {




+ 39
- 39
common/JackControlAPI.cpp View File

@@ -486,7 +486,7 @@ do_nothing_handler(int sig)
snprintf (buf, sizeof(buf), "received signal %d during shutdown (ignored)\n", sig); snprintf (buf, sizeof(buf), "received signal %d during shutdown (ignored)\n", sig);
} }


LIB_EXPORT sigset_t
SERVER_EXPORT sigset_t
jackctl_setup_signals( jackctl_setup_signals(
unsigned int flags) unsigned int flags)
{ {
@@ -564,7 +564,7 @@ jackctl_setup_signals(
return signals; return signals;
} }


LIB_EXPORT void
SERVER_EXPORT void
jackctl_wait_signals(sigset_t signals) jackctl_wait_signals(sigset_t signals)
{ {
int sig; int sig;
@@ -631,7 +631,7 @@ get_realtime_priority_constraint()
return constraint_ptr; return constraint_ptr;
} }


LIB_EXPORT jackctl_server_t * jackctl_server_create(
SERVER_EXPORT jackctl_server_t * jackctl_server_create(
bool (* on_device_acquire)(const char * device_name), bool (* on_device_acquire)(const char * device_name),
void (* on_device_release)(const char * device_name)) void (* on_device_release)(const char * device_name))
{ {
@@ -813,7 +813,7 @@ fail:
return NULL; return NULL;
} }


LIB_EXPORT void jackctl_server_destroy(jackctl_server *server_ptr)
SERVER_EXPORT void jackctl_server_destroy(jackctl_server *server_ptr)
{ {
jackctl_server_free_drivers(server_ptr); jackctl_server_free_drivers(server_ptr);
jackctl_server_free_internals(server_ptr); jackctl_server_free_internals(server_ptr);
@@ -821,18 +821,18 @@ LIB_EXPORT void jackctl_server_destroy(jackctl_server *server_ptr)
free(server_ptr); free(server_ptr);
} }


LIB_EXPORT const JSList * jackctl_server_get_drivers_list(jackctl_server *server_ptr)
SERVER_EXPORT const JSList * jackctl_server_get_drivers_list(jackctl_server *server_ptr)
{ {
return server_ptr->drivers; return server_ptr->drivers;
} }


LIB_EXPORT bool jackctl_server_stop(jackctl_server *server_ptr)
SERVER_EXPORT bool jackctl_server_stop(jackctl_server *server_ptr)
{ {
server_ptr->engine->Stop(); server_ptr->engine->Stop();
return true; return true;
} }


LIB_EXPORT bool jackctl_server_close(jackctl_server *server_ptr)
SERVER_EXPORT bool jackctl_server_close(jackctl_server *server_ptr)
{ {
server_ptr->engine->Close(); server_ptr->engine->Close();
delete server_ptr->engine; delete server_ptr->engine;
@@ -855,12 +855,12 @@ LIB_EXPORT bool jackctl_server_close(jackctl_server *server_ptr)
return true; return true;
} }


LIB_EXPORT const JSList * jackctl_server_get_parameters(jackctl_server *server_ptr)
SERVER_EXPORT const JSList * jackctl_server_get_parameters(jackctl_server *server_ptr)
{ {
return server_ptr->parameters; return server_ptr->parameters;
} }


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_open( jackctl_server_open(
jackctl_server *server_ptr, jackctl_server *server_ptr,
jackctl_driver *driver_ptr) jackctl_driver *driver_ptr)
@@ -944,7 +944,7 @@ fail:
return false; return false;
} }


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_start( jackctl_server_start(
jackctl_server *server_ptr) jackctl_server *server_ptr)
{ {
@@ -957,47 +957,47 @@ jackctl_server_start(
return result; return result;
} }


LIB_EXPORT const char * jackctl_driver_get_name(jackctl_driver *driver_ptr)
SERVER_EXPORT const char * jackctl_driver_get_name(jackctl_driver *driver_ptr)
{ {
return driver_ptr->desc_ptr->name; return driver_ptr->desc_ptr->name;
} }


LIB_EXPORT const JSList * jackctl_driver_get_parameters(jackctl_driver *driver_ptr)
SERVER_EXPORT const JSList * jackctl_driver_get_parameters(jackctl_driver *driver_ptr)
{ {
return driver_ptr->parameters; return driver_ptr->parameters;
} }


LIB_EXPORT jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver *driver_ptr)
SERVER_EXPORT jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver *driver_ptr)
{ {
return driver_ptr->desc_ptr; return driver_ptr->desc_ptr;
} }


LIB_EXPORT const char * jackctl_parameter_get_name(jackctl_parameter *parameter_ptr)
SERVER_EXPORT const char * jackctl_parameter_get_name(jackctl_parameter *parameter_ptr)
{ {
return parameter_ptr->name; return parameter_ptr->name;
} }


LIB_EXPORT const char * jackctl_parameter_get_short_description(jackctl_parameter *parameter_ptr)
SERVER_EXPORT const char * jackctl_parameter_get_short_description(jackctl_parameter *parameter_ptr)
{ {
return parameter_ptr->short_description; return parameter_ptr->short_description;
} }


LIB_EXPORT const char * jackctl_parameter_get_long_description(jackctl_parameter *parameter_ptr)
SERVER_EXPORT const char * jackctl_parameter_get_long_description(jackctl_parameter *parameter_ptr)
{ {
return parameter_ptr->long_description; return parameter_ptr->long_description;
} }


LIB_EXPORT bool jackctl_parameter_has_range_constraint(jackctl_parameter *parameter_ptr)
SERVER_EXPORT bool jackctl_parameter_has_range_constraint(jackctl_parameter *parameter_ptr)
{ {
return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) != 0; return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) != 0;
} }


LIB_EXPORT bool jackctl_parameter_has_enum_constraint(jackctl_parameter *parameter_ptr)
SERVER_EXPORT bool jackctl_parameter_has_enum_constraint(jackctl_parameter *parameter_ptr)
{ {
return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) == 0; return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_RANGE) == 0;
} }


LIB_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter *parameter_ptr)
SERVER_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter *parameter_ptr)
{ {
if (!jackctl_parameter_has_enum_constraint(parameter_ptr)) if (!jackctl_parameter_has_enum_constraint(parameter_ptr))
{ {
@@ -1007,7 +1007,7 @@ LIB_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_paramet
return parameter_ptr->constraint_ptr->constraint.enumeration.count; return parameter_ptr->constraint_ptr->constraint.enumeration.count;
} }


LIB_EXPORT union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value(jackctl_parameter *parameter_ptr, uint32_t index)
SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value(jackctl_parameter *parameter_ptr, uint32_t index)
{ {
jack_driver_param_value_t * value_ptr; jack_driver_param_value_t * value_ptr;
union jackctl_parameter_value jackctl_value; union jackctl_parameter_value jackctl_value;
@@ -1036,12 +1036,12 @@ LIB_EXPORT union jackctl_parameter_value jackctl_parameter_get_enum_constraint_v
return jackctl_value; return jackctl_value;
} }


LIB_EXPORT const char * jackctl_parameter_get_enum_constraint_description(jackctl_parameter *parameter_ptr, uint32_t index)
SERVER_EXPORT const char * jackctl_parameter_get_enum_constraint_description(jackctl_parameter *parameter_ptr, uint32_t index)
{ {
return parameter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].short_desc; return parameter_ptr->constraint_ptr->constraint.enumeration.possible_values_array[index].short_desc;
} }


LIB_EXPORT void jackctl_parameter_get_range_constraint(jackctl_parameter *parameter_ptr, union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr)
SERVER_EXPORT void jackctl_parameter_get_range_constraint(jackctl_parameter *parameter_ptr, union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * max_ptr)
{ {
switch (parameter_ptr->type) switch (parameter_ptr->type)
{ {
@@ -1059,37 +1059,37 @@ LIB_EXPORT void jackctl_parameter_get_range_constraint(jackctl_parameter *parame
} }
} }


LIB_EXPORT bool jackctl_parameter_constraint_is_strict(jackctl_parameter_t * parameter_ptr)
SERVER_EXPORT bool jackctl_parameter_constraint_is_strict(jackctl_parameter_t * parameter_ptr)
{ {
return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_STRICT) != 0; return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_STRICT) != 0;
} }


LIB_EXPORT bool jackctl_parameter_constraint_is_fake_value(jackctl_parameter_t * parameter_ptr)
SERVER_EXPORT bool jackctl_parameter_constraint_is_fake_value(jackctl_parameter_t * parameter_ptr)
{ {
return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE) != 0; return parameter_ptr->constraint_ptr != NULL && (parameter_ptr->constraint_ptr->flags & JACK_CONSTRAINT_FLAG_FAKE_VALUE) != 0;
} }


LIB_EXPORT jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter *parameter_ptr)
SERVER_EXPORT jackctl_param_type_t jackctl_parameter_get_type(jackctl_parameter *parameter_ptr)
{ {
return parameter_ptr->type; return parameter_ptr->type;
} }


LIB_EXPORT char jackctl_parameter_get_id(jackctl_parameter_t * parameter_ptr)
SERVER_EXPORT char jackctl_parameter_get_id(jackctl_parameter_t * parameter_ptr)
{ {
return parameter_ptr->id; return parameter_ptr->id;
} }


LIB_EXPORT bool jackctl_parameter_is_set(jackctl_parameter *parameter_ptr)
SERVER_EXPORT bool jackctl_parameter_is_set(jackctl_parameter *parameter_ptr)
{ {
return parameter_ptr->is_set; return parameter_ptr->is_set;
} }


LIB_EXPORT union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter *parameter_ptr)
SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_value(jackctl_parameter *parameter_ptr)
{ {
return *parameter_ptr->value_ptr; return *parameter_ptr->value_ptr;
} }


LIB_EXPORT bool jackctl_parameter_reset(jackctl_parameter *parameter_ptr)
SERVER_EXPORT bool jackctl_parameter_reset(jackctl_parameter *parameter_ptr)
{ {
if (!parameter_ptr->is_set) if (!parameter_ptr->is_set)
{ {
@@ -1103,7 +1103,7 @@ LIB_EXPORT bool jackctl_parameter_reset(jackctl_parameter *parameter_ptr)
return true; return true;
} }


LIB_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, const union jackctl_parameter_value * value_ptr)
SERVER_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, const union jackctl_parameter_value * value_ptr)
{ {
bool new_driver_parameter; bool new_driver_parameter;


@@ -1162,29 +1162,29 @@ LIB_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, co
return true; return true;
} }


LIB_EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter *parameter_ptr)
SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_default_value(jackctl_parameter *parameter_ptr)
{ {
return *parameter_ptr->default_value_ptr; return *parameter_ptr->default_value_ptr;
} }


// Internals clients // Internals clients


LIB_EXPORT const JSList * jackctl_server_get_internals_list(jackctl_server *server_ptr)
SERVER_EXPORT const JSList * jackctl_server_get_internals_list(jackctl_server *server_ptr)
{ {
return server_ptr->internals; return server_ptr->internals;
} }


LIB_EXPORT const char * jackctl_internal_get_name(jackctl_internal *internal_ptr)
SERVER_EXPORT const char * jackctl_internal_get_name(jackctl_internal *internal_ptr)
{ {
return internal_ptr->desc_ptr->name; return internal_ptr->desc_ptr->name;
} }


LIB_EXPORT const JSList * jackctl_internal_get_parameters(jackctl_internal *internal_ptr)
SERVER_EXPORT const JSList * jackctl_internal_get_parameters(jackctl_internal *internal_ptr)
{ {
return internal_ptr->parameters; return internal_ptr->parameters;
} }


LIB_EXPORT bool jackctl_server_load_internal(
SERVER_EXPORT bool jackctl_server_load_internal(
jackctl_server * server_ptr, jackctl_server * server_ptr,
jackctl_internal * internal) jackctl_internal * internal)
{ {
@@ -1197,7 +1197,7 @@ LIB_EXPORT bool jackctl_server_load_internal(
} }
} }


LIB_EXPORT bool jackctl_server_unload_internal(
SERVER_EXPORT bool jackctl_server_unload_internal(
jackctl_server * server_ptr, jackctl_server * server_ptr,
jackctl_internal * internal) jackctl_internal * internal)
{ {
@@ -1210,7 +1210,7 @@ LIB_EXPORT bool jackctl_server_unload_internal(
} }
} }


LIB_EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
{ {
if (server_ptr->engine != NULL) { if (server_ptr->engine != NULL) {
if (server_ptr->engine->IsRunning()) { if (server_ptr->engine->IsRunning()) {
@@ -1230,7 +1230,7 @@ LIB_EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_dr
} }
} }


LIB_EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
{ {
if (server_ptr->engine != NULL) { if (server_ptr->engine != NULL) {
if (server_ptr->engine->IsRunning()) { if (server_ptr->engine->IsRunning()) {
@@ -1253,7 +1253,7 @@ LIB_EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl
} }
} }


LIB_EXPORT bool jackctl_server_switch_master(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
SERVER_EXPORT bool jackctl_server_switch_master(jackctl_server * server_ptr, jackctl_driver * driver_ptr)
{ {
if (server_ptr->engine != NULL) { if (server_ptr->engine != NULL) {
return (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, driver_ptr->set_parameters) == 0); return (server_ptr->engine->SwitchMaster(driver_ptr->desc_ptr, driver_ptr->set_parameters) == 0);


+ 39
- 39
common/JackControlAPI.h View File

@@ -80,164 +80,164 @@ extern "C" {
} /* Adjust editor indent */ } /* Adjust editor indent */
#endif #endif


LIB_EXPORT sigset_t
SERVER_EXPORT sigset_t
jackctl_setup_signals( jackctl_setup_signals(
unsigned int flags); unsigned int flags);


LIB_EXPORT void
SERVER_EXPORT void
jackctl_wait_signals( jackctl_wait_signals(
sigset_t signals); sigset_t signals);


LIB_EXPORT jackctl_server_t *
SERVER_EXPORT jackctl_server_t *
jackctl_server_create( jackctl_server_create(
bool (* on_device_acquire)(const char * device_name), bool (* on_device_acquire)(const char * device_name),
void (* on_device_release)(const char * device_name)); void (* on_device_release)(const char * device_name));


LIB_EXPORT void
SERVER_EXPORT void
jackctl_server_destroy( jackctl_server_destroy(
jackctl_server_t * server); jackctl_server_t * server);


LIB_EXPORT const JSList *
SERVER_EXPORT const JSList *
jackctl_server_get_drivers_list( jackctl_server_get_drivers_list(
jackctl_server_t * server); jackctl_server_t * server);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_open( jackctl_server_open(
jackctl_server_t * server, jackctl_server_t * server,
jackctl_driver_t * driver); jackctl_driver_t * driver);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_start( jackctl_server_start(
jackctl_server_t * server); jackctl_server_t * server);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_stop( jackctl_server_stop(
jackctl_server_t * server); jackctl_server_t * server);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_close( jackctl_server_close(
jackctl_server_t * server); jackctl_server_t * server);


LIB_EXPORT const JSList *
SERVER_EXPORT const JSList *
jackctl_server_get_parameters( jackctl_server_get_parameters(
jackctl_server_t * server); jackctl_server_t * server);


LIB_EXPORT const char *
SERVER_EXPORT const char *
jackctl_driver_get_name( jackctl_driver_get_name(
jackctl_driver_t * driver); jackctl_driver_t * driver);


LIB_EXPORT const JSList *
SERVER_EXPORT const JSList *
jackctl_driver_get_parameters( jackctl_driver_get_parameters(
jackctl_driver_t * driver); jackctl_driver_t * driver);


LIB_EXPORT const char *
SERVER_EXPORT const char *
jackctl_parameter_get_name( jackctl_parameter_get_name(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT const char *
SERVER_EXPORT const char *
jackctl_parameter_get_short_description( jackctl_parameter_get_short_description(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT const char *
SERVER_EXPORT const char *
jackctl_parameter_get_long_description( jackctl_parameter_get_long_description(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT jackctl_param_type_t
SERVER_EXPORT jackctl_param_type_t
jackctl_parameter_get_type( jackctl_parameter_get_type(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT char
SERVER_EXPORT char
jackctl_parameter_get_id( jackctl_parameter_get_id(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_is_set( jackctl_parameter_is_set(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_reset( jackctl_parameter_reset(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT union jackctl_parameter_value
SERVER_EXPORT union jackctl_parameter_value
jackctl_parameter_get_value( jackctl_parameter_get_value(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_set_value( jackctl_parameter_set_value(
jackctl_parameter_t * parameter, jackctl_parameter_t * parameter,
const union jackctl_parameter_value * value_ptr); const union jackctl_parameter_value * value_ptr);


LIB_EXPORT union jackctl_parameter_value
SERVER_EXPORT union jackctl_parameter_value
jackctl_parameter_get_default_value( jackctl_parameter_get_default_value(
jackctl_parameter_t * parameter); jackctl_parameter_t * parameter);


LIB_EXPORT union jackctl_parameter_value
SERVER_EXPORT union jackctl_parameter_value
jackctl_parameter_get_default_value( jackctl_parameter_get_default_value(
jackctl_parameter *parameter_ptr); jackctl_parameter *parameter_ptr);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_has_range_constraint( jackctl_parameter_has_range_constraint(
jackctl_parameter_t * parameter_ptr); jackctl_parameter_t * parameter_ptr);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_has_enum_constraint( jackctl_parameter_has_enum_constraint(
jackctl_parameter_t * parameter_ptr); jackctl_parameter_t * parameter_ptr);


LIB_EXPORT uint32_t
SERVER_EXPORT uint32_t
jackctl_parameter_get_enum_constraints_count( jackctl_parameter_get_enum_constraints_count(
jackctl_parameter_t * parameter_ptr); jackctl_parameter_t * parameter_ptr);


LIB_EXPORT union jackctl_parameter_value
SERVER_EXPORT union jackctl_parameter_value
jackctl_parameter_get_enum_constraint_value( jackctl_parameter_get_enum_constraint_value(
jackctl_parameter_t * parameter_ptr, jackctl_parameter_t * parameter_ptr,
uint32_t index); uint32_t index);


LIB_EXPORT const char *
SERVER_EXPORT const char *
jackctl_parameter_get_enum_constraint_description( jackctl_parameter_get_enum_constraint_description(
jackctl_parameter_t * parameter_ptr, jackctl_parameter_t * parameter_ptr,
uint32_t index); uint32_t index);


LIB_EXPORT void
SERVER_EXPORT void
jackctl_parameter_get_range_constraint( jackctl_parameter_get_range_constraint(
jackctl_parameter_t * parameter_ptr, jackctl_parameter_t * parameter_ptr,
union jackctl_parameter_value * min_ptr, union jackctl_parameter_value * min_ptr,
union jackctl_parameter_value * max_ptr); union jackctl_parameter_value * max_ptr);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_constraint_is_strict( jackctl_parameter_constraint_is_strict(
jackctl_parameter_t * parameter_ptr); jackctl_parameter_t * parameter_ptr);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_constraint_is_fake_value( jackctl_parameter_constraint_is_fake_value(
jackctl_parameter_t * parameter_ptr); jackctl_parameter_t * parameter_ptr);


LIB_EXPORT const JSList *
SERVER_EXPORT const JSList *
jackctl_server_get_internals_list( jackctl_server_get_internals_list(
jackctl_server *server_ptr); jackctl_server *server_ptr);


LIB_EXPORT const char *
SERVER_EXPORT const char *
jackctl_internal_get_name( jackctl_internal_get_name(
jackctl_internal *internal_ptr); jackctl_internal *internal_ptr);


LIB_EXPORT const JSList *
SERVER_EXPORT const JSList *
jackctl_internal_get_parameters( jackctl_internal_get_parameters(
jackctl_internal *internal_ptr); jackctl_internal *internal_ptr);


LIB_EXPORT bool jackctl_server_load_internal(
SERVER_EXPORT bool jackctl_server_load_internal(
jackctl_server * server, jackctl_server * server,
jackctl_internal * internal); jackctl_internal * internal);


LIB_EXPORT bool jackctl_server_unload_internal(
SERVER_EXPORT bool jackctl_server_unload_internal(
jackctl_server * server, jackctl_server * server,
jackctl_internal * internal); jackctl_internal * internal);


LIB_EXPORT bool jackctl_server_add_slave(jackctl_server_t * server,
SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server_t * server,
jackctl_driver_t * driver); jackctl_driver_t * driver);


LIB_EXPORT bool jackctl_server_remove_slave(jackctl_server_t * server,
SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server_t * server,
jackctl_driver_t * driver); jackctl_driver_t * driver);


LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_switch_master(jackctl_server_t * server, jackctl_server_switch_master(jackctl_server_t * server,
jackctl_driver_t * driver); jackctl_driver_t * driver);




+ 1
- 1
common/JackDebugClient.h View File

@@ -46,7 +46,7 @@ PortFollower;
\brief A "decorator" debug client to validate API use. \brief A "decorator" debug client to validate API use.
*/ */


class SERVER_EXPORT JackDebugClient : public JackClient
class LIB_EXPORT JackDebugClient : public JackClient
{ {
protected: protected:




+ 3
- 6
common/JackDriver.cpp View File

@@ -217,6 +217,8 @@ void JackDriver::SetupDriverSync(int ref, bool freewheel)


int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
{ {
jack_log("JackDriver::ClientNotify ref = %ld driver = %s name = %s notify = %ld", refnum, fClientControl.fName, name, notify);

switch (notify) { switch (notify) {


case kStartFreewheelCallback: case kStartFreewheelCallback:
@@ -228,7 +230,7 @@ int JackDriver::ClientNotify(int refnum, const char* name, int notify, int sync,
jack_log("JackDriver::kStopFreewheel"); jack_log("JackDriver::kStopFreewheel");
SetupDriverSync(fClientControl.fRefNum, false); SetupDriverSync(fClientControl.fRefNum, false);
break; break;
}
}


return 0; return 0;
} }
@@ -342,11 +344,6 @@ int JackDriver::Process()
return 0; return 0;
} }


int JackDriver::ProcessNull()
{
return 0;
}

int JackDriver::Attach() int JackDriver::Attach()
{ {
return 0; return 0;


+ 17
- 19
common/JackDriver.h View File

@@ -53,14 +53,14 @@ class SERVER_EXPORT JackDriverInterface
virtual int Open() = 0; virtual int Open() = 0;


virtual int Open (bool capturing, virtual int Open (bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency) = 0;
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) = 0;


virtual int Open(jack_nframes_t buffer_size, virtual int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate, jack_nframes_t samplerate,
@@ -88,7 +88,6 @@ class SERVER_EXPORT JackDriverInterface
virtual int SetSampleRate(jack_nframes_t sample_rate) = 0; virtual int SetSampleRate(jack_nframes_t sample_rate) = 0;


virtual int Process() = 0; virtual int Process() = 0;
virtual int ProcessNull() = 0;


virtual void SetMaster(bool onoff) = 0; virtual void SetMaster(bool onoff) = 0;
virtual bool GetMaster() = 0; virtual bool GetMaster() = 0;
@@ -176,14 +175,14 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
virtual int Open(); virtual int Open();


virtual int Open (bool capturing, virtual int Open (bool capturing,
bool playing,
int inchannels,
int outchannels,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);
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);


virtual int Open(jack_nframes_t buffer_size, virtual int Open(jack_nframes_t buffer_size,
jack_nframes_t samplerate, jack_nframes_t samplerate,
@@ -199,8 +198,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
virtual int Close(); virtual int Close();


virtual int Process(); virtual int Process();
virtual int ProcessNull();

virtual int Attach(); virtual int Attach();
virtual int Detach(); virtual int Detach();




+ 18
- 35
common/JackDriverLoader.cpp View File

@@ -88,7 +88,7 @@ SERVER_EXPORT void jack_free_driver_params(JSList * driver_params)
} }
} }


LIB_EXPORT int
SERVER_EXPORT int
jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr) jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr)
{ {
struct option * long_options; struct option * long_options;
@@ -173,10 +173,10 @@ jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSLi
if (optarg) { if (optarg) {
switch (desc->params[param_index].type) { switch (desc->params[param_index].type) {
case JackDriverParamInt: case JackDriverParamInt:
driver_param->value.i = atoi (optarg);
driver_param->value.i = atoi(optarg);
break; break;
case JackDriverParamUInt: case JackDriverParamUInt:
driver_param->value.ui = strtoul (optarg, NULL, 10);
driver_param->value.ui = strtoul(optarg, NULL, 10);
break; break;
case JackDriverParamChar: case JackDriverParamChar:
driver_param->value.c = optarg[0]; driver_param->value.c = optarg[0];
@@ -185,20 +185,11 @@ jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSLi
strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX); strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
break; break;
case JackDriverParamBool: case JackDriverParamBool:

/*
if (strcasecmp ("false", optarg) == 0 ||
strcasecmp ("off", optarg) == 0 ||
strcasecmp ("no", optarg) == 0 ||
strcasecmp ("0", optarg) == 0 ||
strcasecmp ("(null)", optarg) == 0 ) {
*/
// steph
if (strcmp ("false", optarg) == 0 ||
strcmp ("off", optarg) == 0 ||
strcmp ("no", optarg) == 0 ||
strcmp ("0", optarg) == 0 ||
strcmp ("(null)", optarg) == 0 ) {
if (strcasecmp("false", optarg) == 0 ||
strcasecmp("off", optarg) == 0 ||
strcasecmp("no", optarg) == 0 ||
strcasecmp("0", optarg) == 0 ||
strcasecmp("(null)", optarg) == 0 ) {
driver_param->value.i = false; driver_param->value.i = false;


} else { } else {
@@ -317,11 +308,11 @@ jackctl_parse_driver_params(jackctl_driver *driver_ptr, int argc, char* argv[])
if (optarg) { if (optarg) {
switch (jackctl_parameter_get_type(param)) { switch (jackctl_parameter_get_type(param)) {
case JackDriverParamInt: case JackDriverParamInt:
value.i = atoi (optarg);
value.i = atoi(optarg);
jackctl_parameter_set_value(param, &value); jackctl_parameter_set_value(param, &value);
break; break;
case JackDriverParamUInt: case JackDriverParamUInt:
value.ui = strtoul (optarg, NULL, 10);
value.ui = strtoul(optarg, NULL, 10);
jackctl_parameter_set_value(param, &value); jackctl_parameter_set_value(param, &value);
break; break;
case JackDriverParamChar: case JackDriverParamChar:
@@ -329,23 +320,15 @@ jackctl_parse_driver_params(jackctl_driver *driver_ptr, int argc, char* argv[])
jackctl_parameter_set_value(param, &value); jackctl_parameter_set_value(param, &value);
break; break;
case JackDriverParamString: case JackDriverParamString:
strncpy (value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
strncpy(value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
jackctl_parameter_set_value(param, &value); jackctl_parameter_set_value(param, &value);
break; break;
case JackDriverParamBool: case JackDriverParamBool:
/*
if (strcasecmp ("false", optarg) == 0 ||
strcasecmp ("off", optarg) == 0 ||
strcasecmp ("no", optarg) == 0 ||
strcasecmp ("0", optarg) == 0 ||
strcasecmp ("(null)", optarg) == 0 ) {
*/
// steph
if (strcmp ("false", optarg) == 0 ||
strcmp ("off", optarg) == 0 ||
strcmp ("no", optarg) == 0 ||
strcmp ("0", optarg) == 0 ||
strcmp ("(null)", optarg) == 0 ) {
if (strcasecmp("false", optarg) == 0 ||
strcasecmp("off", optarg) == 0 ||
strcasecmp("no", optarg) == 0 ||
strcasecmp("0", optarg) == 0 ||
strcasecmp("(null)", optarg) == 0 ) {
value.i = false; value.i = false;
} else { } else {
value.i = true; value.i = true;
@@ -835,7 +818,7 @@ JackDriverInfo::~JackDriverInfo()
UnloadDriverModule(fHandle); UnloadDriverModule(fHandle);
} }


LIB_EXPORT
SERVER_EXPORT
jack_driver_desc_t * jack_driver_desc_t *
jack_driver_descriptor_construct( jack_driver_descriptor_construct(
const char * name, const char * name,
@@ -873,7 +856,7 @@ jack_driver_descriptor_construct(
return desc_ptr; return desc_ptr;
} }


LIB_EXPORT
SERVER_EXPORT
int int
jack_driver_descriptor_add_parameter( jack_driver_descriptor_add_parameter(
jack_driver_desc_t * desc_ptr, jack_driver_desc_t * desc_ptr,


+ 13
- 65
common/JackDummyDriver.cpp View File

@@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */


#include "JackDummyDriver.h" #include "JackDummyDriver.h"
#include "JackEngineControl.h"
#include "JackGraphManager.h"
#include "JackDriverLoader.h" #include "JackDriverLoader.h"
#include "JackThreadedDriver.h" #include "JackThreadedDriver.h"
#include "JackCompilerDeps.h" #include "JackCompilerDeps.h"
@@ -28,61 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <math.h>


namespace Jack
{

int JackDummyDriver::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) {
int buffer_size = lroundf((fWaitTime * fEngineControl->fSampleRate) / 1000000.0f);
if (buffer_size > BUFFER_SIZE_MAX) {
buffer_size = BUFFER_SIZE_MAX;
jack_error("Buffer size set to %d ", BUFFER_SIZE_MAX);
}
SetBufferSize(buffer_size);
return 0;
} else {
return -1;
}
}

int JackDummyDriver::Process()
{
JackDriver::CycleTakeBeginTime();
JackAudioDriver::Process();
JackSleep(std::max(0L, long(fWaitTime - (GetMicroSeconds() - fBeginDateUst))));
return 0;
}

int JackDummyDriver::SetBufferSize(jack_nframes_t buffer_size)
{
// Generic change, never fails
JackAudioDriver::SetBufferSize(buffer_size);
fWaitTime = (unsigned long)((((float)buffer_size) / ((float)fEngineControl->fSampleRate)) * 1000000.0f);
return 0;
}

} // end of namespace


#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
@@ -117,10 +60,10 @@ extern "C"


SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) {
jack_nframes_t sample_rate = 48000; jack_nframes_t sample_rate = 48000;
jack_nframes_t period_size = 1024;
jack_nframes_t buffer_size = 1024;
unsigned int capture_ports = 2; unsigned int capture_ports = 2;
unsigned int playback_ports = 2; unsigned int playback_ports = 2;
unsigned long wait_time = 0;
int wait_time = 0;
const JSList * node; const JSList * node;
const jack_driver_param_t * param; const jack_driver_param_t * param;
bool monitor = false; bool monitor = false;
@@ -143,7 +86,7 @@ extern "C"
break; break;


case 'p': case 'p':
period_size = param->value.ui;
buffer_size = param->value.ui;
break; break;


case 'w': case 'w':
@@ -156,11 +99,16 @@ extern "C"
} }
} }


if (wait_time == 0) // Not set
wait_time = (unsigned long)((((float)period_size) / ((float)sample_rate)) * 1000000.0f);

Jack::JackDriverClientInterface* driver = new Jack::JackThreadedDriver(new Jack::JackDummyDriver("system", "dummy_pcm", engine, table, wait_time));
if (driver->Open(period_size, sample_rate, 1, 1, capture_ports, playback_ports, monitor, "dummy", "dummy", 0, 0) == 0) {
if (wait_time > 0) {
buffer_size = lroundf((wait_time * sample_rate) / 1000000.0f);
if (buffer_size > BUFFER_SIZE_MAX) {
buffer_size = BUFFER_SIZE_MAX;
jack_error("Buffer size set to %d", BUFFER_SIZE_MAX);
}
}
Jack::JackDriverClientInterface* driver = new Jack::JackThreadedDriver(new Jack::JackDummyDriver("system", "dummy_pcm", engine, table));
if (driver->Open(buffer_size, sample_rate, 1, 1, capture_ports, playback_ports, monitor, "dummy", "dummy", 0, 0) == 0) {
return driver; return driver;
} else { } else {
delete driver; delete driver;


+ 5
- 30
common/JackDummyDriver.h View File

@@ -21,7 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef __JackDummyDriver__ #ifndef __JackDummyDriver__
#define __JackDummyDriver__ #define __JackDummyDriver__


#include "JackAudioDriver.h"
#include "JackTimedDriver.h"


namespace Jack namespace Jack
{ {
@@ -30,42 +30,17 @@ namespace Jack
\brief The dummy driver. \brief The dummy driver.
*/ */


class JackDummyDriver : public JackAudioDriver
class JackDummyDriver : public JackTimedDriver
{ {
private:

long fWaitTime;

public: public:


JackDummyDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, unsigned long wait_time)
: JackAudioDriver(name, alias, engine, table), fWaitTime(wait_time)
JackDummyDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
: JackTimedDriver(name, alias, engine, table)
{} {}
virtual ~JackDummyDriver() virtual ~JackDummyDriver()
{} {}


int Open(jack_nframes_t buffersize,
jack_nframes_t samplerate,
bool capturing,
bool playing,
int chan_in,
int chan_out,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,
jack_nframes_t capture_latency,
jack_nframes_t playback_latency);

int Process();
// BufferSize can be changed
bool IsFixedBufferSize()
{
return false;
}

int SetBufferSize(jack_nframes_t buffer_size);

}; };


} // end of namespace } // end of namespace


+ 6
- 11
common/JackEngine.cpp View File

@@ -140,7 +140,6 @@ void JackEngine::ProcessNext(jack_time_t cur_cycle_begin)
fLastSwitchUsecs = cur_cycle_begin; fLastSwitchUsecs = cur_cycle_begin;
if (fGraphManager->RunNextGraph()) { // True if the graph actually switched to a new state if (fGraphManager->RunNextGraph()) { // True if the graph actually switched to a new state
fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0); fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0);
//NotifyGraphReorder();
} }
fSignal.Signal(); // Signal for threads waiting for next cycle fSignal.Signal(); // Signal for threads waiting for next cycle
} }
@@ -198,13 +197,11 @@ void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions
if (status != NotTriggered && status != Finished) { if (status != NotTriggered && status != Finished) {
jack_error("JackEngine::XRun: client = %s was not run: state = %ld", client->GetClientControl()->fName, status); jack_error("JackEngine::XRun: client = %s was not run: state = %ld", client->GetClientControl()->fName, status);
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients
//NotifyXRun(ALL_CLIENTS);
} }


if (status == Finished && (long)(finished_date - callback_usecs) > 0) { if (status == Finished && (long)(finished_date - callback_usecs) > 0) {
jack_error("JackEngine::XRun: client %s finished after current callback", client->GetClientControl()->fName); jack_error("JackEngine::XRun: client %s finished after current callback", client->GetClientControl()->fName);
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients
//NotifyXRun(ALL_CLIENTS);
} }
} }
} }
@@ -275,10 +272,10 @@ int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* nam
// Notify existing clients of the new client and new client of existing clients. // Notify existing clients of the new client and new client of existing clients.
for (int i = 0; i < CLIENT_NUM; i++) { for (int i = 0; i < CLIENT_NUM; i++) {
JackClientInterface* old_client = fClientTable[i]; JackClientInterface* old_client = fClientTable[i];
if (old_client) {
if (old_client && old_client != new_client) {
if (old_client->ClientNotify(refnum, name, kAddClient, true, "", 0, 0) < 0) { if (old_client->ClientNotify(refnum, name, kAddClient, true, "", 0, 0) < 0) {
jack_error("NotifyAddClient old_client fails name = %s", old_client->GetClientControl()->fName); jack_error("NotifyAddClient old_client fails name = %s", old_client->GetClientControl()->fName);
return -1;
// Not considered as a failure...
} }
if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, kAddClient, true, "", 0, 0) < 0) { if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, kAddClient, true, "", 0, 0) < 0) {
jack_error("NotifyAddClient new_client fails name = %s", name); jack_error("NotifyAddClient new_client fails name = %s", name);
@@ -296,7 +293,7 @@ void JackEngine::NotifyRemoveClient(const char* name, int refnum)
for (int i = 0; i < CLIENT_NUM; i++) { for (int i = 0; i < CLIENT_NUM; i++) {
JackClientInterface* client = fClientTable[i]; JackClientInterface* client = fClientTable[i];
if (client) { if (client) {
client->ClientNotify(refnum, name, kRemoveClient, true, "",0, 0);
client->ClientNotify(refnum, name, kRemoveClient, true, "", 0, 0);
} }
} }
} }
@@ -307,7 +304,6 @@ void JackEngine::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs)
// Use the audio thread => request thread communication channel // Use the audio thread => request thread communication channel
fEngineControl->NotifyXRun(callback_usecs, delayed_usecs); fEngineControl->NotifyXRun(callback_usecs, delayed_usecs);
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0);
//NotifyXRun(ALL_CLIENTS);
} }


void JackEngine::NotifyXRun(int refnum) void JackEngine::NotifyXRun(int refnum)
@@ -427,7 +423,7 @@ int JackEngine::ClientCheck(const char* name, int uuid, char* name_res, int prot
*status = 0; *status = 0;
strcpy(name_res, name); strcpy(name_res, name);


jack_log("Check protocol client %ld server = %ld", protocol, JACK_PROTOCOL_VERSION);
jack_log("Check protocol client = %ld server = %ld", protocol, JACK_PROTOCOL_VERSION);


if (protocol != JACK_PROTOCOL_VERSION) { if (protocol != JACK_PROTOCOL_VERSION) {
*status |= (JackFailure | JackVersionError); *status |= (JackFailure | JackVersionError);
@@ -563,7 +559,6 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref
} else { } else {
strncpy(real_name, name, JACK_CLIENT_NAME_SIZE); strncpy(real_name, name, JACK_CLIENT_NAME_SIZE);
} }

EnsureUUID(uuid); EnsureUUID(uuid);
} }


@@ -686,12 +681,12 @@ int JackEngine::ClientCloseAux(int refnum, JackClientInterface* client, bool wai
int i; int i;


fGraphManager->GetInputPorts(refnum, ports); fGraphManager->GetInputPorts(refnum, ports);
for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) {
for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY); i++) {
PortUnRegister(refnum, ports[i]); PortUnRegister(refnum, ports[i]);
} }


fGraphManager->GetOutputPorts(refnum, ports); fGraphManager->GetOutputPorts(refnum, ports);
for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) {
for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY); i++) {
PortUnRegister(refnum, ports[i]); PortUnRegister(refnum, ports[i]);
} }




+ 4
- 4
common/JackExternalClient.cpp View File

@@ -36,7 +36,7 @@ JackExternalClient::~JackExternalClient()
int JackExternalClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) int JackExternalClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
{ {
int result = -1; int result = -1;
jack_log("JackExternalClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify);
jack_log("JackExternalClient::ClientNotify ref = %ld client = %s name = %s notify = %ld", refnum, fClientControl->fName, name, notify);
fChannel.ClientNotify(refnum, name, notify, sync, message, value1, value2, &result); fChannel.ClientNotify(refnum, name, notify, sync, message, value1, value2, &result);
return result; return result;
} }
@@ -49,17 +49,17 @@ int JackExternalClient::Open(const char* name, int pid, int refnum, int uuid, in
jack_error("Cannot connect to client name = %s\n", name); jack_error("Cannot connect to client name = %s\n", name);
return -1; return -1;
} }
// Use "placement new" to allocate object in shared memory // Use "placement new" to allocate object in shared memory
JackShmMemAble* shared_mem = static_cast<JackShmMemAble*>(JackShmMem::operator new(sizeof(JackClientControl))); JackShmMemAble* shared_mem = static_cast<JackShmMemAble*>(JackShmMem::operator new(sizeof(JackClientControl)));
shared_mem->Init(); shared_mem->Init();
fClientControl = new(shared_mem) JackClientControl(name, pid, refnum, uuid); fClientControl = new(shared_mem) JackClientControl(name, pid, refnum, uuid);
if (!fClientControl) { if (!fClientControl) {
jack_error("Cannot allocate client shared memory segment"); jack_error("Cannot allocate client shared memory segment");
return -1; return -1;
} }
*shared_client = shared_mem->GetShmIndex(); *shared_client = shared_mem->GetShmIndex();
jack_log("JackExternalClient::Open name = %s index = %ld base = %x", name, shared_mem->GetShmIndex(), shared_mem->GetShmAddress()); jack_log("JackExternalClient::Open name = %s index = %ld base = %x", name, shared_mem->GetShmIndex(), shared_mem->GetShmAddress());
return 0; return 0;


+ 2
- 2
common/JackExternalClient.h View File

@@ -38,8 +38,8 @@ class JackExternalClient : public JackClientInterface


private: private:


JackNotifyChannel fChannel; /*! Server/client communication channel */
JackClientControl* fClientControl; /*! Client control in shared memory */
JackNotifyChannel fChannel; /*! Server/client communication channel */
JackClientControl* fClientControl; /*! Client control in shared memory */


public: public:




+ 3
- 3
common/JackGlobals.h View File

@@ -53,9 +53,9 @@ struct JackGlobals {
}; };


// Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. // Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table.
extern LIB_EXPORT JackGraphManager* GetGraphManager();
extern LIB_EXPORT JackEngineControl* GetEngineControl();
extern LIB_EXPORT JackSynchro* GetSynchroTable();
extern SERVER_EXPORT JackGraphManager* GetGraphManager();
extern SERVER_EXPORT JackEngineControl* GetEngineControl();
extern SERVER_EXPORT JackSynchro* GetSynchroTable();


} // end of namespace } // end of namespace




+ 7
- 6
common/JackInternalClient.cpp View File

@@ -38,17 +38,17 @@ JackGraphManager* JackInternalClient::fGraphManager = NULL;
JackEngineControl* JackInternalClient::fEngineControl = NULL; JackEngineControl* JackInternalClient::fEngineControl = NULL;


// Used for external C API (JackAPI.cpp) // Used for external C API (JackAPI.cpp)
LIB_EXPORT JackGraphManager* GetGraphManager()
SERVER_EXPORT JackGraphManager* GetGraphManager()
{ {
return JackServerGlobals::fInstance->GetGraphManager(); return JackServerGlobals::fInstance->GetGraphManager();
} }


LIB_EXPORT JackEngineControl* GetEngineControl()
SERVER_EXPORT JackEngineControl* GetEngineControl()
{ {
return JackServerGlobals::fInstance->GetEngineControl(); return JackServerGlobals::fInstance->GetEngineControl();
} }


LIB_EXPORT JackSynchro* GetSynchroTable()
SERVER_EXPORT JackSynchro* GetSynchroTable()
{ {
return JackServerGlobals::fInstance->GetSynchroTable(); return JackServerGlobals::fInstance->GetSynchroTable();
} }
@@ -71,13 +71,14 @@ int JackInternalClient::Open(const char* server_name, const char* name, int uuid


strncpy(fServerName, server_name, sizeof(fServerName)); strncpy(fServerName, server_name, sizeof(fServerName));


fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, false);
if (result < 0) { if (result < 0) {
int status1 = *status; int status1 = *status;
if (status1 & JackVersionError)
if (status1 & JackVersionError) {
jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
else
} else {
jack_error("Client name = %s conflits with another running client", name); jack_error("Client name = %s conflits with another running client", name);
}
goto error; goto error;
} }




+ 1
- 1
common/JackInternalClientChannel.h View File

@@ -50,7 +50,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface
return 0; return 0;
} }


void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result)
void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open)
{ {
*result = fEngine->ClientCheck(name, uuid, name_res, protocol, options, status); *result = fEngine->ClientCheck(name, uuid, name_res, protocol, options, status);
} }


+ 1
- 0
common/JackLibAPI.cpp View File

@@ -42,6 +42,7 @@ extern "C"
jack_client_t * jack_client_open_aux (const char *client_name, jack_client_t * jack_client_open_aux (const char *client_name,
jack_options_t options, jack_options_t options,
jack_status_t *status, va_list ap); jack_status_t *status, va_list ap);

LIB_EXPORT jack_client_t * jack_client_open (const char *client_name, LIB_EXPORT jack_client_t * jack_client_open (const char *client_name,
jack_options_t options, jack_options_t options,
jack_status_t *status, ...); jack_status_t *status, ...);


+ 5
- 8
common/JackLibClient.cpp View File

@@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.


You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


*/ */
@@ -100,22 +100,19 @@ int JackLibClient::Open(const char* server_name, const char* name, int uuid, jac
JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName); JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName);
fClientControl.SetShmIndex(shared_client, fServerName); fClientControl.SetShmIndex(shared_client, fServerName);
JackGlobals::fVerbose = GetEngineControl()->fVerbose; JackGlobals::fVerbose = GetEngineControl()->fVerbose;
} catch (int n) {
jack_error("Map shared memory segments exception %d", n);
goto error;
} catch (...) { } catch (...) {
jack_error("Unknown error...");
jack_error("Map shared memory segments exception");
goto error; goto error;
} }


SetupDriverSync(false); SetupDriverSync(false);
// Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process
if (!fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName)) { if (!fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName)) {
jack_error("Cannot ConnectSemaphore %s client", name_res); jack_error("Cannot ConnectSemaphore %s client", name_res);
goto error; goto error;
} }
JackGlobals::fClientTable[GetClientControl()->fRefNum] = this; JackGlobals::fClientTable[GetClientControl()->fRefNum] = this;
JackGlobals::fServerRunning = true; JackGlobals::fServerRunning = true;
SetClockSource(GetEngineControl()->fClockSource); SetClockSource(GetEngineControl()->fClockSource);
@@ -146,7 +143,7 @@ int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int


case kRemoveClient: case kRemoveClient:
jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum); jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum);
if (strcmp(GetClientControl()->fName, name) != 0)
if (GetClientControl() && strcmp(GetClientControl()->fName, name) != 0)
res = fSynchroTable[refnum].Disconnect() ? 0 : -1; res = fSynchroTable[refnum].Disconnect() ? 0 : -1;
break; break;
} }


+ 1
- 1
common/JackLibClient.h View File

@@ -32,7 +32,7 @@ namespace Jack
\brief Client on the library side. \brief Client on the library side.
*/ */


class SERVER_EXPORT JackLibClient : public JackClient
class LIB_EXPORT JackLibClient : public JackClient
{ {


private: private:


+ 1
- 1
common/JackLibGlobals.h View File

@@ -50,7 +50,7 @@ class JackClient;
\brief Global library static structure: singleton kind of pattern. \brief Global library static structure: singleton kind of pattern.
*/ */


struct SERVER_EXPORT JackLibGlobals
struct LIB_EXPORT JackLibGlobals
{ {
JackShmReadWritePtr<JackGraphManager> fGraphManager; /*! Shared memory Port manager */ JackShmReadWritePtr<JackGraphManager> fGraphManager; /*! Shared memory Port manager */
JackShmReadWritePtr<JackEngineControl> fEngineControl; /*! Shared engine control */ // transport engine has to be writable JackShmReadWritePtr<JackEngineControl> fEngineControl; /*! Shared engine control */ // transport engine has to be writable


+ 14
- 7
common/JackMidiAPI.cpp View File

@@ -57,8 +57,9 @@ LIB_EXPORT
jack_nframes_t jack_midi_get_event_count(void* port_buffer) jack_nframes_t jack_midi_get_event_count(void* port_buffer)
{ {
JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer;
if (!buf || !buf->IsValid())
if (!buf || !buf->IsValid()) {
return 0; return 0;
}
return buf->event_count; return buf->event_count;
} }


@@ -66,10 +67,12 @@ LIB_EXPORT
int jack_midi_event_get(jack_midi_event_t *event, void* port_buffer, jack_nframes_t event_index) int jack_midi_event_get(jack_midi_event_t *event, void* port_buffer, jack_nframes_t event_index)
{ {
JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer;
if (!buf || !buf->IsValid())
if (!buf || !buf->IsValid()) {
return -EINVAL; return -EINVAL;
if (event_index >= buf->event_count)
}
if (event_index >= buf->event_count) {
return -ENOBUFS; return -ENOBUFS;
}
JackMidiEvent* ev = &buf->events[event_index]; JackMidiEvent* ev = &buf->events[event_index];
event->time = ev->time; event->time = ev->time;
event->size = ev->size; event->size = ev->size;
@@ -81,8 +84,9 @@ LIB_EXPORT
void jack_midi_clear_buffer(void* port_buffer) void jack_midi_clear_buffer(void* port_buffer)
{ {
JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer;
if (buf && buf->IsValid())
if (buf && buf->IsValid()) {
buf->Reset(buf->nframes); buf->Reset(buf->nframes);
}
} }


LIB_EXPORT LIB_EXPORT
@@ -124,13 +128,16 @@ int jack_midi_event_write(void* port_buffer,
jack_nframes_t time, const jack_midi_data_t* data, size_t data_size) jack_nframes_t time, const jack_midi_data_t* data, size_t data_size)
{ {
JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer; JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer;
if (!buf && !buf->IsValid())
if (!buf && !buf->IsValid()) {
return -EINVAL; return -EINVAL;
if (time >= buf->nframes || (buf->event_count && buf->events[buf->event_count - 1].time > time))
}
if (time >= buf->nframes || (buf->event_count && buf->events[buf->event_count - 1].time > time)) {
return -EINVAL; return -EINVAL;
}
jack_midi_data_t* dest = buf->ReserveEvent(time, data_size); jack_midi_data_t* dest = buf->ReserveEvent(time, data_size);
if (!dest)
if (!dest) {
return -ENOBUFS; return -ENOBUFS;
}
memcpy(dest, data, data_size); memcpy(dest, data, data_size);
return 0; return 0;
} }


+ 0
- 5
common/JackMidiDriver.cpp View File

@@ -143,11 +143,6 @@ int JackMidiDriver::SetBufferSize(jack_nframes_t buffer_size)
return 0; return 0;
} }


int JackMidiDriver::ProcessNull()
{
return 0;
}

int JackMidiDriver::ProcessRead() int JackMidiDriver::ProcessRead()
{ {
return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync(); return (fEngineControl->fSyncMode) ? ProcessReadSync() : ProcessReadAsync();


+ 0
- 2
common/JackMidiDriver.h View File

@@ -74,8 +74,6 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver
virtual int ProcessRead(); virtual int ProcessRead();
virtual int ProcessWrite(); virtual int ProcessWrite();


virtual int ProcessNull();

virtual int Attach(); virtual int Attach();
virtual int Detach(); virtual int Detach();




+ 109
- 86
common/JackNetAPI.cpp View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009 Grame
Copyright (C) 2009-2011 Grame


This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
@@ -35,18 +35,12 @@ extern "C"


#define MASTER_NAME_SIZE 256 #define MASTER_NAME_SIZE 256


enum JackNetMode {

JackFastMode = 'f',
JackNormalMode = 'n',
JackSlowMode = 's',
};

enum JackNetEncoder { enum JackNetEncoder {


JackFloatEncoder = 0, JackFloatEncoder = 0,
JackIntEncoder = 1, JackIntEncoder = 1,
JackCeltEncoder = 2, JackCeltEncoder = 2,
JackMaxEncoder = 3
}; };


typedef struct { typedef struct {
@@ -57,9 +51,9 @@ extern "C"
int midi_output; int midi_output;
int mtu; int mtu;
int time_out; // in millisecond, -1 means in infinite int time_out; // in millisecond, -1 means in infinite
int encoder;
int encoder; // one of JackNetEncoder
int kbps; // KB per second for CELT encoder int kbps; // KB per second for CELT encoder
char mode;
int latency; // network cycles


} jack_slave_t; } jack_slave_t;


@@ -100,10 +94,10 @@ extern "C"
SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net); SERVER_EXPORT int jack_net_slave_activate(jack_net_slave_t* net);
SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net); SERVER_EXPORT int jack_net_slave_deactivate(jack_net_slave_t* net);


SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t * net, JackNetSlaveProcessCallback net_callback, void *arg);
SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg);
SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg);
SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg);
SERVER_EXPORT int jack_set_net_slave_process_callback(jack_net_slave_t* net, JackNetSlaveProcessCallback net_callback, void *arg);
SERVER_EXPORT int jack_set_net_slave_buffer_size_callback(jack_net_slave_t* net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg);
SERVER_EXPORT int jack_set_net_slave_sample_rate_callback(jack_net_slave_t* net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg);
SERVER_EXPORT int jack_set_net_slave_shutdown_callback(jack_net_slave_t* net, JackNetSlaveShutdownCallback shutdown_callback, void *arg);


// NetJack master API // NetJack master API


@@ -190,19 +184,21 @@ struct JackNetExtMaster : public JackNetMasterInterface {
} }


// Join multicast group // Join multicast group
if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR)
fprintf(stderr, "Can't join multicast group : %s\n", StrError(NET_ERROR_CODE));
if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
fprintf(stderr, "Can't join multicast group : %s\n", StrError(NET_ERROR_CODE));
}


// Local loop // Local loop
if (fSocket.SetLocalLoop() == SOCKET_ERROR)
if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
fprintf(stderr, "Can't set local loop : %s\n", StrError(NET_ERROR_CODE)); fprintf(stderr, "Can't set local loop : %s\n", StrError(NET_ERROR_CODE));
}


// Set a timeout on the multicast receive (the thread can now be cancelled) // Set a timeout on the multicast receive (the thread can now be cancelled)
if (fSocket.SetTimeOut(2000000) == SOCKET_ERROR)
if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) {
fprintf(stderr, "Can't set timeout : %s\n", StrError(NET_ERROR_CODE)); fprintf(stderr, "Can't set timeout : %s\n", StrError(NET_ERROR_CODE));
}


//main loop, wait for data, deal with it and wait again
//utility variables
// Main loop, wait for data, deal with it and wait again
int attempt = 0; int attempt = 0;
int rx_bytes = 0; int rx_bytes = 0;


@@ -251,7 +247,7 @@ struct JackNetExtMaster : public JackNetMasterInterface {
result->midi_input = fParams.fSendMidiChannels; result->midi_input = fParams.fSendMidiChannels;
result->midi_output = fParams.fReturnMidiChannels; result->midi_output = fParams.fReturnMidiChannels;
result->mtu = fParams.fMtu; result->mtu = fParams.fMtu;
result->mode = fParams.fNetworkMode;
result->latency = fParams.fNetworkLatency;
return 0; return 0;


error: error:
@@ -278,12 +274,14 @@ struct JackNetExtMaster : public JackNetMasterInterface {
fSocket.Close(); fSocket.Close();


// Network slave init // Network slave init
if (!JackNetMasterInterface::Init())
if (!JackNetMasterInterface::Init()) {
return -1; return -1;
}


// Set global parameters // Set global parameters
if (!SetParams())
if (!SetParams()) {
return -1; return -1;
}


AllocPorts(); AllocPorts();
return 0; return 0;
@@ -376,8 +374,9 @@ struct JackNetExtMaster : public JackNetMasterInterface {
fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]); fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_input_buffer)[midi_port_index]);
} }


if (SyncRecv() == SOCKET_ERROR)
if (SyncRecv() == SOCKET_ERROR) {
return 0; return 0;
}


DecodeSyncPacket(); DecodeSyncPacket();
return DataRecv(); return DataRecv();
@@ -391,22 +390,23 @@ struct JackNetExtMaster : public JackNetMasterInterface {
int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer) int Write(int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer)
{ {
try { try {
assert(audio_output == fParams.fSendAudioChannels);
assert(audio_output == fParams.fSendAudioChannels);


for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) {
fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]);
}
for (int audio_port_index = 0; audio_port_index < audio_output; audio_port_index++) {
fNetAudioCaptureBuffer->SetBuffer(audio_port_index, audio_output_buffer[audio_port_index]);
}


for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) {
fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
}
for (int midi_port_index = 0; midi_port_index < midi_output; midi_port_index++) {
fNetMidiCaptureBuffer->SetBuffer(midi_port_index, ((JackMidiBuffer**)midi_output_buffer)[midi_port_index]);
}


EncodeSyncPacket();
EncodeSyncPacket();


if (SyncSend() == SOCKET_ERROR)
return SOCKET_ERROR;
if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR;
}


return DataSend();
return DataSend();


} catch (JackNetException& e) { } catch (JackNetException& e) {
jack_error("Connection lost."); jack_error("Connection lost.");
@@ -472,7 +472,7 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
fParams.fReturnAudioChannels = request->audio_output; fParams.fReturnAudioChannels = request->audio_output;
fParams.fSendMidiChannels = request->midi_input; fParams.fSendMidiChannels = request->midi_input;
fParams.fReturnMidiChannels = request->midi_output; fParams.fReturnMidiChannels = request->midi_output;
fParams.fNetworkMode = request->mode;
fParams.fNetworkLatency = request->latency;
fParams.fSampleEncoder = request->encoder; fParams.fSampleEncoder = request->encoder;
fParams.fKBps = request->kbps; fParams.fKBps = request->kbps;
fParams.fSlaveSyncMode = 1; fParams.fSlaveSyncMode = 1;
@@ -493,13 +493,20 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf


int Open(jack_master_t* result) int Open(jack_master_t* result)
{ {
if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
printf("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
return -1;
}

// Init network connection // Init network connection
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut))
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
return -1; return -1;
}


// Then set global parameters // Then set global parameters
if (!SetParams())
if (!SetParams()) {
return -1; return -1;
}


// Set result // Set result
if (result != NULL) { if (result != NULL) {
@@ -519,23 +526,28 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
int Restart() int Restart()
{ {
// If shutdown cb is set, then call it // If shutdown cb is set, then call it
if (fShutdownCallback)
if (fShutdownCallback) {
fShutdownCallback(fShutdownArg); fShutdownCallback(fShutdownArg);
}


// Init network connection // Init network connection
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut))
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
return -1; return -1;
}


// Then set global parameters // Then set global parameters
if (!SetParams())
if (!SetParams()) {
return -1; return -1;
}


// We need to notify possibly new buffer size and sample rate (see Execute) // We need to notify possibly new buffer size and sample rate (see Execute)
if (fBufferSizeCallback)
if (fBufferSizeCallback) {
fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg); fBufferSizeCallback(fParams.fPeriodSize, fBufferSizeArg);
}


if (fSampleRateCallback)
if (fSampleRateCallback) {
fSampleRateCallback(fParams.fSampleRate, fSampleRateArg); fSampleRateCallback(fParams.fSampleRate, fSampleRateArg);
}


AllocPorts(); AllocPorts();
return 0; return 0;
@@ -550,62 +562,58 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf


void AllocPorts() void AllocPorts()
{ {
int port_index;

// Set buffers // Set buffers
fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels]; fAudioCaptureBuffer = new float*[fParams.fSendAudioChannels];
for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) {
fAudioCaptureBuffer[port_index] = new float[fParams.fPeriodSize];
fNetAudioCaptureBuffer->SetBuffer(port_index, fAudioCaptureBuffer[port_index]);
for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
fAudioCaptureBuffer[audio_port_index] = new float[fParams.fPeriodSize];
fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fAudioCaptureBuffer[audio_port_index]);
} }


fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels]; fMidiCaptureBuffer = new JackMidiBuffer*[fParams.fSendMidiChannels];
for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) {
fMidiCaptureBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
fNetMidiCaptureBuffer->SetBuffer(port_index, fMidiCaptureBuffer[port_index]);
for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
fMidiCaptureBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
fNetMidiCaptureBuffer->SetBuffer(midi_port_index, fMidiCaptureBuffer[midi_port_index]);
} }


fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels]; fAudioPlaybackBuffer = new float*[fParams.fReturnAudioChannels];
for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) {
fAudioPlaybackBuffer[port_index] = new float[fParams.fPeriodSize];
fNetAudioPlaybackBuffer->SetBuffer(port_index, fAudioPlaybackBuffer[port_index]);
for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
fAudioPlaybackBuffer[audio_port_index] = new float[fParams.fPeriodSize];
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, fAudioPlaybackBuffer[audio_port_index]);
} }


fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels]; fMidiPlaybackBuffer = new JackMidiBuffer*[fParams.fReturnMidiChannels];
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) {
fMidiPlaybackBuffer[port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
fNetMidiPlaybackBuffer->SetBuffer(port_index, fMidiPlaybackBuffer[port_index]);
for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
fMidiPlaybackBuffer[midi_port_index] = (JackMidiBuffer*)new float[fParams.fPeriodSize];
fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, fMidiPlaybackBuffer[midi_port_index]);
} }
} }


void FreePorts() void FreePorts()
{ {
int port_index;

if (fAudioCaptureBuffer) { if (fAudioCaptureBuffer) {
for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++)
delete[] fAudioCaptureBuffer[port_index];
for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++)
delete[] fAudioCaptureBuffer[audio_port_index];
delete[] fAudioCaptureBuffer; delete[] fAudioCaptureBuffer;
fAudioCaptureBuffer = NULL; fAudioCaptureBuffer = NULL;
} }


if (fMidiCaptureBuffer) { if (fMidiCaptureBuffer) {
for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++)
delete[] (fMidiCaptureBuffer[port_index]);
for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
delete[] (fMidiCaptureBuffer[midi_port_index]);
delete[] fMidiCaptureBuffer; delete[] fMidiCaptureBuffer;
fMidiCaptureBuffer = NULL; fMidiCaptureBuffer = NULL;
} }


if (fAudioPlaybackBuffer) { if (fAudioPlaybackBuffer) {
for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++)
delete[] fAudioPlaybackBuffer[port_index];
for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++)
delete[] fAudioPlaybackBuffer[audio_port_index];
delete[] fAudioPlaybackBuffer; delete[] fAudioPlaybackBuffer;
fAudioPlaybackBuffer = NULL; fAudioPlaybackBuffer = NULL;
} }


if (fMidiPlaybackBuffer) { if (fMidiPlaybackBuffer) {
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++)
delete[] fMidiPlaybackBuffer[port_index];
for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
delete[] fMidiPlaybackBuffer[midi_port_index];
delete[] fMidiPlaybackBuffer; delete[] fMidiPlaybackBuffer;
fMidiPlaybackBuffer = NULL; fMidiPlaybackBuffer = NULL;
} }
@@ -621,7 +629,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
bool Init() bool Init()
{ {
// Will do "something" on OSX only... // Will do "something" on OSX only...
fThread.SetParams(UInt64(float(fParams.fPeriodSize)/float(fParams.fSampleRate)*1000000), 100 * 1000, 500 * 1000);
UInt64 period, constraint;
period = constraint = float(fParams.fPeriodSize) / float(fParams.fSampleRate) * 1000000;
UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize);
fThread.SetParams(period, computation, constraint);

return (fThread.AcquireRealTime(80) == 0); // TODO: get a value from the server return (fThread.AcquireRealTime(80) == 0); // TODO: get a value from the server
} }


@@ -630,8 +642,9 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
try { try {
// Keep running even in case of error // Keep running even in case of error
while (fThread.GetStatus() == JackThread::kRunning) { while (fThread.GetStatus() == JackThread::kRunning) {
if (Process() == SOCKET_ERROR)
if (Process() == SOCKET_ERROR) {
return false; return false;
}
} }
return false; return false;
} catch (JackNetException& e) { } catch (JackNetException& e) {
@@ -652,10 +665,10 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf


int Read() int Read()
{ {
// Don't return -1 in case of sync recv failure
// we need the process to continue for network error detection
if (SyncRecv() == SOCKET_ERROR)
return 0;
//receive sync (launch the cycle)
if (SyncRecv() == SOCKET_ERROR) {
return SOCKET_ERROR;
}


DecodeSyncPacket(); DecodeSyncPacket();
return DataRecv(); return DataRecv();
@@ -665,18 +678,19 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
{ {
EncodeSyncPacket(); EncodeSyncPacket();


if (SyncSend() == SOCKET_ERROR)
if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
}


return DataSend(); return DataSend();
} }


int Process() int Process()
{ {
// Read data from the network
// in case of fatal network error, stop the process
if (Read() == SOCKET_ERROR)
// Read data from the network, throw JackNetException in case of network error...
if (Read() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
}


fProcessCallback(fParams.fPeriodSize, fProcessCallback(fParams.fPeriodSize,
fParams.fSendAudioChannels, fParams.fSendAudioChannels,
@@ -689,10 +703,10 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
(void**)fMidiPlaybackBuffer, (void**)fMidiPlaybackBuffer,
fProcessArg); fProcessArg);


// Then write data to network
// in case of failure, stop process
if (Write() == SOCKET_ERROR)
// Then write data to network, throw JackNetException in case of network error...
if (Write() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
}


return 0; return 0;
} }
@@ -777,17 +791,20 @@ struct JackNetAdapter : public JackAudioAdapterInterface {
{ {
//ringbuffers //ringbuffers


if (fCaptureChannels > 0)
if (fCaptureChannels > 0) {
fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fCaptureRingBuffer = new JackResampler*[fCaptureChannels];
if (fPlaybackChannels > 0)
}
if (fPlaybackChannels > 0) {
fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels];
}


if (fAdaptative) { if (fAdaptative) {
AdaptRingBufferSize(); AdaptRingBufferSize();
jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize);
} else { } else {
if (fRingbufferCurSize > DEFAULT_RB_SIZE)
if (fRingbufferCurSize > DEFAULT_RB_SIZE) {
fRingbufferCurSize = DEFAULT_RB_SIZE; fRingbufferCurSize = DEFAULT_RB_SIZE;
}
jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize);
} }


@@ -800,10 +817,12 @@ struct JackNetAdapter : public JackAudioAdapterInterface {
fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize);
} }


if (fCaptureChannels > 0)
if (fCaptureChannels > 0) {
jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace());
if (fPlaybackChannels > 0)
}
if (fPlaybackChannels > 0) {
jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace());
}
} }


virtual ~JackNetAdapter() virtual ~JackNetAdapter()
@@ -923,7 +942,11 @@ SERVER_EXPORT jack_adapter_t* jack_create_adapter(int input, int output,
jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_buffer_size,
jack_nframes_t adapted_sample_rate) jack_nframes_t adapted_sample_rate)
{ {
return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
try {
return (jack_adapter_t*)new JackNetAdapter(input, output, host_buffer_size, host_sample_rate, adapted_buffer_size, adapted_sample_rate);
} catch (...) {
return NULL;
}
} }


SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter) SERVER_EXPORT int jack_destroy_adapter(jack_adapter_t* adapter)


+ 13
- 15
common/JackNetAdapter.cpp View File

@@ -41,6 +41,7 @@ namespace Jack
GetHostName(fParams.fName, JACK_CLIENT_NAME_SIZE); GetHostName(fParams.fName, JACK_CLIENT_NAME_SIZE);
fSocket.GetName(fParams.fSlaveNetName); fSocket.GetName(fParams.fSlaveNetName);
fParams.fMtu = DEFAULT_MTU; fParams.fMtu = DEFAULT_MTU;
// Desactivated for now...
fParams.fTransportSync = 0; fParams.fTransportSync = 0;
int send_audio = -1; int send_audio = -1;
int return_audio = -1; int return_audio = -1;
@@ -49,7 +50,7 @@ namespace Jack
fParams.fSampleRate = sample_rate; fParams.fSampleRate = sample_rate;
fParams.fPeriodSize = buffer_size; fParams.fPeriodSize = buffer_size;
fParams.fSlaveSyncMode = 1; fParams.fSlaveSyncMode = 1;
fParams.fNetworkMode = 's';
fParams.fNetworkLatency = 2;
fParams.fSampleEncoder = JackFloatEncoder; fParams.fSampleEncoder = JackFloatEncoder;
fJackClient = jack_client; fJackClient = jack_client;


@@ -94,15 +95,11 @@ namespace Jack
} }
break; break;
#endif #endif
case 'm' :
if (strcmp(param->value.str, "normal") == 0) {
fParams.fNetworkMode = 'n';
} else if (strcmp(param->value.str, "slow") == 0) {
fParams.fNetworkMode = 's';
} else if (strcmp(param->value.str, "fast") == 0) {
fParams.fNetworkMode = 'f';
} else {
jack_error("Unknown network mode, using 'normal' mode.");
case 'l' :
fParams.fNetworkLatency = param->value.i;
if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) {
jack_error("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
throw std::bad_alloc();
} }
break; break;
case 'q': case 'q':
@@ -276,20 +273,20 @@ namespace Jack
{ {
case JackTransportStopped : case JackTransportStopped :
jack_transport_stop(fJackClient); jack_transport_stop(fJackClient);
jack_info("NetMaster : transport stops.");
jack_info("NetMaster : transport stops");
break; break;


case JackTransportStarting : case JackTransportStarting :
jack_transport_reposition(fJackClient, &fSendTransportData.fPosition); jack_transport_reposition(fJackClient, &fSendTransportData.fPosition);
jack_transport_start(fJackClient); jack_transport_start(fJackClient);
jack_info("NetMaster : transport starts.");
jack_info("NetMaster : transport starts");
break; break;


case JackTransportRolling : case JackTransportRolling :
// TODO, we need to : // TODO, we need to :
// - find a way to call TransportEngine->SetNetworkSync() // - find a way to call TransportEngine->SetNetworkSync()
// - turn the transport state to JackTransportRolling // - turn the transport state to JackTransportRolling
jack_info("NetMaster : transport rolls.");
jack_info("NetMaster : transport rolls");
break; break;
} }
} }
@@ -412,8 +409,8 @@ extern "C"
value.ui = 1U; value.ui = 1U;
jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL);


strcpy(value.str, "slow");
jack_driver_descriptor_add_parameter(desc, &filler, "mode", 'm', JackDriverParamString, &value, NULL, "Slow, Normal or Fast mode.", NULL);
value.ui = 2U;
jack_driver_descriptor_add_parameter(desc, &filler, "latency", 'l', JackDriverParamUInt, &value, NULL, "Network latency", NULL);


value.i = 0; value.i = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL);
@@ -448,6 +445,7 @@ extern "C"
} }


} catch (...) { } catch (...) {
jack_info("NetAdapter allocation error");
return 1; return 1;
} }
} }


+ 64
- 108
common/JackNetDriver.cpp View File

@@ -1,5 +1,4 @@
/* /*
Copyright (C) 2001 Paul Davis
Copyright (C) 2008-2011 Romain Moret at Grame Copyright (C) 2008-2011 Romain Moret at Grame


This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@@ -29,14 +28,15 @@ namespace Jack
{ {
JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports, const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports,
char* net_name, uint transport_sync, char network_mode, int celt_encoding)
: JackAudioDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port)
char* net_name, uint transport_sync, int network_latency, int celt_encoding)
: JackTimedDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port)
{ {
jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port); jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port);


// Use the hostname if no name parameter was given // Use the hostname if no name parameter was given
if (strcmp(net_name, "") == 0)
if (strcmp(net_name, "") == 0) {
GetHostName(net_name, JACK_CLIENT_NAME_SIZE); GetHostName(net_name, JACK_CLIENT_NAME_SIZE);
}


fParams.fMtu = mtu; fParams.fMtu = mtu;
fParams.fSendMidiChannels = midi_input_ports; fParams.fSendMidiChannels = midi_input_ports;
@@ -50,7 +50,7 @@ namespace Jack
strcpy(fParams.fName, net_name); strcpy(fParams.fName, net_name);
fSocket.GetName(fParams.fSlaveNetName); fSocket.GetName(fParams.fSlaveNetName);
fParams.fTransportSync = transport_sync; fParams.fTransportSync = transport_sync;
fParams.fNetworkMode = network_mode;
fParams.fNetworkLatency = network_latency;
fSendTransportData.fState = -1; fSendTransportData.fState = -1;
fReturnTransportData.fState = -1; fReturnTransportData.fState = -1;
fLastTransportState = -1; fLastTransportState = -1;
@@ -73,32 +73,16 @@ namespace Jack
} }


//open, close, attach and detach------------------------------------------------------ //open, close, attach and detach------------------------------------------------------
int JackNetDriver::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)
{
return JackAudioDriver::Open(buffer_size,
samplerate,
capturing,
playing,
inchannels,
outchannels,
monitor,
capture_driver_name,
playback_driver_name,
capture_latency,
playback_latency);
}

int JackNetDriver::Close() int JackNetDriver::Close()
{ {
#ifdef JACK_MONITOR #ifdef JACK_MONITOR
if (fNetTimeMon)
if (fNetTimeMon) {
fNetTimeMon->Save(); fNetTimeMon->Save();
}
#endif #endif
FreeAll(); FreeAll();
return JackDriver::Close();
return JackTimedDriver::Close();
} }


// Attach and Detach are defined as empty methods: port allocation is done when driver actually start (that is in Init) // Attach and Detach are defined as empty methods: port allocation is done when driver actually start (that is in Init)
@@ -185,20 +169,7 @@ namespace Jack
plot_name = string(fParams.fName); plot_name = string(fParams.fName);
plot_name += string("_slave"); plot_name += string("_slave");
plot_name += (fEngineControl->fSyncMode) ? string("_sync") : string("_async"); plot_name += (fEngineControl->fSyncMode) ? string("_sync") : string("_async");
switch (fParams.fNetworkMode)
{
case 's' :
plot_name += string("_slow");
break;

case 'n' :
plot_name += string("_normal");
break;

case 'f' :
plot_name += string("_fast");
break;
}
plot_name += string("_latency");
fNetTimeMon = new JackGnuPlotMonitor<float>(128, 5, plot_name); fNetTimeMon = new JackGnuPlotMonitor<float>(128, 5, plot_name);
string net_time_mon_fields[] = string net_time_mon_fields[] =
{ {
@@ -216,8 +187,8 @@ namespace Jack
fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 5); fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 5);
#endif #endif
// Driver parametering // Driver parametering
JackAudioDriver::SetBufferSize(fParams.fPeriodSize);
JackAudioDriver::SetSampleRate(fParams.fSampleRate);
JackTimedDriver::SetBufferSize(fParams.fPeriodSize);
JackTimedDriver::SetSampleRate(fParams.fSampleRate);


JackDriver::NotifyBufferSize(fParams.fPeriodSize); JackDriver::NotifyBufferSize(fParams.fPeriodSize);
JackDriver::NotifySampleRate(fParams.fSampleRate); JackDriver::NotifySampleRate(fParams.fSampleRate);
@@ -273,68 +244,56 @@ namespace Jack


//audio //audio
port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++)
{
for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) {
snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1);
snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, audio_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, audio_port_index + 1);
if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0)
{
static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0) {
jack_error("driver: cannot register port for %s", name); jack_error("driver: cannot register port for %s", name);
return -1; return -1;
} }

//port latency
port = fGraphManager->GetPort(port_index); port = fGraphManager->GetPort(port_index);
port->SetAlias(alias); port->SetAlias(alias);
//port latency
range.min = range.max = fEngineControl->fBufferSize; range.min = range.max = fEngineControl->fBufferSize;
port->SetLatencyRange(JackCaptureLatency, &range); port->SetLatencyRange(JackCaptureLatency, &range);
fCapturePortList[audio_port_index] = port_index; fCapturePortList[audio_port_index] = port_index;
jack_log("JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency()); jack_log("JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency());
} }

port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++)
{
for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1);
snprintf(name, sizeof(name) - 1, "%s:playback_%d",fClientControl.fName, audio_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d",fClientControl.fName, audio_port_index + 1);
if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0)
{
static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0) {
jack_error("driver: cannot register port for %s", name); jack_error("driver: cannot register port for %s", name);
return -1; return -1;
} }

//port latency
port = fGraphManager->GetPort(port_index); port = fGraphManager->GetPort(port_index);
port->SetAlias(alias); port->SetAlias(alias);
//port latency
switch (fParams.fNetworkMode)
{
case 'f' :
range.min = range.max = (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize;
break;
case 'n' :
range.min = range.max = (fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize);
break;
case 's' :
range.min = range.max = (2 * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize);
break;
}
range.min = range.max = (fParams.fNetworkLatency * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize);
port->SetLatencyRange(JackPlaybackLatency, &range); port->SetLatencyRange(JackPlaybackLatency, &range);
fPlaybackPortList[audio_port_index] = port_index; fPlaybackPortList[audio_port_index] = port_index;
jack_log("JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency()); jack_log("JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency());
} }

//midi //midi
port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++)
{
for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1);
snprintf(name, sizeof (name) - 1, "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1); snprintf(name, sizeof (name) - 1, "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1);
if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0)
{
static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0) {
jack_error("driver: cannot register port for %s", name); jack_error("driver: cannot register port for %s", name);
return -1; return -1;
} }
port = fGraphManager->GetPort(port_index);
//port latency //port latency
port = fGraphManager->GetPort(port_index);
range.min = range.max = fEngineControl->fBufferSize; range.min = range.max = fEngineControl->fBufferSize;
port->SetLatencyRange(JackCaptureLatency, &range); port->SetLatencyRange(JackCaptureLatency, &range);
fMidiCapturePortList[midi_port_index] = port_index; fMidiCapturePortList[midi_port_index] = port_index;
@@ -342,30 +301,18 @@ namespace Jack
} }


port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++)
{
for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1);
snprintf(name, sizeof(name) - 1, "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1);
if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0)
{
static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0) {
jack_error("driver: cannot register port for %s", name); jack_error("driver: cannot register port for %s", name);
return -1; return -1;
} }
port = fGraphManager->GetPort(port_index);
//port latency //port latency
switch (fParams.fNetworkMode)
{
case 'f' :
range.min = range.max = (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize;
break;
case 'n' :
range.min = range.max = (fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize);
break;
case 's' :
range.min = range.max = (2 * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize);
break;
}
port = fGraphManager->GetPort(port_index);
range.min = range.max = (fParams.fNetworkLatency * fEngineControl->fBufferSize + (fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize);
port->SetLatencyRange(JackPlaybackLatency, &range); port->SetLatencyRange(JackPlaybackLatency, &range);
fMidiPlaybackPortList[midi_port_index] = port_index; fMidiPlaybackPortList[midi_port_index] = port_index;
jack_log("JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency()); jack_log("JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency());
@@ -413,7 +360,7 @@ namespace Jack
const char** connections; const char** connections;
fConnections.clear(); fConnections.clear();


JackAudioDriver::SaveConnections();
JackTimedDriver::SaveConnections();


for (int i = 0; i < fParams.fSendMidiChannels; ++i) { for (int i = 0; i < fParams.fSendMidiChannels; ++i) {
if (fCapturePortList[i] && (connections = fGraphManager->GetConnections(fMidiCapturePortList[i])) != 0) { if (fCapturePortList[i] && (connections = fGraphManager->GetConnections(fMidiCapturePortList[i])) != 0) {
@@ -455,8 +402,9 @@ namespace Jack
bool conditional; bool conditional;
if (fSendTransportData.fTimebaseMaster == TIMEBASEMASTER) { if (fSendTransportData.fTimebaseMaster == TIMEBASEMASTER) {
fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional); fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional);
if (refnum != -1)
if (refnum != -1) {
fEngineControl->fTransport.ResetTimebase(refnum); fEngineControl->fTransport.ResetTimebase(refnum);
}
jack_info("The NetMaster is now the new timebase master."); jack_info("The NetMaster is now the new timebase master.");
} }


@@ -513,12 +461,19 @@ namespace Jack
fReturnTransportData.fNewState = ((fReturnTransportData.fState == JackTransportNetStarting) && fReturnTransportData.fNewState = ((fReturnTransportData.fState == JackTransportNetStarting) &&
(fReturnTransportData.fState != fLastTransportState) && (fReturnTransportData.fState != fLastTransportState) &&
(fReturnTransportData.fState != fSendTransportData.fState)); (fReturnTransportData.fState != fSendTransportData.fState));
if (fReturnTransportData.fNewState)
if (fReturnTransportData.fNewState) {
jack_info("Sending '%s'.", GetTransportState(fReturnTransportData.fState)); jack_info("Sending '%s'.", GetTransportState(fReturnTransportData.fState));
}
fLastTransportState = fReturnTransportData.fState; fLastTransportState = fReturnTransportData.fState;
} }


//driver processes-------------------------------------------------------------------- //driver processes--------------------------------------------------------------------

int JackNetDriver::Process()
{
return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
}
int JackNetDriver::Read() int JackNetDriver::Read()
{ {
//buffers //buffers
@@ -538,8 +493,9 @@ namespace Jack
#endif #endif


//receive sync (launch the cycle) //receive sync (launch the cycle)
if (SyncRecv() == SOCKET_ERROR)
return 0;
if (SyncRecv() == SOCKET_ERROR) {
return SOCKET_ERROR;
}


#ifdef JACK_MONITOR #ifdef JACK_MONITOR
// For timing // For timing
@@ -581,7 +537,7 @@ namespace Jack
for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
#ifdef OPTIMIZED_PROTOCOL #ifdef OPTIMIZED_PROTOCOL
// Port is connected on other side... // Port is connected on other side...
if ((intptr_t)fNetAudioPlaybackBuffer->GetBuffer(audio_port_index) == -1) {
if (fNetAudioPlaybackBuffer->GetConnected(audio_port_index)) {
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index, true)); fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index, true));
} else { } else {
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL); fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL);
@@ -599,16 +555,18 @@ namespace Jack
EncodeSyncPacket(); EncodeSyncPacket();


//send sync //send sync
if (SyncSend() == SOCKET_ERROR)
if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
}


#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f); fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
#endif #endif


//send data //send data
if (DataSend() == SOCKET_ERROR)
if (DataSend() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
}


#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fNetTimeMon->AddLast(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f); fNetTimeMon->AddLast(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
@@ -655,11 +613,11 @@ namespace Jack
strcpy(value.str, "'hostname'"); strcpy(value.str, "'hostname'");
jack_driver_descriptor_add_parameter(desc, &filler, "client_name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "client_name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL);


value.ui = 1U;
value.ui = 0U;
jack_driver_descriptor_add_parameter(desc, &filler, "transport_sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "transport_sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL);


strcpy(value.str, "slow");
jack_driver_descriptor_add_parameter(desc, &filler, "mode", 'm', JackDriverParamString, &value, NULL, "Slow, Normal or Fast mode.", NULL);
value.ui = 5U;
jack_driver_descriptor_add_parameter(desc, &filler, "latency", 'l', JackDriverParamUInt, &value, NULL, "Network latency", NULL);


return desc; return desc;
} }
@@ -670,7 +628,8 @@ namespace Jack
char net_name[JACK_CLIENT_NAME_SIZE + 1]; char net_name[JACK_CLIENT_NAME_SIZE + 1];
int udp_port; int udp_port;
int mtu = DEFAULT_MTU; int mtu = DEFAULT_MTU;
uint transport_sync = 1;
// Desactivated for now...
uint transport_sync = 0;
jack_nframes_t period_size = 128; jack_nframes_t period_size = 128;
jack_nframes_t sample_rate = 48000; jack_nframes_t sample_rate = 48000;
int audio_capture_ports = -1; int audio_capture_ports = -1;
@@ -679,7 +638,7 @@ namespace Jack
int midi_output_ports = 0; int midi_output_ports = 0;
int celt_encoding = -1; int celt_encoding = -1;
bool monitor = false; bool monitor = false;
char network_mode = 's';
int network_latency = 5;
const JSList* node; const JSList* node;
const jack_driver_param_t* param; const jack_driver_param_t* param;


@@ -732,15 +691,12 @@ namespace Jack
case 't' : case 't' :
transport_sync = param->value.ui; transport_sync = param->value.ui;
break; break;
case 'm' :
if (strcmp(param->value.str, "normal") == 0)
network_mode = 'n';
else if (strcmp(param->value.str, "slow") == 0)
network_mode = 's';
else if (strcmp(param->value.str, "fast") == 0)
network_mode = 'f';
else
jack_error("Unknown network mode, using 'normal' mode.");
case 'l' :
network_latency = param->value.ui;
if (network_latency > NETWORK_MAX_LATENCY) {
printf("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
return NULL;
}
break; break;
} }
} }
@@ -751,7 +707,7 @@ namespace Jack
new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu, new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu,
midi_input_ports, midi_output_ports, midi_input_ports, midi_output_ports,
net_name, transport_sync, net_name, transport_sync,
network_mode, celt_encoding));
network_latency, celt_encoding));
if (driver->Open(period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, monitor, "from_master_", "to_master_", 0, 0) == 0) { if (driver->Open(period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, monitor, "from_master_", "to_master_", 0, 0) == 0) {
return driver; return driver;
} else { } else {


+ 10
- 9
common/JackNetDriver.h View File

@@ -1,5 +1,4 @@
/* /*
Copyright (C) 2001 Paul Davis
Copyright (C) 2008-2011 Romain Moret at Grame Copyright (C) 2008-2011 Romain Moret at Grame


This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@@ -21,9 +20,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef __JackNetDriver__ #ifndef __JackNetDriver__
#define __JackNetDriver__ #define __JackNetDriver__


#include "JackAudioDriver.h"
#include "JackTimedDriver.h"
#include "JackNetInterface.h" #include "JackNetInterface.h"


//#define JACK_MONITOR

#ifdef JACK_MONITOR #ifdef JACK_MONITOR
#include "JackFrameTimer.h" #include "JackFrameTimer.h"
#endif #endif
@@ -34,7 +35,7 @@ namespace Jack
\Brief This class describes the Net Backend \Brief This class describes the Net Backend
*/ */


class JackNetDriver : public JackAudioDriver, public JackNetSlaveInterface
class JackNetDriver : public JackTimedDriver, public JackNetSlaveInterface
{ {


private: private:
@@ -72,14 +73,14 @@ namespace Jack


JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports, const char* ip, int port, int mtu, int midi_input_ports, int midi_output_ports,
char* net_name, uint transport_sync, char network_master_mode, int celt_encoding);
~JackNetDriver();
char* net_name, uint transport_sync, int network_latency, int celt_encoding);
virtual ~JackNetDriver();


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 Close();

// The
int Process();
int Attach(); int Attach();
int Detach(); int Detach();




+ 321
- 360
common/JackNetInterface.cpp
File diff suppressed because it is too large
View File


+ 71
- 63
common/JackNetInterface.h View File

@@ -1,5 +1,4 @@
/* /*
Copyright (C) 2001 Paul Davis
Copyright (C) 2008-2011 Romain Moret at Grame Copyright (C) 2008-2011 Romain Moret at Grame


This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
@@ -25,8 +24,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


namespace Jack namespace Jack
{ {

#define DEFAULT_MULTICAST_IP "225.3.19.154"
#define DEFAULT_PORT 19000
#define DEFAULT_MTU 1500

#define SLAVE_SETUP_RETRY 5

#define MANAGER_INIT_TIMEOUT 2000000 // in usec
#define MASTER_INIT_TIMEOUT 1000000 // in usec
#define SLAVE_INIT_TIMEOUT 1000000 // in usec

#define NETWORK_MAX_LATENCY 20

/** /**
\Brief This class describes the basic Net Interface, used by both master and slave
\Brief This class describes the basic Net Interface, used by both master and slave.
*/ */


class SERVER_EXPORT JackNetInterface class SERVER_EXPORT JackNetInterface
@@ -40,7 +52,7 @@ namespace Jack
JackNetSocket fSocket; JackNetSocket fSocket;
char fMulticastIP[32]; char fMulticastIP[32];


//headers
// headers
packet_header_t fTxHeader; packet_header_t fTxHeader;
packet_header_t fRxHeader; packet_header_t fRxHeader;


@@ -48,31 +60,31 @@ namespace Jack
net_transport_data_t fSendTransportData; net_transport_data_t fSendTransportData;
net_transport_data_t fReturnTransportData; net_transport_data_t fReturnTransportData;


//network buffers
// network buffers
char* fTxBuffer; char* fTxBuffer;
char* fRxBuffer; char* fRxBuffer;
char* fTxData; char* fTxData;
char* fRxData; char* fRxData;


//jack buffers
// JACK buffers
NetMidiBuffer* fNetMidiCaptureBuffer; NetMidiBuffer* fNetMidiCaptureBuffer;
NetMidiBuffer* fNetMidiPlaybackBuffer; NetMidiBuffer* fNetMidiPlaybackBuffer;
NetAudioBuffer* fNetAudioCaptureBuffer; NetAudioBuffer* fNetAudioCaptureBuffer;
NetAudioBuffer* fNetAudioPlaybackBuffer; NetAudioBuffer* fNetAudioPlaybackBuffer;


//utility methods
// utility methods
int SetNetBufferSize(); int SetNetBufferSize();
void FreeNetworkBuffers(); void FreeNetworkBuffers();


//virtual methods : depends on the sub class master/slave
// virtual methods : depends on the sub class master/slave
virtual bool SetParams(); virtual bool SetParams();
virtual bool Init() = 0; virtual bool Init() = 0;


//transport
// transport
virtual void EncodeTransportData() = 0; virtual void EncodeTransportData() = 0;
virtual void DecodeTransportData() = 0; virtual void DecodeTransportData() = 0;


//sync packet
// sync packet
virtual void EncodeSyncPacket() = 0; virtual void EncodeSyncPacket() = 0;
virtual void DecodeSyncPacket() = 0; virtual void DecodeSyncPacket() = 0;


@@ -84,14 +96,23 @@ namespace Jack
virtual int Send(size_t size, int flags) = 0; virtual int Send(size_t size, int flags) = 0;
virtual int Recv(size_t size, int flags) = 0; virtual int Recv(size_t size, int flags) = 0;


virtual void FatalError() = 0;
virtual void FatalRecvError() = 0;
virtual void FatalSendError() = 0;

int MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels);
int AudioSend(NetAudioBuffer* buffer, int audio_channels);

int MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt);
int AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer);

int FinishRecv(NetAudioBuffer* buffer);

public:


JackNetInterface(); JackNetInterface();
JackNetInterface(const char* multicast_ip, int port); JackNetInterface(const char* multicast_ip, int port);
JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip); JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip);


public:

virtual ~JackNetInterface(); virtual ~JackNetInterface();


}; };
@@ -106,7 +127,9 @@ namespace Jack
protected: protected:


bool fRunning; bool fRunning;
int fCycleOffset;

int fCurrentCycleOffset;
int fMaxCycleOffset;
int fLastfCycleOffset; int fLastfCycleOffset;


bool Init(); bool Init();
@@ -121,24 +144,27 @@ namespace Jack
int DataRecv(); int DataRecv();
int DataSend(); int DataSend();


//sync packet
// sync packet
void EncodeSyncPacket(); void EncodeSyncPacket();
void DecodeSyncPacket(); void DecodeSyncPacket();


int Send ( size_t size, int flags );
int Recv ( size_t size, int flags );
int Send(size_t size, int flags);
int Recv(size_t size, int flags);


bool IsSynched(); bool IsSynched();


void FatalError();
void FatalRecvError();
void FatalSendError();


public: public:
JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCycleOffset(0), fLastfCycleOffset(0)

JackNetMasterInterface() : JackNetInterface(), fRunning(false), fCurrentCycleOffset(0), fMaxCycleOffset(0), fLastfCycleOffset(0)
{} {}
JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip )
: JackNetInterface ( params, socket, multicast_ip )
JackNetMasterInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip)
: JackNetInterface(params, socket, multicast_ip)
{} {}
~JackNetMasterInterface()

virtual~JackNetMasterInterface()
{} {}
}; };


@@ -154,7 +180,7 @@ namespace Jack
static uint fSlaveCounter; static uint fSlaveCounter;


bool Init(); bool Init();
bool InitConnection(int time_out);
bool InitConnection(int time_out_sec);
bool InitRendering(); bool InitRendering();


net_status_t SendAvailableToMaster(long count = LONG_MAX); // long here (and not int...) net_status_t SendAvailableToMaster(long count = LONG_MAX); // long here (and not int...)
@@ -168,65 +194,47 @@ namespace Jack
int DataRecv(); int DataRecv();
int DataSend(); int DataSend();


//sync packet
// sync packet
void EncodeSyncPacket(); void EncodeSyncPacket();
void DecodeSyncPacket(); void DecodeSyncPacket();


int Recv ( size_t size, int flags );
int Send ( size_t size, int flags );
int Recv(size_t size, int flags);
int Send(size_t size, int flags);

void FatalRecvError();
void FatalSendError();


void FatalError();
void InitAPI()
{
// open Socket API with the first slave
if (fSlaveCounter++ == 0) {
if (SocketAPIInit() < 0) {
jack_error("Can't init Socket API, exiting...");
throw std::bad_alloc();
}
}
}


public: public:


JackNetSlaveInterface() : JackNetInterface() JackNetSlaveInterface() : JackNetInterface()
{ {
//open Socket API with the first slave
if ( fSlaveCounter++ == 0 )
{
if ( SocketAPIInit() < 0 )
{
jack_error ( "Can't init Socket API, exiting..." );
throw -1;
}
}
InitAPI();
} }


JackNetSlaveInterface ( const char* ip, int port ) : JackNetInterface ( ip, port )
JackNetSlaveInterface(const char* ip, int port) : JackNetInterface(ip, port)
{ {
//open Socket API with the first slave
if ( fSlaveCounter++ == 0 )
{
if ( SocketAPIInit() < 0 )
{
jack_error ( "Can't init Socket API, exiting..." );
throw -1;
}
}
InitAPI();
} }


~JackNetSlaveInterface()
virtual ~JackNetSlaveInterface()
{ {
//close Socket API with the last slave
if ( --fSlaveCounter == 0 )
// close Socket API with the last slave
if (--fSlaveCounter == 0) {
SocketAPIEnd(); SocketAPIEnd();
}
} }
}; };
} }


#define DEFAULT_MULTICAST_IP "225.3.19.154"
#define DEFAULT_PORT 19000
#define DEFAULT_MTU 1500

#define SLAVE_SETUP_RETRY 5

#define MASTER_INIT_TIMEOUT 1000000 // in usec
#define SLAVE_INIT_TIMEOUT 1000000 // in usec

#define CYCLE_OFFSET_FAST 0
#define CYCLE_OFFSET_NORMAL 1
#define CYCLE_OFFSET_SLOW 2
//#define CYCLE_OFFSET_SLOW 30
#define MAX_LATENCY CYCLE_OFFSET_SLOW * 4

#endif #endif

+ 257
- 265
common/JackNetManager.cpp View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2008-2011 Romain Moret at Grame
Copyright(C) 2008-2011 Romain Moret at Grame


This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -29,13 +29,13 @@ namespace Jack
{ {
//JackNetMaster****************************************************************************************************** //JackNetMaster******************************************************************************************************


JackNetMaster::JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip)
: JackNetMasterInterface ( params, socket, multicast_ip )
JackNetMaster::JackNetMaster(JackNetSocket& socket, session_params_t& params, const char* multicast_ip)
: JackNetMasterInterface(params, socket, multicast_ip)
{ {
jack_log ( "JackNetMaster::JackNetMaster" );
jack_log("JackNetMaster::JackNetMaster");


//settings //settings
fClientName = const_cast<char*> ( fParams.fName );
fClientName = const_cast<char*>(fParams.fName);
fJackClient = NULL; fJackClient = NULL;
fSendTransportData.fState = -1; fSendTransportData.fState = -1;
fReturnTransportData.fState = -1; fReturnTransportData.fState = -1;
@@ -44,64 +44,59 @@ namespace Jack


//jack audio ports //jack audio ports
fAudioCapturePorts = new jack_port_t* [fParams.fSendAudioChannels]; fAudioCapturePorts = new jack_port_t* [fParams.fSendAudioChannels];
for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) {
fAudioCapturePorts[port_index] = NULL; fAudioCapturePorts[port_index] = NULL;
}

fAudioPlaybackPorts = new jack_port_t* [fParams.fReturnAudioChannels]; fAudioPlaybackPorts = new jack_port_t* [fParams.fReturnAudioChannels];
for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) {
fAudioPlaybackPorts[port_index] = NULL; fAudioPlaybackPorts[port_index] = NULL;
}

//jack midi ports //jack midi ports
fMidiCapturePorts = new jack_port_t* [fParams.fSendMidiChannels]; fMidiCapturePorts = new jack_port_t* [fParams.fSendMidiChannels];
for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) {
fMidiCapturePorts[port_index] = NULL; fMidiCapturePorts[port_index] = NULL;
}

fMidiPlaybackPorts = new jack_port_t* [fParams.fReturnMidiChannels]; fMidiPlaybackPorts = new jack_port_t* [fParams.fReturnMidiChannels];
for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) {
fMidiPlaybackPorts[port_index] = NULL; fMidiPlaybackPorts[port_index] = NULL;
}


//monitor //monitor
#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fPeriodUsecs = ( int ) ( 1000000.f * ( ( float ) fParams.fPeriodSize / ( float ) fParams.fSampleRate ) );
fPeriodUsecs = (int)(1000000.f * ((float) fParams.fPeriodSize / (float) fParams.fSampleRate));
string plot_name; string plot_name;
plot_name = string ( fParams.fName );
plot_name += string ( "_master" );
plot_name += string ( ( fParams.fSlaveSyncMode ) ? "_sync" : "_async" );
switch ( fParams.fNetworkMode )
{
case 's' :
plot_name += string ( "_slow" );
break;
case 'n' :
plot_name += string ( "_normal" );
break;
case 'f' :
plot_name += string ( "_fast" );
break;
}
fNetTimeMon = new JackGnuPlotMonitor<float> ( 128, 4, plot_name );
plot_name = string(fParams.fName);
plot_name += string("_master");
plot_name += string((fParams.fSlaveSyncMode) ? "_sync" : "_async");
plot_name += string("_latency");
fNetTimeMon = new JackGnuPlotMonitor<float>(128, 4, plot_name);
string net_time_mon_fields[] = string net_time_mon_fields[] =
{ {
string ( "sync send" ),
string ( "end of send" ),
string ( "sync recv" ),
string ( "end of cycle" )
string("sync send"),
string("end of send"),
string("sync recv"),
string("end of cycle")
}; };
string net_time_mon_options[] = string net_time_mon_options[] =
{ {
string ( "set xlabel \"audio cycles\"" ),
string ( "set ylabel \"% of audio cycle\"" )
string("set xlabel \"audio cycles\""),
string("set ylabel \"% of audio cycle\"")
}; };
fNetTimeMon->SetPlotFile ( net_time_mon_options, 2, net_time_mon_fields, 4 );
fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 4);
#endif #endif
} }


JackNetMaster::~JackNetMaster() JackNetMaster::~JackNetMaster()
{ {
jack_log ( "JackNetMaster::~JackNetMaster, ID %u", fParams.fID );
jack_log("JackNetMaster::~JackNetMaster ID = %u", fParams.fID);


if ( fJackClient )
{
jack_deactivate ( fJackClient );
if (fJackClient) {
jack_deactivate(fJackClient);
FreePorts(); FreePorts();
jack_client_close ( fJackClient );
jack_client_close(fJackClient);
} }
delete[] fAudioCapturePorts; delete[] fAudioCapturePorts;
delete[] fAudioPlaybackPorts; delete[] fAudioPlaybackPorts;
@@ -117,33 +112,33 @@ namespace Jack
{ {
//network init //network init
if (!JackNetMasterInterface::Init()) { if (!JackNetMasterInterface::Init()) {
jack_error("JackNetMasterInterface::Init() error..." );
jack_error("JackNetMasterInterface::Init() error...");
return false; return false;
} }


//set global parameters //set global parameters
if (!SetParams()) { if (!SetParams()) {
jack_error("SetParams error..." );
jack_error("SetParams error...");
return false; return false;
} }


//jack client and process //jack client and process
jack_status_t status; jack_status_t status;
if ( ( fJackClient = jack_client_open ( fClientName, JackNullOption, &status, NULL ) ) == NULL )
{
jack_error ( "Can't open a new jack client" );
if ((fJackClient = jack_client_open(fClientName, JackNullOption, &status, NULL)) == NULL) {
jack_error("Can't open a new JACK client");
return false; return false;
} }


if (jack_set_process_callback(fJackClient, SetProcess, this ) < 0)
goto fail;
if (jack_set_process_callback(fJackClient, SetProcess, this) < 0) {
goto fail;
}


if (jack_set_buffer_size_callback(fJackClient, SetBufferSize, this) < 0)
goto fail;
if (jack_set_buffer_size_callback(fJackClient, SetBufferSize, this) < 0) {
goto fail;
}


if ( AllocPorts() != 0 )
{
jack_error ( "Can't allocate jack ports" );
if (AllocPorts() != 0) {
jack_error("Can't allocate JACK ports");
goto fail; goto fail;
} }


@@ -151,20 +146,20 @@ namespace Jack
fRunning = true; fRunning = true;


//finally activate jack client //finally activate jack client
if ( jack_activate ( fJackClient ) != 0 )
{
jack_error ( "Can't activate jack client" );
if (jack_activate(fJackClient) != 0) {
jack_error("Can't activate JACK client");
goto fail; goto fail;
} }


if (auto_connect)
if (auto_connect) {
ConnectPorts(); ConnectPorts();
jack_info ( "New NetMaster started" );
}
jack_info("New NetMaster started");
return true; return true;


fail: fail:
FreePorts(); FreePorts();
jack_client_close ( fJackClient );
jack_client_close(fJackClient);
fJackClient = NULL; fJackClient = NULL;
return false; return false;
} }
@@ -174,76 +169,47 @@ namespace Jack
{ {
int i; int i;
char name[24]; char name[24];
jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient );
jack_nframes_t port_latency = jack_get_buffer_size(fJackClient);
jack_latency_range_t range; jack_latency_range_t range;


jack_log ( "JackNetMaster::AllocPorts" );
jack_log("JackNetMaster::AllocPorts");


//audio //audio
for ( i = 0; i < fParams.fSendAudioChannels; i++ )
{
sprintf ( name, "to_slave_%d", i+1 );
if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL )
for (i = 0; i < fParams.fSendAudioChannels; i++) {
sprintf(name, "to_slave_%d", i+1);
if ((fAudioCapturePorts[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0)) == NULL)
return -1; return -1;
//port latency //port latency
range.min = range.max = 0; range.min = range.max = 0;
jack_port_set_latency_range(fAudioCapturePorts[i], JackCaptureLatency, &range); jack_port_set_latency_range(fAudioCapturePorts[i], JackCaptureLatency, &range);
} }


for ( i = 0; i < fParams.fReturnAudioChannels; i++ )
{
sprintf ( name, "from_slave_%d", i+1 );
if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL )
for (i = 0; i < fParams.fReturnAudioChannels; i++) {
sprintf(name, "from_slave_%d", i+1);
if ((fAudioPlaybackPorts[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL)
return -1; return -1;
//port latency //port latency
switch ( fParams.fNetworkMode )
{
case 'f' :
range.min = range.max = (fParams.fSlaveSyncMode) ? 0 : port_latency;
jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range);
break;
case 'n' :
range.min = range.max = port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency;
jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range);
break;
case 's' :
range.min = range.max = 2 * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency;
jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range);
break;
}
range.min = range.max = fParams.fNetworkLatency * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency;
jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range);
} }


//midi //midi
for ( i = 0; i < fParams.fSendMidiChannels; i++ )
{
sprintf ( name, "midi_to_slave_%d", i+1 );
if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL )
for (i = 0; i < fParams.fSendMidiChannels; i++) {
sprintf(name, "midi_to_slave_%d", i+1);
if ((fMidiCapturePorts[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0)) == NULL)
return -1; return -1;
//port latency //port latency
range.min = range.max = 0; range.min = range.max = 0;
jack_port_set_latency_range(fMidiCapturePorts[i], JackCaptureLatency, &range); jack_port_set_latency_range(fMidiCapturePorts[i], JackCaptureLatency, &range);
} }
for ( i = 0; i < fParams.fReturnMidiChannels; i++ )
{
sprintf ( name, "midi_from_slave_%d", i+1 );
if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL )

for (i = 0; i < fParams.fReturnMidiChannels; i++) {
sprintf(name, "midi_from_slave_%d", i+1);
if ((fMidiPlaybackPorts[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL)
return -1; return -1;
//port latency //port latency
switch ( fParams.fNetworkMode )
{
case 'f' :
range.min = range.max = (fParams.fSlaveSyncMode) ? 0 : port_latency;
jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range);
break;
case 'n' :
range.min = range.max = port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency;
jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range);
break;
case 's' :
range.min = range.max = 2 * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency;
jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range);
break;
}
range.min = range.max = fParams.fNetworkLatency * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency;
jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range);
} }
return 0; return 0;
} }
@@ -271,21 +237,29 @@ namespace Jack


void JackNetMaster::FreePorts() void JackNetMaster::FreePorts()
{ {
jack_log ( "JackNetMaster::FreePorts, ID %u", fParams.fID );
jack_log("JackNetMaster::FreePorts ID = %u", fParams.fID);


int port_index; int port_index;
for ( port_index = 0; port_index < fParams.fSendAudioChannels; port_index++ )
if ( fAudioCapturePorts[port_index] )
jack_port_unregister ( fJackClient, fAudioCapturePorts[port_index] );
for ( port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++ )
if ( fAudioPlaybackPorts[port_index] )
jack_port_unregister ( fJackClient, fAudioPlaybackPorts[port_index] );
for ( port_index = 0; port_index < fParams.fSendMidiChannels; port_index++ )
if ( fMidiCapturePorts[port_index] )
jack_port_unregister ( fJackClient, fMidiCapturePorts[port_index] );
for ( port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++ )
if ( fMidiPlaybackPorts[port_index] )
jack_port_unregister ( fJackClient, fMidiPlaybackPorts[port_index] );
for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) {
if (fAudioCapturePorts[port_index]) {
jack_port_unregister(fJackClient, fAudioCapturePorts[port_index]);
}
}
for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) {
if (fAudioPlaybackPorts[port_index]) {
jack_port_unregister(fJackClient, fAudioPlaybackPorts[port_index]);
}
}
for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) {
if (fMidiCapturePorts[port_index]) {
jack_port_unregister(fJackClient, fMidiCapturePorts[port_index]);
}
}
for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) {
if (fMidiPlaybackPorts[port_index]) {
jack_port_unregister(fJackClient, fMidiPlaybackPorts[port_index]);
}
}
} }


//transport--------------------------------------------------------------------------- //transport---------------------------------------------------------------------------
@@ -296,26 +270,26 @@ namespace Jack
fSendTransportData.fTimebaseMaster = NO_CHANGE; fSendTransportData.fTimebaseMaster = NO_CHANGE;


//update state and position //update state and position
fSendTransportData.fState = static_cast<uint> ( jack_transport_query ( fJackClient, &fSendTransportData.fPosition ) );
fSendTransportData.fState = static_cast<uint>(jack_transport_query(fJackClient, &fSendTransportData.fPosition));


//is it a new state ? //is it a new state ?
fSendTransportData.fNewState = ( ( fSendTransportData.fState != fLastTransportState ) &&
( fSendTransportData.fState != fReturnTransportData.fState ) );
if ( fSendTransportData.fNewState )
jack_info ( "Sending '%s' to '%s' frame = %ld", GetTransportState ( fSendTransportData.fState ), fParams.fName, fSendTransportData.fPosition.frame );
fSendTransportData.fNewState = ((fSendTransportData.fState != fLastTransportState) && (fSendTransportData.fState != fReturnTransportData.fState));
if (fSendTransportData.fNewState) {
jack_info("Sending '%s' to '%s' frame = %ld", GetTransportState(fSendTransportData.fState), fParams.fName, fSendTransportData.fPosition.frame);
}
fLastTransportState = fSendTransportData.fState; fLastTransportState = fSendTransportData.fState;
} }


void JackNetMaster::DecodeTransportData() void JackNetMaster::DecodeTransportData()
{ {
//is there timebase master change ? //is there timebase master change ?
if ( fReturnTransportData.fTimebaseMaster != NO_CHANGE )
{
if (fReturnTransportData.fTimebaseMaster != NO_CHANGE) {
int timebase = 0; int timebase = 0;
switch ( fReturnTransportData.fTimebaseMaster )
switch (fReturnTransportData.fTimebaseMaster)
{ {
case RELEASE_TIMEBASEMASTER : case RELEASE_TIMEBASEMASTER :
timebase = jack_release_timebase ( fJackClient );
timebase = jack_release_timebase(fJackClient);
if (timebase < 0) { if (timebase < 0) {
jack_error("Can't release timebase master"); jack_error("Can't release timebase master");
} else { } else {
@@ -324,7 +298,7 @@ namespace Jack
break; break;


case TIMEBASEMASTER : case TIMEBASEMASTER :
timebase = jack_set_timebase_callback ( fJackClient, 0, SetTimebaseCallback, this );
timebase = jack_set_timebase_callback(fJackClient, 0, SetTimebaseCallback, this);
if (timebase < 0) { if (timebase < 0) {
jack_error("Can't set a new timebase master"); jack_error("Can't set a new timebase master");
} else { } else {
@@ -333,7 +307,7 @@ namespace Jack
break; break;


case CONDITIONAL_TIMEBASEMASTER : case CONDITIONAL_TIMEBASEMASTER :
timebase = jack_set_timebase_callback ( fJackClient, 1, SetTimebaseCallback, this );
timebase = jack_set_timebase_callback(fJackClient, 1, SetTimebaseCallback, this);
if (timebase != EBUSY) { if (timebase != EBUSY) {
if (timebase < 0) if (timebase < 0)
jack_error("Can't set a new timebase master"); jack_error("Can't set a new timebase master");
@@ -345,39 +319,39 @@ namespace Jack
} }


//is the slave in a new transport state and is this state different from master's ? //is the slave in a new transport state and is this state different from master's ?
if ( fReturnTransportData.fNewState && ( fReturnTransportData.fState != jack_transport_query ( fJackClient, NULL ) ) )
{
switch ( fReturnTransportData.fState )
if (fReturnTransportData.fNewState && (fReturnTransportData.fState != jack_transport_query(fJackClient, NULL))) {
switch (fReturnTransportData.fState)
{ {
case JackTransportStopped : case JackTransportStopped :
jack_transport_stop ( fJackClient );
jack_info ( "'%s' stops transport", fParams.fName );
jack_transport_stop(fJackClient);
jack_info("'%s' stops transport", fParams.fName);
break; break;


case JackTransportStarting : case JackTransportStarting :
if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) == EINVAL )
jack_error ( "Can't set new position" );
jack_transport_start ( fJackClient );
jack_info ( "'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame);
if (jack_transport_reposition(fJackClient, &fReturnTransportData.fPosition) == EINVAL)
jack_error("Can't set new position");
jack_transport_start(fJackClient);
jack_info("'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame);
break; break;


case JackTransportNetStarting : case JackTransportNetStarting :
jack_info ( "'%s' is ready to roll...", fParams.fName );
jack_info("'%s' is ready to roll...", fParams.fName);
break; break;


case JackTransportRolling : case JackTransportRolling :
jack_info ( "'%s' is rolling", fParams.fName );
jack_info("'%s' is rolling", fParams.fName);
break; break;
} }
} }
} }


void JackNetMaster::SetTimebaseCallback ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg )
void JackNetMaster::SetTimebaseCallback(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg)
{ {
static_cast<JackNetMaster*> ( arg )->TimebaseCallback ( pos );
static_cast<JackNetMaster*>(arg)->TimebaseCallback(pos);
} }


void JackNetMaster::TimebaseCallback ( jack_position_t* pos )
void JackNetMaster::TimebaseCallback(jack_position_t* pos)
{ {
pos->bar = fReturnTransportData.fPosition.bar; pos->bar = fReturnTransportData.fPosition.bar;
pos->beat = fReturnTransportData.fPosition.beat; pos->beat = fReturnTransportData.fPosition.beat;
@@ -393,7 +367,7 @@ namespace Jack


bool JackNetMaster::IsSlaveReadyToRoll() bool JackNetMaster::IsSlaveReadyToRoll()
{ {
return ( fReturnTransportData.fState == JackTransportNetStarting );
return (fReturnTransportData.fState == JackTransportNetStarting);
} }


int JackNetMaster::SetBufferSize(jack_nframes_t nframes, void* arg) int JackNetMaster::SetBufferSize(jack_nframes_t nframes, void* arg)
@@ -420,8 +394,9 @@ namespace Jack
{ {
int res; int res;


if (!fRunning)
if (!fRunning) {
return 0; return 0;
}


#ifdef JACK_MONITOR #ifdef JACK_MONITOR
jack_time_t begin_time = GetMicroSeconds(); jack_time_t begin_time = GetMicroSeconds();
@@ -437,11 +412,12 @@ namespace Jack
for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {


#ifdef OPTIMIZED_PROTOCOL #ifdef OPTIMIZED_PROTOCOL
if ((intptr_t)fNetAudioCaptureBuffer->GetBuffer(audio_port_index) == -1) {
if (fNetAudioCaptureBuffer->GetConnected(audio_port_index)) {
// Port is connected on other side... // Port is connected on other side...
fNetAudioCaptureBuffer->SetBuffer(audio_port_index, fNetAudioCaptureBuffer->SetBuffer(audio_port_index,
static_cast<sample_t*>(jack_port_get_buffer_nulled(fAudioCapturePorts[audio_port_index],
fParams.fPeriodSize)));
((jack_port_connected(fAudioCapturePorts[audio_port_index]) > 0)
? static_cast<sample_t*>(jack_port_get_buffer(fAudioCapturePorts[audio_port_index], fParams.fPeriodSize))
: NULL));
} else { } else {
fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL); fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL);
} }
@@ -461,13 +437,19 @@ namespace Jack
for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) { for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {


#ifdef OPTIMIZED_PROTOCOL #ifdef OPTIMIZED_PROTOCOL
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index,
static_cast<sample_t*>(jack_port_get_buffer_nulled(fAudioPlaybackPorts[audio_port_index],
fParams.fPeriodSize)));
sample_t* out = (jack_port_connected(fAudioPlaybackPorts[audio_port_index]) > 0)
? static_cast<sample_t*>(jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index], fParams.fPeriodSize))
: NULL;
if (out) {
memset(out, 0, sizeof(float) * fParams.fPeriodSize);
}
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out);
#else #else
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index,
static_cast<sample_t*>(jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index],
fParams.fPeriodSize)));
sample_t* out = static_cast<sample_t*>(jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index], fParams.fPeriodSize));
if (out) {
memset(out, 0, sizeof(float) * fParams.fPeriodSize);
}
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out)));
#endif #endif
} }


@@ -476,19 +458,21 @@ namespace Jack
//encode the first packet //encode the first packet
EncodeSyncPacket(); EncodeSyncPacket();


if (SyncSend() == SOCKET_ERROR)
if (SyncSend() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
}


#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fNetTimeMon->Add((((float) (GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs ) * 100.f);
fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
#endif #endif


//send data //send data
if (DataSend() == SOCKET_ERROR)
if (DataSend() == SOCKET_ERROR) {
return SOCKET_ERROR; return SOCKET_ERROR;
}


#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fNetTimeMon->Add((((float) (GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
#endif #endif


} else { } else {
@@ -497,8 +481,9 @@ namespace Jack


//receive sync //receive sync
res = SyncRecv(); res = SyncRecv();
if ((res == 0) || (res == SOCKET_ERROR))
if ((res == 0) || (res == SOCKET_ERROR)) {
return res; return res;
}


/* /*
switch (SyncRecv()) { switch (SyncRecv()) {
@@ -521,7 +506,7 @@ namespace Jack
*/ */


#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fNetTimeMon->Add ((((float) (GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
#endif #endif


//decode sync //decode sync
@@ -532,7 +517,7 @@ namespace Jack
if ((res == 0) || (res == SOCKET_ERROR)) { if ((res == 0) || (res == SOCKET_ERROR)) {
return res; return res;
} else if (res == NET_PACKET_ERROR) { } else if (res == NET_PACKET_ERROR) {
// Well not a real XRun, but...
// Well not a real XRun...
JackServerGlobals::fInstance->GetEngine()->NotifyXRun(GetMicroSeconds(), 0); JackServerGlobals::fInstance->GetEngine()->NotifyXRun(GetMicroSeconds(), 0);
} }


@@ -557,19 +542,19 @@ namespace Jack
*/ */


#ifdef JACK_MONITOR #ifdef JACK_MONITOR
fNetTimeMon->AddLast((((float) (GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
fNetTimeMon->AddLast((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
#endif #endif
return 0; return 0;
} }


//JackNetMasterManager*********************************************************************************************** //JackNetMasterManager***********************************************************************************************


JackNetMasterManager::JackNetMasterManager ( jack_client_t* client, const JSList* params ) : fSocket()
JackNetMasterManager::JackNetMasterManager(jack_client_t* client, const JSList* params) : fSocket()
{ {
jack_log ( "JackNetMasterManager::JackNetMasterManager" );
jack_log("JackNetMasterManager::JackNetMasterManager");


fManagerClient = client; fManagerClient = client;
fManagerName = jack_get_client_name ( fManagerClient );
fManagerName = jack_get_client_name(fManagerClient);
fGlobalID = 0; fGlobalID = 0;
fRunning = true; fRunning = true;
fAutoConnect = false; fAutoConnect = false;
@@ -588,20 +573,21 @@ namespace Jack
strcpy(fMulticastIP, DEFAULT_MULTICAST_IP); strcpy(fMulticastIP, DEFAULT_MULTICAST_IP);
} }


for ( node = params; node; node = jack_slist_next ( node ) )
{
param = ( const jack_driver_param_t* ) node->data;
switch ( param->character )
for (node = params; node; node = jack_slist_next(node)) {
param = (const jack_driver_param_t*) node->data;
switch (param->character)
{ {
case 'a' : case 'a' :
if (strlen (param->value.str) < 32)
if (strlen(param->value.str) < 32) {
strcpy(fMulticastIP, param->value.str); strcpy(fMulticastIP, param->value.str);
else
} else {
jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP); jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP);
}
break; break;


case 'p': case 'p':
fSocket.SetPort ( param->value.ui );
fSocket.SetPort(param->value.ui);
break; break;


case 'c': case 'c':
@@ -611,26 +597,29 @@ namespace Jack
} }


//set sync callback //set sync callback
jack_set_sync_callback ( fManagerClient, SetSyncCallback, this );
jack_set_sync_callback(fManagerClient, SetSyncCallback, this);


//activate the client (for sync callback) //activate the client (for sync callback)
if ( jack_activate ( fManagerClient ) != 0 )
jack_error ( "Can't activate the network manager client, transport disabled" );
if (jack_activate(fManagerClient) != 0) {
jack_error("Can't activate the NetManager client, transport disabled");
}


//launch the manager thread //launch the manager thread
if ( jack_client_create_thread ( fManagerClient, &fManagerThread, 0, 0, NetManagerThread, this ) )
jack_error ( "Can't create the network manager control thread" );
if (jack_client_create_thread(fManagerClient, &fManagerThread, 0, 0, NetManagerThread, this)) {
jack_error("Can't create the NetManager control thread");
}
} }


JackNetMasterManager::~JackNetMasterManager() JackNetMasterManager::~JackNetMasterManager()
{ {
jack_log ( "JackNetMasterManager::~JackNetMasterManager" );
jack_info ( "Exiting net manager..." );
jack_log("JackNetMasterManager::~JackNetMasterManager");
jack_info("Exiting NetManager...");
fRunning = false; fRunning = false;
jack_client_kill_thread ( fManagerClient, fManagerThread );
jack_client_kill_thread(fManagerClient, fManagerThread);
master_list_t::iterator it; master_list_t::iterator it;
for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
delete ( *it );
for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
delete(*it);
}
fSocket.Close(); fSocket.Close();
SocketAPIEnd(); SocketAPIEnd();
} }
@@ -653,35 +642,37 @@ namespace Jack
return count; return count;
} }


int JackNetMasterManager::SetSyncCallback ( jack_transport_state_t state, jack_position_t* pos, void* arg )
int JackNetMasterManager::SetSyncCallback(jack_transport_state_t state, jack_position_t* pos, void* arg)
{ {
return static_cast<JackNetMasterManager*> ( arg )->SyncCallback ( state, pos );
return static_cast<JackNetMasterManager*>(arg)->SyncCallback(state, pos);
} }


int JackNetMasterManager::SyncCallback ( jack_transport_state_t state, jack_position_t* pos )
int JackNetMasterManager::SyncCallback(jack_transport_state_t state, jack_position_t* pos)
{ {
//check if each slave is ready to roll //check if each slave is ready to roll
int ret = 1; int ret = 1;
master_list_it_t it; master_list_it_t it;
for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
if ( ! ( *it )->IsSlaveReadyToRoll() )
for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
if (!(*it)->IsSlaveReadyToRoll()) {
ret = 0; ret = 0;
jack_log ( "JackNetMasterManager::SyncCallback returns '%s'", ( ret ) ? "true" : "false" );
}
}
jack_log("JackNetMasterManager::SyncCallback returns '%s'", (ret) ? "true" : "false");
return ret; return ret;
} }


void* JackNetMasterManager::NetManagerThread ( void* arg )
void* JackNetMasterManager::NetManagerThread(void* arg)
{ {
JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*> ( arg );
jack_info ( "Starting Jack Network Manager" );
jack_info ( "Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort() );
JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*>(arg);
jack_info("Starting Jack NetManager");
jack_info("Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort());
master_manager->Run(); master_manager->Run();
return NULL; return NULL;
} }


void JackNetMasterManager::Run() void JackNetMasterManager::Run()
{ {
jack_log ( "JackNetMasterManager::Run" );
jack_log("JackNetMasterManager::Run");
//utility variables //utility variables
int attempt = 0; int attempt = 0;


@@ -691,75 +682,75 @@ namespace Jack
JackNetMaster* net_master; JackNetMaster* net_master;


//init socket API (win32) //init socket API (win32)
if ( SocketAPIInit() < 0 )
{
jack_error ( "Can't init Socket API, exiting..." );
if (SocketAPIInit() < 0) {
jack_error("Can't init Socket API, exiting...");
return; return;
} }


//socket //socket
if ( fSocket.NewSocket() == SOCKET_ERROR )
{
jack_error ( "Can't create the network management input socket : %s", StrError ( NET_ERROR_CODE ) );
if (fSocket.NewSocket() == SOCKET_ERROR) {
jack_error("Can't create NetManager input socket : %s", StrError(NET_ERROR_CODE));
return; return;
} }


//bind the socket to the local port //bind the socket to the local port
if ( fSocket.Bind() == SOCKET_ERROR )
{
jack_error ( "Can't bind the network manager socket : %s", StrError ( NET_ERROR_CODE ) );
if (fSocket.Bind() == SOCKET_ERROR) {
jack_error("Can't bind NetManager socket : %s", StrError(NET_ERROR_CODE));
fSocket.Close(); fSocket.Close();
return; return;
} }


//join multicast group //join multicast group
if ( fSocket.JoinMCastGroup ( fMulticastIP ) == SOCKET_ERROR )
jack_error ( "Can't join multicast group : %s", StrError ( NET_ERROR_CODE ) );
if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE));
}


//local loop //local loop
if ( fSocket.SetLocalLoop() == SOCKET_ERROR )
jack_error ( "Can't set local loop : %s", StrError ( NET_ERROR_CODE ) );
if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE));
}


//set a timeout on the multicast receive (the thread can now be cancelled) //set a timeout on the multicast receive (the thread can now be cancelled)
if ( fSocket.SetTimeOut ( 2000000 ) == SOCKET_ERROR )
jack_error ( "Can't set timeout : %s", StrError ( NET_ERROR_CODE ) );
if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) {
jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
}


//main loop, wait for data, deal with it and wait again //main loop, wait for data, deal with it and wait again
do do
{ {
session_params_t net_params; session_params_t net_params;
rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 );
rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
SessionParamsNToH(&net_params, &host_params); SessionParamsNToH(&net_params, &host_params);
if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) )
{
jack_error ( "Error in receive : %s", StrError ( NET_ERROR_CODE ) );
if ( ++attempt == 10 )
{
jack_error ( "Can't receive on the socket, exiting net manager" );
if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
jack_error("Error in receive : %s", StrError(NET_ERROR_CODE));
if (++attempt == 10) {
jack_error("Can't receive on the socket, exiting net manager");
return; return;
} }
} }
if ( rx_bytes == sizeof ( session_params_t ) )
{
switch ( GetPacketType ( &host_params ) )
if (rx_bytes == sizeof(session_params_t)) {
switch (GetPacketType (&host_params))
{ {
case SLAVE_AVAILABLE: case SLAVE_AVAILABLE:
if ( ( net_master = InitMaster ( host_params ) ) )
SessionParamsDisplay ( &net_master->fParams );
else
jack_error ( "Can't init new net master..." );
jack_info ( "Waiting for a slave..." );
if ((net_master = InitMaster(host_params))) {
SessionParamsDisplay(&net_master->fParams);
} else {
jack_error("Can't init new NetMaster...");
}
jack_info("Waiting for a slave...");
break; break;
case KILL_MASTER: case KILL_MASTER:
if ( KillMaster ( &host_params ) )
jack_info ( "Waiting for a slave..." );
if (KillMaster(&host_params)) {
jack_info("Waiting for a slave...");
}
break; break;
default: default:
break; break;
} }
} }
} }
while ( fRunning );
while (fRunning);
} }


JackNetMaster* JackNetMasterManager::InitMaster(session_params_t& params) JackNetMaster* JackNetMasterManager::InitMaster(session_params_t& params)
@@ -768,15 +759,15 @@ namespace Jack


//check MASTER <<==> SLAVE network protocol coherency //check MASTER <<==> SLAVE network protocol coherency
if (params.fProtocolVersion != MASTER_PROTOCOL) { if (params.fProtocolVersion != MASTER_PROTOCOL) {
jack_error ( "Error : slave %s is running with a different protocol %d != %d", params.fName, params.fProtocolVersion, MASTER_PROTOCOL);
jack_error("Error : slave %s is running with a different protocol %d != %d", params.fName, params.fProtocolVersion, MASTER_PROTOCOL);
return NULL; return NULL;
} }


//settings //settings
fSocket.GetName ( params.fMasterNetName );
fSocket.GetName(params.fMasterNetName);
params.fID = ++fGlobalID; params.fID = ++fGlobalID;
params.fSampleRate = jack_get_sample_rate ( fManagerClient );
params.fPeriodSize = jack_get_buffer_size ( fManagerClient );
params.fSampleRate = jack_get_sample_rate(fManagerClient);
params.fPeriodSize = jack_get_buffer_size(fManagerClient);


if (params.fSendAudioChannels == -1) { if (params.fSendAudioChannels == -1) {
params.fSendAudioChannels = CountIO(JackPortIsPhysical | JackPortIsOutput); params.fSendAudioChannels = CountIO(JackPortIsPhysical | JackPortIsOutput);
@@ -800,35 +791,38 @@ namespace Jack
return NULL; return NULL;
} }


void JackNetMasterManager::SetSlaveName ( session_params_t& params )
void JackNetMasterManager::SetSlaveName(session_params_t& params)
{ {
jack_log ( "JackNetMasterManager::SetSlaveName" );
jack_log("JackNetMasterManager::SetSlaveName");


master_list_it_t it; master_list_it_t it;
for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
if ( strcmp ( ( *it )->fParams.fName, params.fName ) == 0 )
sprintf ( params.fName, "%s-%u", params.fName, params.fID );
for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
if (strcmp((*it)->fParams.fName, params.fName) == 0) {
sprintf(params.fName, "%s-%u", params.fName, params.fID);
}
}
} }


master_list_it_t JackNetMasterManager::FindMaster ( uint32_t id )
master_list_it_t JackNetMasterManager::FindMaster(uint32_t id)
{ {
jack_log ( "JackNetMasterManager::FindMaster, ID %u", id );
jack_log("JackNetMasterManager::FindMaster ID = %u", id);


master_list_it_t it; master_list_it_t it;
for ( it = fMasterList.begin(); it != fMasterList.end(); it++ )
if ( ( *it )->fParams.fID == id )
for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
if ((*it)->fParams.fID == id) {
return it; return it;
}
}
return it; return it;
} }


int JackNetMasterManager::KillMaster ( session_params_t* params )
int JackNetMasterManager::KillMaster(session_params_t* params)
{ {
jack_log ( "JackNetMasterManager::KillMaster, ID %u", params->fID );
jack_log("JackNetMasterManager::KillMaster ID = %u", params->fID);


master_list_it_t master = FindMaster ( params->fID );
if ( master != fMasterList.end() )
{
fMasterList.erase ( master );
master_list_it_t master = FindMaster(params->fID);
if (master != fMasterList.end()) {
fMasterList.erase(master);
delete *master; delete *master;
return 1; return 1;
} }
@@ -851,7 +845,7 @@ extern "C"


desc = jack_driver_descriptor_construct("netmanager", "netjack multi-cast master component", &filler); desc = jack_driver_descriptor_construct("netmanager", "netjack multi-cast master component", &filler);


strcpy(value.str, DEFAULT_MULTICAST_IP );
strcpy(value.str, DEFAULT_MULTICAST_IP);
jack_driver_descriptor_add_parameter(desc, &filler, "multicast_ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "multicast_ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL);


value.i = DEFAULT_PORT; value.i = DEFAULT_PORT;
@@ -863,48 +857,46 @@ extern "C"
return desc; return desc;
} }


SERVER_EXPORT int jack_internal_initialize ( jack_client_t* jack_client, const JSList* params )
SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params)
{ {
if ( master_manager )
{
jack_error ( "Master Manager already loaded" );
if (master_manager) {
jack_error("Master Manager already loaded");
return 1; return 1;
}
else
{
jack_log ( "Loading Master Manager" );
master_manager = new Jack::JackNetMasterManager ( jack_client, params );
return ( master_manager ) ? 0 : 1;
} else {
jack_log("Loading Master Manager");
master_manager = new Jack::JackNetMasterManager(jack_client, params);
return (master_manager) ? 0 : 1;
} }
} }


SERVER_EXPORT int jack_initialize ( jack_client_t* jack_client, const char* load_init )
SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init)
{ {
JSList* params = NULL; JSList* params = NULL;
bool parse_params = true; bool parse_params = true;
int res = 1; int res = 1;
jack_driver_desc_t* desc = jack_get_descriptor(); jack_driver_desc_t* desc = jack_get_descriptor();


Jack::JackArgParser parser ( load_init );
if ( parser.GetArgc() > 0 )
parse_params = parser.ParseParams ( desc, &params );
Jack::JackArgParser parser(load_init);
if (parser.GetArgc() > 0) {
parse_params = parser.ParseParams(desc, &params);
}


if (parse_params) { if (parse_params) {
res = jack_internal_initialize ( jack_client, params );
parser.FreeParams ( params );
res = jack_internal_initialize(jack_client, params);
parser.FreeParams(params);
} }
return res; return res;
} }


SERVER_EXPORT void jack_finish ( void* arg )
SERVER_EXPORT void jack_finish(void* arg)
{ {
if ( master_manager )
{
jack_log ( "Unloading Master Manager" );
if (master_manager) {
jack_log ("Unloading Master Manager");
delete master_manager; delete master_manager;
master_manager = NULL; master_manager = NULL;
} }
} }

#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

+ 15
- 15
common/JackNetManager.h View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2008 Grame
Copyright (C) 2008-2011 Romain Moret at Grame


This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -40,9 +40,9 @@ namespace Jack


private: private:


static int SetProcess ( jack_nframes_t nframes, void* arg );
static int SetBufferSize (jack_nframes_t nframes, void* arg);
static void SetTimebaseCallback ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg );
static int SetProcess(jack_nframes_t nframes, void* arg);
static int SetBufferSize(jack_nframes_t nframes, void* arg);
static void SetTimebaseCallback(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg);


//jack client //jack client
jack_client_t* fJackClient; jack_client_t* fJackClient;
@@ -72,13 +72,13 @@ namespace Jack
void DecodeTransportData(); void DecodeTransportData();


int Process(); int Process();
void TimebaseCallback ( jack_position_t* pos );
void TimebaseCallback(jack_position_t* pos);
void ConnectPorts(); void ConnectPorts();


public: public:


JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip);
~JackNetMaster ();
JackNetMaster(JackNetSocket& socket, session_params_t& params, const char* multicast_ip);
~JackNetMaster();


bool IsSlaveReadyToRoll(); bool IsSlaveReadyToRoll();
}; };
@@ -96,8 +96,8 @@ namespace Jack


private: private:


static int SetSyncCallback ( jack_transport_state_t state, jack_position_t* pos, void* arg );
static void* NetManagerThread ( void* arg );
static int SetSyncCallback(jack_transport_state_t state, jack_position_t* pos, void* arg);
static void* NetManagerThread(void* arg);


jack_client_t* fManagerClient; jack_client_t* fManagerClient;
const char* fManagerName; const char* fManagerName;
@@ -110,18 +110,18 @@ namespace Jack
bool fAutoConnect; bool fAutoConnect;


void Run(); void Run();
JackNetMaster* InitMaster ( session_params_t& params );
master_list_it_t FindMaster ( uint32_t client_id );
int KillMaster ( session_params_t* params );
void SetSlaveName ( session_params_t& params );
JackNetMaster* InitMaster(session_params_t& params);
master_list_it_t FindMaster(uint32_t client_id);
int KillMaster(session_params_t* params);
void SetSlaveName(session_params_t& params);


int SyncCallback ( jack_transport_state_t state, jack_position_t* pos );
int SyncCallback(jack_transport_state_t state, jack_position_t* pos);


int CountIO(int flags); int CountIO(int flags);


public: public:


JackNetMasterManager ( jack_client_t* jack_client, const JSList* params);
JackNetMasterManager(jack_client_t* jack_client, const JSList* params);
~JackNetMasterManager(); ~JackNetMasterManager();
}; };
} }


+ 16
- 29
common/JackNetOneDriver.cpp View File

@@ -1,6 +1,5 @@
/* /*
Copyright (C) 2001 Paul Davis
Copyright (C) 2008-2011 Romain Moret at Grame
Copyright (C) 2008-2011 Torben Horn


This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -46,21 +45,21 @@ using namespace std;


namespace Jack namespace Jack
{ {
JackNetOneDriver::JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
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 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, int sample_rate, int period_size, int resample_factor,
const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, 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 )
int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val)
: JackTimedDriver(name, alias, engine, table)
{ {
jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port );
jack_log("JackNetOneDriver::JackNetOneDriver port %d", port);


#ifdef WIN32 #ifdef WIN32
WSADATA wsa; WSADATA wsa;
int rc = WSAStartup(MAKEWORD(2, 0), &wsa); int rc = WSAStartup(MAKEWORD(2, 0), &wsa);
#endif #endif


netjack_init( & (this->netj),
netjack_init(& (this->netj),
NULL, // client NULL, // client
name, name,
capture_ports, capture_ports,
@@ -88,28 +87,11 @@ JackNetOneDriver::~JackNetOneDriver()
} }


//open, close, attach and detach------------------------------------------------------ //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 )
{
return JackAudioDriver::Open(buffer_size,
samplerate,
capturing,
playing,
inchannels,
outchannels,
monitor,
capture_driver_name,
playback_driver_name,
capture_latency,
playback_latency);
}


int JackNetOneDriver::Close() int JackNetOneDriver::Close()
{ {
// Generic audio driver close // Generic audio driver close
int res = JackAudioDriver::Close();
int res = JackTimedDriver::Close();


FreePorts(); FreePorts();
netjack_release(&netj); netjack_release(&netj);
@@ -254,8 +236,8 @@ bool JackNetOneDriver::Initialize()


//monitor //monitor
//driver parametering //driver parametering
JackAudioDriver::SetBufferSize ( netj.period_size );
JackAudioDriver::SetSampleRate ( netj.sample_rate );
JackTimedDriver::SetBufferSize ( netj.period_size );
JackTimedDriver::SetSampleRate ( netj.sample_rate );


JackDriver::NotifyBufferSize ( netj.period_size ); JackDriver::NotifyBufferSize ( netj.period_size );
JackDriver::NotifySampleRate ( netj.sample_rate ); JackDriver::NotifySampleRate ( netj.sample_rate );
@@ -269,6 +251,12 @@ bool JackNetOneDriver::Initialize()
//jack ports and buffers-------------------------------------------------------------- //jack ports and buffers--------------------------------------------------------------


//driver processes-------------------------------------------------------------------- //driver processes--------------------------------------------------------------------
int JackNetOneDriver::Process()
{
return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
}
int JackNetOneDriver::Read() int JackNetOneDriver::Read()
{ {
int delay; int delay;
@@ -951,8 +939,7 @@ extern "C"
} }


try { try {
Jack::JackDriverClientInterface* driver =
new Jack::JackWaitThreadedDriver (
Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver (
new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu,
capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, capture_ports_midi, playback_ports_midi, capture_ports, playback_ports,
sample_rate, period_size, resample_factor, sample_rate, period_size, resample_factor,


+ 12
- 12
common/JackNetOneDriver.h View File

@@ -1,6 +1,5 @@
/* /*
Copyright (C) 2001 Paul Davis
Copyright (C) 2008-2011 Romain Moret at Grame
Copyright (C) 2008-2011 Torben Horn


This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -21,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifndef __JackNetDriver__ #ifndef __JackNetDriver__
#define __JackNetDriver__ #define __JackNetDriver__


#include "JackAudioDriver.h"
#include "JackTimedDriver.h"
#include "netjack.h" #include "netjack.h"
#include "netjack_packet.h" #include "netjack_packet.h"


@@ -31,7 +30,7 @@ namespace Jack
\Brief This class describes the Net Backend \Brief This class describes the Net Backend
*/ */


class JackNetOneDriver : public JackAudioDriver
class JackNetOneDriver : public JackTimedDriver
{ {
private: private:


@@ -59,15 +58,13 @@ class JackNetOneDriver : public JackAudioDriver
int sample_rate, int period_size, int resample_factor, int sample_rate, int period_size, int resample_factor,
const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, 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); 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);
virtual ~JackNetOneDriver();


int Close(); int Close();
int Attach(); int Attach();
int Detach(); int Detach();
int Process();


int Read(); int Read();
int Write(); int Write();
@@ -77,15 +74,18 @@ class JackNetOneDriver : public JackAudioDriver
void FreePorts(); void FreePorts();


// BufferSize can't be changed // BufferSize can't be changed
bool IsFixedBufferSize() {
bool IsFixedBufferSize()
{
return true; return true;
} }


int SetBufferSize(jack_nframes_t buffer_size) {
int SetBufferSize(jack_nframes_t buffer_size)
{
return -1; return -1;
} }


int SetSampleRate(jack_nframes_t sample_rate) {
int SetSampleRate(jack_nframes_t sample_rate)
{
return -1; return -1;
} }




+ 368
- 244
common/JackNetTool.cpp View File

@@ -97,12 +97,14 @@ namespace Jack
fMaxPcktSize = params->fMtu - sizeof(packet_header_t); fMaxPcktSize = params->fMtu - sizeof(packet_header_t);
fBuffer = new char[fMaxBufsize]; fBuffer = new char[fMaxBufsize];
fPortBuffer = new JackMidiBuffer* [fNPorts]; fPortBuffer = new JackMidiBuffer* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
fPortBuffer[port_index] = NULL; fPortBuffer[port_index] = NULL;
}
fNetBuffer = net_buffer; fNetBuffer = net_buffer;


fCycleSize = params->fMtu * (max(params->fSendMidiChannels, params->fReturnMidiChannels) *
params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t)));
fCycleBytesSize = params->fMtu
* (max(params->fSendMidiChannels, params->fReturnMidiChannels)
* params->fPeriodSize * sizeof(sample_t) / (params->fMtu - sizeof(packet_header_t)));
} }


NetMidiBuffer::~NetMidiBuffer() NetMidiBuffer::~NetMidiBuffer()
@@ -113,14 +115,14 @@ namespace Jack


size_t NetMidiBuffer::GetCycleSize() size_t NetMidiBuffer::GetCycleSize()
{ {
return fCycleSize;
return fCycleBytesSize;
} }


int NetMidiBuffer::GetNumPackets(int data_size, int max_size) int NetMidiBuffer::GetNumPackets(int data_size, int max_size)
{ {
return (data_size % max_size)
? (data_size / max_size + 1)
: data_size / max_size;
int res1 = data_size % max_size;
int res2 = data_size / max_size;
return (res1) ? res2 + 1 : res2;
} }


void NetMidiBuffer::SetBuffer(int index, JackMidiBuffer* buffer) void NetMidiBuffer::SetBuffer(int index, JackMidiBuffer* buffer)
@@ -137,10 +139,11 @@ namespace Jack
{ {
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
for (uint event = 0; event < fPortBuffer[port_index]->event_count; event++) { for (uint event = 0; event < fPortBuffer[port_index]->event_count; event++) {
if (fPortBuffer[port_index]->IsValid())
if (fPortBuffer[port_index]->IsValid()) {
jack_info("port %d : midi event %u/%u -> time : %u, size : %u", jack_info("port %d : midi event %u/%u -> time : %u, size : %u",
port_index + 1, event + 1, fPortBuffer[port_index]->event_count, port_index + 1, event + 1, fPortBuffer[port_index]->event_count,
fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size); fPortBuffer[port_index]->events[event].time, fPortBuffer[port_index]->events[event].size);
}
} }
} }
} }
@@ -155,8 +158,9 @@ namespace Jack
copy_size = sizeof(JackMidiBuffer) + fPortBuffer[port_index]->event_count * sizeof(JackMidiEvent); copy_size = sizeof(JackMidiBuffer) + fPortBuffer[port_index]->event_count * sizeof(JackMidiEvent);
memcpy(fBuffer + pos, fPortBuffer[port_index], copy_size); memcpy(fBuffer + pos, fPortBuffer[port_index], copy_size);
pos += copy_size; pos += copy_size;
memcpy(fBuffer + pos, fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos),
fPortBuffer[port_index]->write_pos);
memcpy(fBuffer + pos,
fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos),
fPortBuffer[port_index]->write_pos);
pos += fPortBuffer[port_index]->write_pos; pos += fPortBuffer[port_index]->write_pos;


JackMidiBuffer* midi_buffer = reinterpret_cast<JackMidiBuffer*>(write_pos); JackMidiBuffer* midi_buffer = reinterpret_cast<JackMidiBuffer*>(write_pos);
@@ -168,7 +172,7 @@ namespace Jack
void NetMidiBuffer::RenderToJackPorts() void NetMidiBuffer::RenderToJackPorts()
{ {
int pos = 0; int pos = 0;
int copy_size;
size_t copy_size;


for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
JackMidiBuffer* midi_buffer = reinterpret_cast<JackMidiBuffer*>(fBuffer + pos); JackMidiBuffer* midi_buffer = reinterpret_cast<JackMidiBuffer*>(fBuffer + pos);
@@ -177,7 +181,8 @@ namespace Jack
memcpy(fPortBuffer[port_index], fBuffer + pos, copy_size); memcpy(fPortBuffer[port_index], fBuffer + pos, copy_size);
pos += copy_size; pos += copy_size;
memcpy(fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos), memcpy(fPortBuffer[port_index] + (fPortBuffer[port_index]->buffer_size - fPortBuffer[port_index]->write_pos),
fBuffer + pos, fPortBuffer[port_index]->write_pos);
fBuffer + pos,
fPortBuffer[port_index]->write_pos);
pos += fPortBuffer[port_index]->write_pos; pos += fPortBuffer[port_index]->write_pos;
} }
} }
@@ -197,60 +202,277 @@ namespace Jack


// net audio buffer ********************************************************************************* // net audio buffer *********************************************************************************


NetAudioBuffer::NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
{
fNPorts = nports;
fNetBuffer = net_buffer;

fPortBuffer = new sample_t* [fNPorts];
fConnectedPorts = new bool[fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++) {
fPortBuffer[port_index] = NULL;
fConnectedPorts[port_index] = true;
}
}

NetAudioBuffer::~NetAudioBuffer()
{
delete [] fConnectedPorts;
delete [] fPortBuffer;
}

void NetAudioBuffer::SetBuffer(int index, sample_t* buffer)
{
fPortBuffer[index] = buffer;
}

sample_t* NetAudioBuffer::GetBuffer(int index)
{
return fPortBuffer[index];
}

int NetAudioBuffer::CheckPacket(int cycle, int sub_cycle)
{
int res;

if (sub_cycle != fLastSubCycle + 1) {
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
res = NET_PACKET_ERROR;
} else {
res = 0;
}

fLastSubCycle = sub_cycle;
return res;
}

void NetAudioBuffer::NextCycle()
{
// reset for next cycle
fLastSubCycle = -1;
}

void NetAudioBuffer::Cleanup()
{
for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) {
memset(fPortBuffer[port_index], 0, fPeriodSize * sizeof(sample_t));
}
}
}

//network<->buffer

int NetAudioBuffer::ActivePortsToNetwork(char* net_buffer)
{
int active_ports = 0;
int* active_port_address = (int*)net_buffer;

for (int port_index = 0; port_index < fNPorts; port_index++) {
// Write the active port number
if (fPortBuffer[port_index]) {
*active_port_address = port_index;
active_port_address++;
active_ports++;
assert(active_ports < 256);
}
}

return active_ports;
}

void NetAudioBuffer::ActivePortsFromNetwork(char* net_buffer, uint32_t port_num)
{
int* active_port_address = (int*)net_buffer;

for (int port_index = 0; port_index < fNPorts; port_index++) {
fConnectedPorts[port_index] = false;
}

for (uint port_index = 0; port_index < port_num; port_index++) {
// Use -1 when port is actually connected on other side
int active_port = *active_port_address;
if (active_port >= 0 && active_port < fNPorts) {
fConnectedPorts[active_port] = true;
} else {
jack_error("ActivePortsFromNetwork: incorrect port = %d", active_port);
}
active_port_address++;
}
}

int NetAudioBuffer::RenderFromJackPorts()
{
// Count active ports
int active_ports = 0;
for (int port_index = 0; port_index < fNPorts; port_index++) {

if (fPortBuffer[port_index]) {
active_ports++;
}
}
//jack_info("active_ports %d", active_ports);
return active_ports;
}

void NetAudioBuffer::RenderToJackPorts()
{
// Nothing to do
NextCycle();
}

// Float converter

NetFloatAudioBuffer::NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer) NetFloatAudioBuffer::NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
: fPortBuffer(params, nports), fNetBuffer(net_buffer)
{}
: NetAudioBuffer(params, nports, net_buffer)
{
fPeriodSize = params->fPeriodSize;
fPacketSize = PACKET_AVAILABLE_SIZE(params);

UpdateParams(max(params->fReturnAudioChannels, params->fSendAudioChannels));

fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t);

fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate);
fCycleBytesSize = params->fMtu * (fPeriodSize / fSubPeriodSize);

fLastSubCycle = -1;
}


NetFloatAudioBuffer::~NetFloatAudioBuffer() NetFloatAudioBuffer::~NetFloatAudioBuffer()
{} {}


// needed size in bytes for an entire cycle
size_t NetFloatAudioBuffer::GetCycleSize() size_t NetFloatAudioBuffer::GetCycleSize()
{ {
return fPortBuffer.GetCycleSize();
return fCycleBytesSize;
} }


void NetFloatAudioBuffer::SetBuffer(int index, sample_t* buffer)
// cycle duration in sec
float NetFloatAudioBuffer::GetCycleDuration()
{ {
fPortBuffer.SetBuffer(index, buffer);
return fCycleDuration;
} }


sample_t* NetFloatAudioBuffer::GetBuffer(int index)
void NetFloatAudioBuffer::UpdateParams(int active_ports)
{ {
return fPortBuffer.GetBuffer(index);
if (active_ports == 0) {
fSubPeriodSize = fPeriodSize;
} else {
jack_nframes_t period = (int) powf(2.f, (int)(log(float(fPacketSize) / (active_ports * sizeof(sample_t))) / log(2.)));
fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period;
}

fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t) + sizeof(int); // The port number in coded on 4 bytes
} }


void NetFloatAudioBuffer::RenderFromJackPorts()
int NetFloatAudioBuffer::GetNumPackets(int active_ports)
{ {
fPortBuffer.RenderFromJackPorts();
UpdateParams(active_ports);

/*
jack_log("GetNumPackets packet = %d fPeriodSize = %d fSubPeriodSize = %d fSubPeriodBytesSize = %d",
fPeriodSize / fSubPeriodSize, fPeriodSize, fSubPeriodSize, fSubPeriodBytesSize);
*/
return fPeriodSize / fSubPeriodSize; // At least one packet
} }


void NetFloatAudioBuffer::RenderToJackPorts()
//jack<->buffer

/*
int NetFloatAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{ {
fPortBuffer.RenderToJackPorts();
// Cleanup all JACK ports at the beginning of the cycle
if (sub_cycle == 0) {
Cleanup();
}

if (port_num > 0) {

/// Setup rendering parameters
int sub_period_size, sub_period_bytes_size;
if (port_num == 0) {
sub_period_size = fPeriodSize;
} else {
jack_nframes_t period = (int) powf(2.f, (int)(log(float(fPacketSize) / (port_num * sizeof(sample_t))) / log(2.)));
sub_period_size = (period > fPeriodSize) ? fPeriodSize : period;
}
sub_period_bytes_size = sub_period_size * sizeof(sample_t) + sizeof(uint32_t); // The port number in coded on 4 bytes

for (uint32_t port_index = 0; port_index < port_num; port_index++) {
// Only copy to active ports : read the active port number then audio data
uint32_t* active_port_address = (uint32_t*)(fNetBuffer + port_index * sub_period_bytes_size);
uint32_t active_port = (uint32_t)(*active_port_address);
printf("active_port %d\n", active_port);
if (fPortBuffer[active_port]) {
memcpy(fPortBuffer[active_port] + sub_cycle * sub_period_size, (char*)(active_port_address + 1), sub_period_bytes_size - sizeof(uint32_t));
//RenderFromNetwork((char*)(active_port_address + 1), active_port, sub_cycle, sub_period_bytes_size - sizeof(uint32_t));
}
}
}

return CheckPacket(cycle, sub_cycle);
} }
*/


//network<->buffer
int NetFloatAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
int NetFloatAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{ {
return fPortBuffer.RenderFromNetwork(fNetBuffer, cycle, sub_cycle, copy_size, port_num);
// Cleanup all JACK ports at the beginning of the cycle
if (sub_cycle == 0) {
Cleanup();
}

if (port_num > 0) {

UpdateParams(port_num);

for (uint32_t port_index = 0; port_index < port_num; port_index++) {
// Only copy to active ports : read the active port number then audio data
int* active_port_address = (int*)(fNetBuffer + port_index * fSubPeriodBytesSize);
int active_port = *active_port_address;
/*
if (fPortBuffer[active_port]) {
memcpy(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, (char*)(active_port_address + 1), fSubPeriodBytesSize - sizeof(uint32_t));
}
*/
RenderFromNetwork((char*)(active_port_address + 1), active_port, sub_cycle);
}
}

return CheckPacket(cycle, sub_cycle);
} }


int NetFloatAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t& port_num)

int NetFloatAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{ {
return fPortBuffer.RenderToNetwork(fNetBuffer, sub_cycle, port_num);
int active_ports = 0;

for (int port_index = 0; port_index < fNPorts; port_index++) {
// Only copy from active ports : write the active port number then audio data
if (fPortBuffer[port_index]) {
int* active_port_address = (int*)(fNetBuffer + active_ports * fSubPeriodBytesSize);
*active_port_address = port_index;
//memcpy((char*)(active_port_address + 1), fPortBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(uint32_t));
RenderToNetwork((char*)(active_port_address + 1), port_index, sub_cycle);
active_ports++;
}
}

return port_num * fSubPeriodBytesSize;
} }


void NetFloatAudioBuffer::ActivePortsToNetwork(char* net_buffer, uint32_t& port_num)
void NetFloatAudioBuffer::RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle)
{ {
fPortBuffer.ActivePortsToNetwork(net_buffer, port_num);
if (fPortBuffer[active_port]) {
memcpy(fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, net_buffer, fSubPeriodBytesSize - sizeof(int));
}
} }


void NetFloatAudioBuffer::ActivePortsFromNetwork(char* net_buffer, uint32_t port_num)
void NetFloatAudioBuffer::RenderToNetwork(char* net_buffer, int active_port, int sub_cycle)
{ {
fPortBuffer.ActivePortsFromNetwork(net_buffer, port_num);
memcpy(net_buffer, fPortBuffer[active_port] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(int));
} }



// Celt audio buffer ********************************************************************************* // Celt audio buffer *********************************************************************************


#if HAVE_CELT #if HAVE_CELT
@@ -259,13 +481,8 @@ namespace Jack
#define KPS_DIV 8 #define KPS_DIV 8


NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps) NetCeltAudioBuffer::NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps)
: fNetBuffer(net_buffer)
:NetAudioBuffer(params, nports, net_buffer)
{ {
int res1, res2;

fNPorts = nports;
fPeriodSize = params->fPeriodSize;

fCeltMode = new CELTMode *[fNPorts]; fCeltMode = new CELTMode *[fNPorts];
fCeltEncoder = new CELTEncoder *[fNPorts]; fCeltEncoder = new CELTEncoder *[fNPorts];
fCeltDecoder = new CELTDecoder *[fNPorts]; fCeltDecoder = new CELTDecoder *[fNPorts];
@@ -278,77 +495,84 @@ namespace Jack


for (int i = 0; i < fNPorts; i++) { for (int i = 0; i < fNPorts; i++) {
fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error); fCeltMode[i] = celt_mode_create(params->fSampleRate, params->fPeriodSize, &error);
if (error != CELT_OK)
if (error != CELT_OK) {
goto error; goto error;
}


#if HAVE_CELT_API_0_11 #if HAVE_CELT_API_0_11


fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error); fCeltEncoder[i] = celt_encoder_create_custom(fCeltMode[i], 1, &error);
if (error != CELT_OK)
if (error != CELT_OK) {
goto error; goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1)); celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));


fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error); fCeltDecoder[i] = celt_decoder_create_custom(fCeltMode[i], 1, &error);
if (error != CELT_OK)
if (error != CELT_OK) {
goto error; goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1)); celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));


#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8


fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error); fCeltEncoder[i] = celt_encoder_create(fCeltMode[i], 1, &error);
if (error != CELT_OK)
if (error != CELT_OK) {
goto error; goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1)); celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));


fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error); fCeltDecoder[i] = celt_decoder_create(fCeltMode[i], 1, &error);
if (error != CELT_OK)
if (error != CELT_OK) {
goto error; goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1)); celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));


#else #else


fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]); fCeltEncoder[i] = celt_encoder_create(fCeltMode[i]);
if (error != CELT_OK)
if (error != CELT_OK) {
goto error; goto error;
}
celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1)); celt_encoder_ctl(fCeltEncoder[i], CELT_SET_COMPLEXITY(1));


fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]); fCeltDecoder[i] = celt_decoder_create(fCeltMode[i]);
if (error != CELT_OK)
if (error != CELT_OK) {
goto error; goto error;
}
celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1)); celt_decoder_ctl(fCeltDecoder[i], CELT_SET_COMPLEXITY(1));


#endif #endif
} }


fPortBuffer = new sample_t* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++)
fPortBuffer[port_index] = NULL;

fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
{
fPeriodSize = params->fPeriodSize;


fCompressedBuffer = new unsigned char* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++)
fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte];
fCompressedSizeByte = (kbps * params->fPeriodSize * 1024) / (params->fSampleRate * 8);
jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);


jack_log("NetCeltAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);
fCompressedBuffer = new unsigned char* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++) {
fCompressedBuffer[port_index] = new unsigned char[fCompressedSizeByte];
}


res1 = (fNPorts * fCompressedSizeByte) % (params->fMtu - sizeof(packet_header_t));
res2 = (fNPorts * fCompressedSizeByte) / (params->fMtu - sizeof(packet_header_t));
int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);


fNumPackets = (res1) ? (res2 + 1) : res2;
fNumPackets = (res1) ? (res2 + 1) : res2;


jack_log("NetCeltAudioBuffer res1 = %d res2 = %d", res1, res2);
jack_log("NetCeltAudioBuffer res1 = %d res2 = %d", res1, res2);


fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;


jack_log("NetCeltAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
jack_log("NetCeltAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);


fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleSize = params->fMtu * fNumPackets;
fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleBytesSize = params->fMtu * fNumPackets;


fLastSubCycle = -1;
return;
fLastSubCycle = -1;
return;
}


error: error:


@@ -360,22 +584,25 @@ namespace Jack
{ {
FreeCelt(); FreeCelt();


for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
delete [] fCompressedBuffer[port_index]; delete [] fCompressedBuffer[port_index];
}


delete [] fCompressedBuffer; delete [] fCompressedBuffer;
delete [] fPortBuffer;
} }


void NetCeltAudioBuffer::FreeCelt() void NetCeltAudioBuffer::FreeCelt()
{ {
for (int i = 0; i < fNPorts; i++) { for (int i = 0; i < fNPorts; i++) {
if (fCeltEncoder[i])
if (fCeltEncoder[i]) {
celt_encoder_destroy(fCeltEncoder[i]); celt_encoder_destroy(fCeltEncoder[i]);
if (fCeltDecoder[i])
}
if (fCeltDecoder[i]) {
celt_decoder_destroy(fCeltDecoder[i]); celt_decoder_destroy(fCeltDecoder[i]);
if (fCeltMode[i])
}
if (fCeltMode[i]) {
celt_mode_destroy(fCeltMode[i]); celt_mode_destroy(fCeltMode[i]);
}
} }


delete [] fCeltMode; delete [] fCeltMode;
@@ -385,7 +612,7 @@ namespace Jack


size_t NetCeltAudioBuffer::GetCycleSize() size_t NetCeltAudioBuffer::GetCycleSize()
{ {
return fCycleSize;
return fCycleBytesSize;
} }


float NetCeltAudioBuffer::GetCycleDuration() float NetCeltAudioBuffer::GetCycleDuration()
@@ -393,38 +620,29 @@ namespace Jack
return fCycleDuration; return fCycleDuration;
} }


int NetCeltAudioBuffer::GetNumPackets()
int NetCeltAudioBuffer::GetNumPackets(int active_ports)
{ {
return fNumPackets; return fNumPackets;
} }


void NetCeltAudioBuffer::SetBuffer(int index, sample_t* buffer)
{
assert(fPortBuffer);
fPortBuffer[index] = buffer;
}

sample_t* NetCeltAudioBuffer::GetBuffer(int index)
{
assert(fPortBuffer);
return fPortBuffer[index];
}

void NetCeltAudioBuffer::RenderFromJackPorts()
int NetCeltAudioBuffer::RenderFromJackPorts()
{ {
float floatbuf[fPeriodSize];
float buffer[fPeriodSize];


for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(floatbuf, fPortBuffer[port_index], fPeriodSize * sizeof(float));
memcpy(buffer, fPortBuffer[port_index], fPeriodSize * sizeof(sample_t));
#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
int res = celt_encode_float(fCeltEncoder[port_index], floatbuf, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
int res = celt_encode_float(fCeltEncoder[port_index], buffer, fPeriodSize, fCompressedBuffer[port_index], fCompressedSizeByte);
#else #else
int res = celt_encode_float(fCeltEncoder[port_index], floatbuf, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
int res = celt_encode_float(fCeltEncoder[port_index], buffer, NULL, fCompressedBuffer[port_index], fCompressedSizeByte);
#endif #endif
if (res != fCompressedSizeByte) { if (res != fCompressedSizeByte) {
jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
jack_error("celt_encode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
} }
} }

// All ports active
return fNPorts;
} }


void NetCeltAudioBuffer::RenderToJackPorts() void NetCeltAudioBuffer::RenderToJackPorts()
@@ -436,47 +654,42 @@ namespace Jack
int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]); int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
#endif #endif
if (res != CELT_OK) { if (res != CELT_OK) {
jack_error("celt_decode_float error res = %d", fCompressedSizeByte, res);
jack_error("celt_decode_float error fCompressedSizeByte = %d res = %d", fCompressedSizeByte, res);
} }
} }


// reset for next cycle
fLastSubCycle = -1;
NextCycle();
} }


//network<->buffer //network<->buffer
int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
int NetCeltAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{ {
int res = 0;

// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) { if (sub_cycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
}
} else { } else {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); memcpy(fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
} }


if (sub_cycle != fLastSubCycle + 1) {
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
res = NET_PACKET_ERROR;
}

fLastSubCycle = sub_cycle;
return res;
return CheckPacket(cycle, sub_cycle);
} }


int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t& port_num)
int NetCeltAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{ {
port_num = fNPorts;

// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) { if (sub_cycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize); memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fLastSubPeriodBytesSize);
}
return fNPorts * fLastSubPeriodBytesSize; return fNPorts * fLastSubPeriodBytesSize;
} else { } else {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fSubPeriodBytesSize); memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fCompressedBuffer[port_index] + sub_cycle * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
return fNPorts * fSubPeriodBytesSize; return fNPorts * fSubPeriodBytesSize;
} }
} }
@@ -484,42 +697,34 @@ namespace Jack
#endif #endif


NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer) NetIntAudioBuffer::NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
: fNetBuffer(net_buffer)
: NetAudioBuffer(params, nports, net_buffer)
{ {
int res1, res2;

fNPorts = nports;
fPeriodSize = params->fPeriodSize; fPeriodSize = params->fPeriodSize;


fPortBuffer = new sample_t* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++)
fPortBuffer[port_index] = NULL;
fCompressedSizeByte = (params->fPeriodSize * sizeof(short));
jack_log("NetIntAudioBuffer fCompressedSizeByte %d", fCompressedSizeByte);


fIntBuffer = new short* [fNPorts]; fIntBuffer = new short* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
fIntBuffer[port_index] = new short[fPeriodSize]; fIntBuffer[port_index] = new short[fPeriodSize];
}


fCompressedSizeByte = (params->fPeriodSize * sizeof(short));

jack_log("fCompressedSizeByte %d", fCompressedSizeByte);

res1 = (fNPorts * fCompressedSizeByte) % (params->fMtu - sizeof(packet_header_t));
res2 = (fNPorts * fCompressedSizeByte) / (params->fMtu - sizeof(packet_header_t));
int res1 = (fNPorts * fCompressedSizeByte) % PACKET_AVAILABLE_SIZE(params);
int res2 = (fNPorts * fCompressedSizeByte) / PACKET_AVAILABLE_SIZE(params);


jack_log("res1 = %d res2 = %d", res1, res2);
jack_log("NetIntAudioBuffer res1 = %d res2 = %d", res1, res2);


fNumPackets = (res1) ? (res2 + 1) : res2; fNumPackets = (res1) ? (res2 + 1) : res2;


fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets; fSubPeriodBytesSize = fCompressedSizeByte / fNumPackets;
fSubPeriodSize = fSubPeriodBytesSize / sizeof(short);

fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets; fLastSubPeriodBytesSize = fSubPeriodBytesSize + fCompressedSizeByte % fNumPackets;
fLastSubPeriodSize = fLastSubPeriodBytesSize / sizeof(short);


jack_log("fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);
fSubPeriodSize = fSubPeriodBytesSize / sizeof(short);

jack_log("NetIntAudioBuffer fNumPackets = %d fSubPeriodBytesSize = %d, fLastSubPeriodBytesSize = %d", fNumPackets, fSubPeriodBytesSize, fLastSubPeriodBytesSize);


fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate); fCycleDuration = float(fSubPeriodBytesSize / sizeof(sample_t)) / float(params->fSampleRate);
fCycleSize = params->fMtu * fNumPackets;
fCycleBytesSize = params->fMtu * fNumPackets;


fLastSubCycle = -1; fLastSubCycle = -1;
return; return;
@@ -527,16 +732,16 @@ namespace Jack


NetIntAudioBuffer::~NetIntAudioBuffer() NetIntAudioBuffer::~NetIntAudioBuffer()
{ {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
delete [] fIntBuffer[port_index]; delete [] fIntBuffer[port_index];
}


delete [] fIntBuffer; delete [] fIntBuffer;
delete [] fPortBuffer;
} }


size_t NetIntAudioBuffer::GetCycleSize() size_t NetIntAudioBuffer::GetCycleSize()
{ {
return fCycleSize;
return fCycleBytesSize;
} }


float NetIntAudioBuffer::GetCycleDuration() float NetIntAudioBuffer::GetCycleDuration()
@@ -544,135 +749,67 @@ namespace Jack
return fCycleDuration; return fCycleDuration;
} }


int NetIntAudioBuffer::GetNumPackets()
int NetIntAudioBuffer::GetNumPackets(int active_ports)
{ {
return fNumPackets; return fNumPackets;
} }


void NetIntAudioBuffer::SetBuffer(int index, sample_t* buffer)
{
fPortBuffer[index] = buffer;
}

sample_t* NetIntAudioBuffer::GetBuffer(int index)
{
return fPortBuffer[index];
}

void NetIntAudioBuffer::RenderFromJackPorts()
int NetIntAudioBuffer::RenderFromJackPorts()
{ {
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
for (unsigned int frame = 0; frame < fPeriodSize; frame++)
for (uint frame = 0; frame < fPeriodSize; frame++) {
fIntBuffer[port_index][frame] = short(fPortBuffer[port_index][frame] * 32768.f); fIntBuffer[port_index][frame] = short(fPortBuffer[port_index][frame] * 32768.f);
}
} }

// All ports active
return fNPorts;
} }


void NetIntAudioBuffer::RenderToJackPorts() void NetIntAudioBuffer::RenderToJackPorts()
{ {
float coef = 1.f / 32768.f;
for (int port_index = 0; port_index < fNPorts; port_index++) { for (int port_index = 0; port_index < fNPorts; port_index++) {
float coef = 1.f / 32768.f;
for (unsigned int frame = 0; frame < fPeriodSize; frame++)
for (uint frame = 0; frame < fPeriodSize; frame++) {
fPortBuffer[port_index][frame] = float(fIntBuffer[port_index][frame] * coef); fPortBuffer[port_index][frame] = float(fIntBuffer[port_index][frame] * coef);
}
} }


// reset for next cycle
fLastSubCycle = -1;
NextCycle();
} }


//network<->buffer
int NetIntAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
//network<->buffer
int NetIntAudioBuffer::RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num)
{ {
int res = 0;

if (sub_cycle == fNumPackets - 1) { if (sub_cycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize); memcpy(fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fNetBuffer + port_index * fLastSubPeriodBytesSize, fLastSubPeriodBytesSize);
}
} else { } else {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize); memcpy(fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fNetBuffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
} }


if (sub_cycle != fLastSubCycle + 1) {
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
res = NET_PACKET_ERROR;
}

fLastSubCycle = sub_cycle;
return res;
return CheckPacket(cycle, sub_cycle);
} }


int NetIntAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t& port_num)
int NetIntAudioBuffer::RenderToNetwork(int sub_cycle, uint32_t port_num)
{ {
port_num = fNPorts;

// Last packet of the cycle
if (sub_cycle == fNumPackets - 1) { if (sub_cycle == fNumPackets - 1) {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fLastSubPeriodBytesSize); memcpy(fNetBuffer + port_index * fLastSubPeriodBytesSize, fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fLastSubPeriodBytesSize);
}
return fNPorts * fLastSubPeriodBytesSize; return fNPorts * fLastSubPeriodBytesSize;
} else { } else {
for (int port_index = 0; port_index < fNPorts; port_index++)
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize); memcpy(fNetBuffer + port_index * fSubPeriodBytesSize, fIntBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize);
}
return fNPorts * fSubPeriodBytesSize; return fNPorts * fSubPeriodBytesSize;
} }
} }


// Buffered

/*
NetBufferedAudioBuffer::NetBufferedAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer)
{
fMaxCycle = 0;
fNetBuffer = net_buffer;

for (int i = 0; i < AUDIO_BUFFER_SIZE; i++) {
fPortBuffer[i].Init(params, nports);
}

fJackPortBuffer = new sample_t* [nports];
for (uint32_t port_index = 0; port_index < nports; port_index++)
fJackPortBuffer[port_index] = NULL;
}

NetBufferedAudioBuffer::~NetBufferedAudioBuffer()
{
delete [] fJackPortBuffer;
}

size_t NetBufferedAudioBuffer::GetCycleSize()
{
return fPortBuffer[0].GetCycleSize();
}

void NetBufferedAudioBuffer::SetBuffer(int index, sample_t* buffer)
{
fJackPortBuffer[index] = buffer;
}

sample_t* NetBufferedAudioBuffer::GetBuffer(int index)
{
return fJackPortBuffer[index];
}

void NetBufferedAudioBuffer::RenderFromJackPorts (int sub_cycle)
{
fPortBuffer[0].RenderFromJackPorts(fNetBuffer, sub_cycle); // Always use first buffer...
}

void NetBufferedAudioBuffer::RenderToJackPorts (int cycle, int sub_cycle)
{
if (cycle < fMaxCycle) {
jack_info("Wrong order fCycle %d sub_cycle %d fMaxCycle %d", cycle, sub_cycle, fMaxCycle);
}
fPortBuffer[cycle % AUDIO_BUFFER_SIZE].RenderToJackPorts(fNetBuffer, sub_cycle);
}

void NetBufferedAudioBuffer::FinishRenderToJackPorts (int cycle)
{
fMaxCycle = std::max(fMaxCycle, cycle);
fPortBuffer[(cycle + 1) % AUDIO_BUFFER_SIZE].Copy(fJackPortBuffer); // Copy internal buffer in JACK ports
}
*/

// SessionParams ************************************************************************************ // SessionParams ************************************************************************************


SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params) SERVER_EXPORT void SessionParamsHToN(session_params_t* src_params, session_params_t* dst_params)
@@ -690,6 +827,7 @@ namespace Jack
dst_params->fPeriodSize = htonl(src_params->fPeriodSize); dst_params->fPeriodSize = htonl(src_params->fPeriodSize);
dst_params->fSampleEncoder = htonl(src_params->fSampleEncoder); dst_params->fSampleEncoder = htonl(src_params->fSampleEncoder);
dst_params->fSlaveSyncMode = htonl(src_params->fSlaveSyncMode); dst_params->fSlaveSyncMode = htonl(src_params->fSlaveSyncMode);
dst_params->fNetworkLatency = htonl(src_params->fNetworkLatency);
} }


SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params) SERVER_EXPORT void SessionParamsNToH(session_params_t* src_params, session_params_t* dst_params)
@@ -707,6 +845,7 @@ namespace Jack
dst_params->fPeriodSize = ntohl(src_params->fPeriodSize); dst_params->fPeriodSize = ntohl(src_params->fPeriodSize);
dst_params->fSampleEncoder = ntohl(src_params->fSampleEncoder); dst_params->fSampleEncoder = ntohl(src_params->fSampleEncoder);
dst_params->fSlaveSyncMode = ntohl(src_params->fSlaveSyncMode); dst_params->fSlaveSyncMode = ntohl(src_params->fSlaveSyncMode);
dst_params->fNetworkLatency = ntohl(src_params->fNetworkLatency);
} }


SERVER_EXPORT void SessionParamsDisplay(session_params_t* params) SERVER_EXPORT void SessionParamsDisplay(session_params_t* params)
@@ -725,19 +864,6 @@ namespace Jack
break; break;
} }


char mode[8];
switch (params->fNetworkMode)
{
case 's' :
strcpy(mode, "slow");
break;
case 'n' :
strcpy(mode, "normal");
break;
case 'f' :
strcpy(mode, "fast");
break;
}
jack_info("**************** Network parameters ****************"); jack_info("**************** Network parameters ****************");
jack_info("Name : %s", params->fName); jack_info("Name : %s", params->fName);
jack_info("Protocol revision : %d", params->fProtocolVersion); jack_info("Protocol revision : %d", params->fProtocolVersion);
@@ -750,6 +876,7 @@ namespace Jack
jack_info("Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels); jack_info("Return channels (audio - midi) : %d - %d", params->fReturnAudioChannels, params->fReturnMidiChannels);
jack_info("Sample rate : %u frames per second", params->fSampleRate); jack_info("Sample rate : %u frames per second", params->fSampleRate);
jack_info("Period size : %u frames per period", params->fPeriodSize); jack_info("Period size : %u frames per period", params->fPeriodSize);
jack_info("Network latency : %u cycles", params->fNetworkLatency);
switch (params->fSampleEncoder) { switch (params->fSampleEncoder) {
case (JackFloatEncoder): case (JackFloatEncoder):
jack_info("SampleEncoder : %s", "Float"); jack_info("SampleEncoder : %s", "Float");
@@ -763,7 +890,6 @@ namespace Jack
break; break;
}; };
jack_info("Slave mode : %s", (params->fSlaveSyncMode) ? "sync" : "async"); jack_info("Slave mode : %s", (params->fSlaveSyncMode) ? "sync" : "async");
jack_info("Network mode : %s", mode);
jack_info("****************************************************"); jack_info("****************************************************");
} }


@@ -943,14 +1069,12 @@ namespace Jack
WORD wVersionRequested = MAKEWORD(2, 2); WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData; WSADATA wsaData;


if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
jack_error("WSAStartup error : %s", strerror(NET_ERROR_CODE)); jack_error("WSAStartup error : %s", strerror(NET_ERROR_CODE));
return -1; return -1;
} }


if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
jack_error("Could not find a useable version of Winsock.dll\n"); jack_error("Could not find a useable version of Winsock.dll\n");
WSACleanup(); WSACleanup();
return -1; return -1;


+ 70
- 516
common/JackNetTool.h View File

@@ -39,13 +39,16 @@ using namespace std;
#endif #endif
#endif #endif


#define MASTER_PROTOCOL 4
#define SLAVE_PROTOCOL 4
#define MASTER_PROTOCOL 5
#define SLAVE_PROTOCOL 5


#define NET_PACKET_ERROR -2 #define NET_PACKET_ERROR -2


#define OPTIMIZED_PROTOCOL #define OPTIMIZED_PROTOCOL


#define HEADER_SIZE (sizeof(packet_header_t))
#define PACKET_AVAILABLE_SIZE(params) ((params)->fMtu - sizeof(packet_header_t))

namespace Jack namespace Jack
{ {
typedef struct _session_params session_params_t; typedef struct _session_params session_params_t;
@@ -101,7 +104,7 @@ namespace Jack
uint32_t fSampleEncoder; //samples encoder uint32_t fSampleEncoder; //samples encoder
uint32_t fKBps; //KB per second for CELT encoder uint32_t fKBps; //KB per second for CELT encoder
uint32_t fSlaveSyncMode; //is the slave in sync mode ? uint32_t fSlaveSyncMode; //is the slave in sync mode ?
char fNetworkMode; //fast, normal or slow mode
uint32_t fNetworkLatency; //network latency
}; };


//net status ********************************************************************************** //net status **********************************************************************************
@@ -232,11 +235,12 @@ namespace Jack
int fNPorts; int fNPorts;
size_t fMaxBufsize; size_t fMaxBufsize;
int fMaxPcktSize; int fMaxPcktSize;

char* fBuffer; char* fBuffer;
char* fNetBuffer; char* fNetBuffer;
JackMidiBuffer** fPortBuffer; JackMidiBuffer** fPortBuffer;


size_t fCycleSize; // needed size in bytes ofr an entire cycle
size_t fCycleBytesSize; // needed size in bytes ofr an entire cycle


public: public:


@@ -247,9 +251,11 @@ namespace Jack


// needed size in bytes for an entire cycle // needed size in bytes for an entire cycle
size_t GetCycleSize(); size_t GetCycleSize();

int GetNumPackets(int data_sizen, int max_size); int GetNumPackets(int data_sizen, int max_size);


void SetBuffer(int index, JackMidiBuffer* buffer);
JackMidiBuffer* GetBuffer(int index);

//utility //utility
void DisplayEvents(); void DisplayEvents();


@@ -261,8 +267,6 @@ namespace Jack
void RenderFromNetwork(int sub_cycle, size_t copy_size); void RenderFromNetwork(int sub_cycle, size_t copy_size);
int RenderToNetwork(int sub_cycle, size_t total_size); int RenderToNetwork(int sub_cycle, size_t total_size);


void SetBuffer(int index, JackMidiBuffer* buffer);
JackMidiBuffer* GetBuffer(int index);
}; };


// audio data ********************************************************************************* // audio data *********************************************************************************
@@ -270,12 +274,33 @@ namespace Jack
class SERVER_EXPORT NetAudioBuffer class SERVER_EXPORT NetAudioBuffer
{ {


protected:

int fNPorts;
int fLastSubCycle;

char* fNetBuffer;
sample_t** fPortBuffer;
bool* fConnectedPorts;

jack_nframes_t fPeriodSize;
jack_nframes_t fSubPeriodSize;
size_t fSubPeriodBytesSize;

float fCycleDuration; // in sec
size_t fCycleBytesSize; // needed size in bytes for an entire cycle

int CheckPacket(int cycle, int sub_cycle);
void NextCycle();
void Cleanup();

public: public:


NetAudioBuffer()
{}
virtual ~NetAudioBuffer()
{}
NetAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
virtual ~NetAudioBuffer();

bool GetConnected(int port_index) { return fConnectedPorts[port_index]; }
void SetConnected(int port_index, bool state) { fConnectedPorts[port_index] = state; }


// needed syze in bytes ofr an entire cycle // needed syze in bytes ofr an entire cycle
virtual size_t GetCycleSize() = 0; virtual size_t GetCycleSize() = 0;
@@ -283,414 +308,55 @@ namespace Jack
// cycle duration in sec // cycle duration in sec
virtual float GetCycleDuration() = 0; virtual float GetCycleDuration() = 0;


virtual int GetNumPackets() = 0;
virtual int GetNumPackets(int active_ports) = 0;

virtual void SetBuffer(int index, sample_t* buffer);
virtual sample_t* GetBuffer(int index);


//jack<->buffer //jack<->buffer
virtual void RenderFromJackPorts() = 0;
virtual void RenderToJackPorts() = 0;
virtual int RenderFromJackPorts();
virtual void RenderToJackPorts();


//network<->buffer //network<->buffer
virtual int RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num) = 0;
virtual void ActivePortsFromNetwork(char* net_buffer, uint32_t port_num) {}

virtual int RenderToNetwork(int sub_cycle, uint32_t& port_num) = 0;
virtual void ActivePortsToNetwork(char* net_buffer, uint32_t& port_num) {}

virtual void SetBuffer(int index, sample_t* buffer) = 0;
virtual sample_t* GetBuffer(int index) = 0;
};

/**
\Brief Audio buffer and operations class

This class is a toolset to manipulate audio buffers.
The manipulation of audio buffers is similar to midi buffer, except those buffers have fixed size.
The interleaving/uninterleaving operations are simplier here because audio buffers have fixed size,
So there is no need of an intermediate buffer as in NetMidiBuffer.

*/

struct JackPortList {

// "[---Header---|--audio data--|--audio data--]..."

jack_nframes_t fPeriodSize;
jack_nframes_t fSubPeriodSize;
size_t fSubPeriodBytesSize;
sample_t** fPortBuffer;
int fPacketSize;
int fNPorts;
size_t fCycleSize; // needed size in bytes for an entire cycle
float fCycleDuration; // in sec

int fLastSubCycle;

JackPortList(session_params_t* params, uint32_t nports)
{
fNPorts = nports;
fPeriodSize = params->fPeriodSize;
fPacketSize = params->fMtu - sizeof(packet_header_t);

if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) {
fSubPeriodSize = params->fPeriodSize;
} else {
jack_nframes_t period = (int) powf(2.f,(int)(log(float(fPacketSize)
/ (max(params->fReturnAudioChannels, params->fSendAudioChannels) * sizeof(sample_t))) / log(2.)));
fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period;
}

fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t);

fPortBuffer = new sample_t* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++) {
fPortBuffer[port_index] = NULL;
}

fCycleDuration = float(fSubPeriodSize) / float(params->fSampleRate);
fCycleSize = params->fMtu * (fPeriodSize / fSubPeriodSize);

fLastSubCycle = -1;
}

virtual int GetNumPackets()
{
jack_info("GetNumPackets packet = %d fPeriodSize = %d fSubPeriodSize = %d fSubPeriodBytesSize = %d",
fPeriodSize / fSubPeriodSize, fPeriodSize, fSubPeriodSize, fSubPeriodBytesSize);
return fPeriodSize / fSubPeriodSize;
}

JackPortList()
{
fNPorts = 0;
fPeriodSize = 0;
fSubPeriodSize = 0;
fSubPeriodBytesSize = 0;
fPortBuffer = 0;
}

virtual ~JackPortList()
{
delete [] fPortBuffer;
}

void SetBuffer(int index, sample_t* buffer)
{
fPortBuffer[index] = buffer;
}

sample_t* GetBuffer(int index)
{
return fPortBuffer[index];
}

void Copy(sample_t** buffers)
{
for (int port_index = 0; port_index < fNPorts; port_index++)
memcpy(buffers[port_index], fPortBuffer[port_index], fPeriodSize * sizeof(float));
}

// needed syze in bytes for an entire cycle
size_t GetCycleSize()
{
return fCycleSize;
}

// cycle duration in sec
float GetCycleDuration()
{
return fCycleDuration;
}

#ifdef __BIG_ENDIAN__

static inline float SwapFloat(float f)
{
union
{
float f;
unsigned char b[4];
} dat1, dat2;

dat1.f = f;
dat2.b[0] = dat1.b[3];
dat2.b[1] = dat1.b[2];
dat2.b[2] = dat1.b[1];
dat2.b[3] = dat1.b[0];
return dat2.f;
}

virtual void RenderFromJackPorts()
{}

virtual void RenderToJackPorts()
{}

//network<->buffer
virtual int RenderFromNetwork(char* net_buffer, int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
{
int res = 0;

for (int port_index = 0; port_index < fNPorts; port_index++) {
float* src = (float*)(net_buffer + port_index * fSubPeriodBytesSize);
float* dst = (float*)(fPortBuffer[port_index] + sub_cycle * fSubPeriodSize);
for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) {
dst[sample] = SwapFloat(src[sample]);
}
}
if (sub_cycle != fLastSubCycle + 1) {
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
res = NET_PACKET_ERROR;
}

fLastSubCycle = sub_cycle;
return res;
}

virtual int RenderToNetwork(char* net_buffer, int sub_cycle, uint32_t& port_num)
{
for (int port_index = 0; port_index < fNPorts; port_index++) {
float* src = (float*)(fPortBuffer[port_index] + sub_cycle * fSubPeriodSize);
float* dst = (float*)(net_buffer + port_index * fSubPeriodBytesSize);
for (unsigned int sample = 0; sample < fSubPeriodBytesSize / sizeof(float); sample++) {
dst[sample] = SwapFloat(src[sample]);
}
}

port_num = fNPorts;
return fNPorts * fSubPeriodBytesSize;
}

#else

virtual void RenderFromJackPorts()
{}

virtual void RenderToJackPorts()
{
// reset for next cycle
fLastSubCycle = -1;
}

//network<->buffer
virtual int RenderFromNetwork(char* net_buffer, int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
{
int res = 0;

for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(fPortBuffer[port_index] + sub_cycle * fSubPeriodSize, net_buffer + port_index * fSubPeriodBytesSize, fSubPeriodBytesSize);
}
if (sub_cycle != fLastSubCycle + 1) {
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
res = NET_PACKET_ERROR;
}

fLastSubCycle = sub_cycle;
return res;
}

virtual int RenderToNetwork(char* net_buffer, int sub_cycle, uint32_t& port_num)
{
for (int port_index = 0; port_index < fNPorts; port_index++) {
memcpy(net_buffer + port_index * fSubPeriodBytesSize, fPortBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize);
}
port_num = fNPorts;
return fNPorts * fSubPeriodBytesSize;
}

#endif

virtual void ActivePortsFromNetwork(char* net_buffer, uint32_t port_num)
{}

virtual void ActivePortsToNetwork(char* net_buffer, uint32_t& port_num)
{
port_num = fNPorts;
}
virtual int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num) = 0;
virtual int RenderToNetwork(int sub_cycle, uint32_t port_num) = 0;


};
virtual void RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle, size_t copy_size) {}
virtual void RenderToNetwork(char* net_buffer, int active_port, int sub_cycle, size_t copy_size) {}


struct JackOptimizedPortList : JackPortList {

// Consuming port list is transmitted in the Sync packed
// "[---Header---|--active_port_num---audio data--|--active_port_num---audio data--]..."

JackOptimizedPortList(session_params_t* params, uint32_t nports)
:JackPortList(params, nports)
{}

virtual ~JackOptimizedPortList()
{}

int GetNumPackets()
{
// Count active ports
int active_ports = 0;
for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index]) active_ports++;
}

if (active_ports == 0) {
fSubPeriodSize = fPeriodSize;
} else {
jack_nframes_t period = (int) powf(2.f, (int)(log(float(fPacketSize) / (active_ports * sizeof(sample_t))) / log(2.)));
fSubPeriodSize = (period > fPeriodSize) ? fPeriodSize : period;
}

fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t) + sizeof(uint32_t); // The port number in coded on 4 bytes
return fPeriodSize / fSubPeriodSize; // At least one packet
}

#ifdef __BIG_ENDIAN__

// TODO

#else

//network<->buffer
virtual int RenderFromNetwork(char* net_buffer, int cycle, int sub_cycle, size_t copy_size, uint32_t port_num)
{
int res = 0;

// Cleanup all JACK ports at the beginning of the cycle
if (sub_cycle == 0) {
for (int port_index = 0; port_index < fNPorts; port_index++) {
if (fPortBuffer[port_index])
memset(fPortBuffer[port_index], 0, fPeriodSize * sizeof(sample_t));
}
}

if (port_num > 0) {

/// Setup rendering parameters
int sub_period_size, sub_period_bytes_size;
if (port_num == 0) {
sub_period_size = fPeriodSize;
} else {
jack_nframes_t period = (int) powf(2.f, (int)(log(float(fPacketSize) / (port_num * sizeof(sample_t))) / log(2.)));
sub_period_size = (period > fPeriodSize) ? fPeriodSize : period;
}
sub_period_bytes_size = sub_period_size * sizeof(sample_t) + sizeof(uint32_t); // The port number in coded on 4 bytes

for (uint32_t port_index = 0; port_index < port_num; port_index++) {
// Only copy to active ports : read the active port number then audio data
int* active_port_address = (int*)(net_buffer + port_index * sub_period_bytes_size);
int active_port = (int)(*active_port_address);
if (fPortBuffer[port_index])
memcpy(fPortBuffer[active_port] + sub_cycle * sub_period_size, (char*)(active_port_address + 1), sub_period_bytes_size - sizeof(int));
}

if (sub_cycle != fLastSubCycle + 1) {
jack_error("Packet(s) missing from... %d %d", fLastSubCycle, sub_cycle);
res = NET_PACKET_ERROR;
}

fLastSubCycle = sub_cycle;
}

return res;
}

virtual int RenderToNetwork(char* net_buffer,int sub_cycle, uint32_t& port_num)
{
// Init active port count
port_num = 0;

for (int port_index = 0; port_index < fNPorts; port_index++) {
// Only copy from active ports : write the active port number then audio data
if (fPortBuffer[port_index]) {
int* active_port_address = (int*)(net_buffer + port_num * fSubPeriodBytesSize);
*active_port_address = port_index;
memcpy((char*)(active_port_address + 1), fPortBuffer[port_index] + sub_cycle * fSubPeriodSize, fSubPeriodBytesSize - sizeof(uint32_t));
port_num++;
}
}

return port_num * fSubPeriodBytesSize;
}

#endif

virtual void ActivePortsToNetwork(char* net_buffer, uint32_t& port_num)
{
// Init active port count
port_num = 0;
short* active_port_address = (short*)net_buffer;

for (int port_index = 0; port_index < fNPorts; port_index++) {
// Write the active port number
if (fPortBuffer[port_index]) {
*active_port_address = port_index;
active_port_address++;
port_num++;
assert(port_num < 512);
}
}
}

virtual void ActivePortsFromNetwork(char* net_buffer, uint32_t port_num)
{
short* active_port_address = (short*)net_buffer;

for (int port_index = 0; port_index < fNPorts; port_index++) {
fPortBuffer[port_index] = NULL;
}

for (uint port_index = 0; port_index < port_num; port_index++) {
// Use -1 when port is actually connected on other side
if (*active_port_address >= 0 && *active_port_address < fNPorts) {
fPortBuffer[*active_port_address] = (sample_t*)-1;
} else {
jack_error("ActivePortsFromNetwork: incorrect port = %d", *active_port_address);
}
active_port_address++;
}
}
virtual int ActivePortsToNetwork(char* net_buffer);
virtual void ActivePortsFromNetwork(char* net_buffer, uint32_t port_num);


}; };


class SERVER_EXPORT NetFloatAudioBuffer : public NetAudioBuffer class SERVER_EXPORT NetFloatAudioBuffer : public NetAudioBuffer
{ {

private: private:


#ifdef OPTIMIZED_PROTOCOL
JackOptimizedPortList fPortBuffer;
#else
JackPortList fPortBuffer;
#endif
char* fNetBuffer;
int fPacketSize;

void UpdateParams(int active_ports);


public: public:


NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); NetFloatAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
~NetFloatAudioBuffer();
virtual ~NetFloatAudioBuffer();


// needed size in bytes for an entire cycle // needed size in bytes for an entire cycle
size_t GetCycleSize(); size_t GetCycleSize();


// cycle duration in sec // cycle duration in sec
float GetCycleDuration()
{
return fPortBuffer.GetCycleDuration();
}

int GetNumPackets()
{
return fPortBuffer.GetNumPackets();
}
float GetCycleDuration();
int GetNumPackets(int active_ports);


//jack<->buffer //jack<->buffer
void RenderFromJackPorts();
void RenderToJackPorts();
int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t port_num);


void SetBuffer(int index, sample_t* buffer);
sample_t* GetBuffer(int index);
void RenderFromNetwork(char* net_buffer, int active_port, int sub_cycle);
void RenderToNetwork(char* net_buffer, int active_port, int sub_cycle);


//network<->buffer
int RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num);
void ActivePortsFromNetwork(char* net_buffer, uint32_t port_num);

int RenderToNetwork(int sub_cycle, uint32_t& ort_num);
void ActivePortsToNetwork(char* net_buffer, uint32_t& port_num);
}; };


#if HAVE_CELT #if HAVE_CELT
@@ -706,45 +372,33 @@ namespace Jack
CELTDecoder** fCeltDecoder; CELTDecoder** fCeltDecoder;


int fCompressedSizeByte; int fCompressedSizeByte;
jack_nframes_t fPeriodSize;
int fNumPackets; int fNumPackets;
float fCycleDuration; // in sec
size_t fCycleSize; // needed size in bytes for an entire cycle


size_t fSubPeriodBytesSize;
size_t fLastSubPeriodBytesSize; size_t fLastSubPeriodBytesSize;


sample_t** fPortBuffer;
char* fNetBuffer;
unsigned char** fCompressedBuffer; unsigned char** fCompressedBuffer;


int fNPorts;
int fLastSubCycle;

void FreeCelt(); void FreeCelt();


public: public:


NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps); NetCeltAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer, int kbps);
~NetCeltAudioBuffer();
virtual ~NetCeltAudioBuffer();


// needed size in bytes for an entire cycle // needed size in bytes for an entire cycle
size_t GetCycleSize(); size_t GetCycleSize();


// cycle duration in sec // cycle duration in sec
float GetCycleDuration(); float GetCycleDuration();
int GetNumPackets();

void SetBuffer(int index, sample_t* buffer);
sample_t* GetBuffer(int index);
int GetNumPackets(int active_ports);


//jack<->buffer //jack<->buffer
void RenderFromJackPorts();
int RenderFromJackPorts();
void RenderToJackPorts(); void RenderToJackPorts();


//network<->buffer //network<->buffer
int RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t& port_num);
int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t port_num);
}; };


#endif #endif
@@ -754,133 +408,33 @@ namespace Jack
private: private:


int fCompressedSizeByte; int fCompressedSizeByte;
jack_nframes_t fPeriodSize;

int fNumPackets; int fNumPackets;
float fCycleDuration; // in sec
size_t fCycleSize; // needed size in bytes for an entire cycle


size_t fSubPeriodSize;
size_t fSubPeriodBytesSize;
size_t fLastSubPeriodSize;;
size_t fLastSubPeriodBytesSize; size_t fLastSubPeriodBytesSize;


sample_t** fPortBuffer;
char* fNetBuffer;
short ** fIntBuffer;

int fNPorts;
int fLastSubCycle;
short** fIntBuffer;


public: public:


NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer); NetIntAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
~NetIntAudioBuffer();
virtual ~NetIntAudioBuffer();


// needed size in bytes for an entire cycle // needed size in bytes for an entire cycle
size_t GetCycleSize(); size_t GetCycleSize();


// cycle duration in sec // cycle duration in sec
float GetCycleDuration(); float GetCycleDuration();
int GetNumPackets();

void SetBuffer(int index, sample_t* buffer);
sample_t* GetBuffer(int index);
int GetNumPackets(int active_ports);


//jack<->buffer //jack<->buffer
void RenderFromJackPorts();
int RenderFromJackPorts();
void RenderToJackPorts(); void RenderToJackPorts();


//network<->buffer //network<->buffer
int RenderFromNetwork(int cycle, int sub_cycle, size_t copy_size, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t& port_num);
int RenderFromNetwork(int cycle, int sub_cycle, uint32_t port_num);
int RenderToNetwork(int sub_cycle, uint32_t port_num);
}; };


/*
#define AUDIO_BUFFER_SIZE 8

struct JackPortListAllocate : public JackPortList {

JackPortListAllocate()
{
fNPorts = 0;
fPeriodSize = 0;
fSubPeriodSize = 0;
fSubPeriodBytesSize = 0;
fPortBuffer = 0;
}

~JackPortListAllocate()
{
for (int port_index = 0; port_index < fNPorts; port_index++)
delete [] fPortBuffer[port_index];
delete [] fPortBuffer;
}

void Init(session_params_t* params, uint32_t nports)
{
fNPorts = nports;
fPeriodSize = params->fPeriodSize;

if (params->fSendAudioChannels == 0 && params->fReturnAudioChannels == 0) {
fSubPeriodSize = params->fPeriodSize;
} else {
jack_nframes_t period = (int) powf(2.f, (int)(log(float((params->fMtu - sizeof(packet_header_t)))
/ (max(params->fReturnAudioChannels, params->fSendAudioChannels) * sizeof(sample_t))) / log(2.)));
fSubPeriodSize = (period > params->fPeriodSize) ? params->fPeriodSize : period;
}

fSubPeriodBytesSize = fSubPeriodSize * sizeof(sample_t);
fPortBuffer = new sample_t* [fNPorts];
for (int port_index = 0; port_index < fNPorts; port_index++)
fPortBuffer[port_index] = new sample_t[fPeriodSize];
}

};

class SERVER_EXPORT NetBufferedAudioBuffer : public NetAudioBuffer
{

private:
char* fNetBuffer;
JackPortListAllocate fPortBuffer[AUDIO_BUFFER_SIZE];
sample_t** fJackPortBuffer;
int fMaxCycle;

public:
NetBufferedAudioBuffer(session_params_t* params, uint32_t nports, char* net_buffer);
~NetBufferedAudioBuffer();

// needed syze in bytes ofr an entire cycle
size_t GetCycleSize();

// cycle duration in sec
float GetCycleDuration()
{
return fPortBuffer[0].GetCycleDuration();
}

//jack<->buffer
void RenderFromJackPorts(int sub_cycle);
void RenderToJackPorts(int cycle, int sub_cycle);
//void FinishRenderToJackPorts(int cycle);

//network<->buffer
void RenderFromNetwork(int sub_cycle, size_t copy_size)
{
// TODO
}
int RenderToNetwork(int sub_cycle, size_t total_size)
{
// TODO
return 0;
}

void SetBuffer(int index, sample_t* buffer);
sample_t* GetBuffer(int index);
};
*/

//utility ************************************************************************************* //utility *************************************************************************************


//socket API management //socket API management


+ 1
- 0
common/JackPort.cpp View File

@@ -35,6 +35,7 @@ JackPort::JackPort()
bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags)
{ {
jack_port_type_id_t id = GetPortTypeId(port_type); jack_port_type_id_t id = GetPortTypeId(port_type);
assert(id >= 0 && id <= PORT_TYPES_MAX);
if (id == PORT_TYPES_MAX) if (id == PORT_TYPES_MAX)
return false; return false;
fTypeId = id; fTypeId = id;


+ 7
- 4
common/JackRequest.h View File

@@ -149,11 +149,12 @@ struct JackClientCheckRequest : public JackRequest
int fProtocol; int fProtocol;
int fOptions; int fOptions;
int fUUID; int fUUID;
int fOpen;


JackClientCheckRequest() JackClientCheckRequest()
{} {}
JackClientCheckRequest(const char* name, int protocol, int options, int uuid)
: JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options), fUUID(uuid)
JackClientCheckRequest(const char* name, int protocol, int options, int uuid, int open = false)
: JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options), fUUID(uuid), fOpen(open)
{ {
snprintf(fName, sizeof(fName), "%s", name); snprintf(fName, sizeof(fName), "%s", name);
} }
@@ -163,7 +164,8 @@ struct JackClientCheckRequest : public JackRequest
CheckRes(trans->Read(&fName, sizeof(fName))); CheckRes(trans->Read(&fName, sizeof(fName)));
CheckRes(trans->Read(&fProtocol, sizeof(int))); CheckRes(trans->Read(&fProtocol, sizeof(int)));
CheckRes(trans->Read(&fOptions, sizeof(int))); CheckRes(trans->Read(&fOptions, sizeof(int)));
return trans->Read(&fUUID, sizeof(int));
CheckRes(trans->Read(&fUUID, sizeof(int)));
return trans->Read(&fOpen, sizeof(int));
} }


int Write(JackChannelTransaction* trans) int Write(JackChannelTransaction* trans)
@@ -172,7 +174,8 @@ struct JackClientCheckRequest : public JackRequest
CheckRes(trans->Write(&fName, sizeof(fName))); CheckRes(trans->Write(&fName, sizeof(fName)));
CheckRes(trans->Write(&fProtocol, sizeof(int))); CheckRes(trans->Write(&fProtocol, sizeof(int)));
CheckRes(trans->Write(&fOptions, sizeof(int))); CheckRes(trans->Write(&fOptions, sizeof(int)));
return trans->Write(&fUUID, sizeof(int));
CheckRes(trans->Write(&fUUID, sizeof(int)));
return trans->Write(&fOpen, sizeof(int));
} }


}; };


+ 0
- 1
common/JackServer.cpp View File

@@ -22,7 +22,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackServerGlobals.h" #include "JackServerGlobals.h"
#include "JackTime.h" #include "JackTime.h"
#include "JackFreewheelDriver.h" #include "JackFreewheelDriver.h"
#include "JackDummyDriver.h"
#include "JackThreadedDriver.h" #include "JackThreadedDriver.h"
#include "JackGlobals.h" #include "JackGlobals.h"
#include "JackLockedEngine.h" #include "JackLockedEngine.h"


+ 9
- 12
common/JackServerAPI.cpp View File

@@ -33,17 +33,14 @@ extern "C"
{ {
#endif #endif


jack_client_t * jack_client_new_aux (const char *client_name,
jack_options_t options,
jack_status_t *status);
jack_client_t * jack_client_open_aux (const char *client_name,
jack_options_t options,
jack_status_t *status, va_list ap);
LIB_EXPORT jack_client_t * jack_client_open (const char *client_name,
jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status);
jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap);

SERVER_EXPORT jack_client_t * jack_client_open (const char *client_name,
jack_options_t options, jack_options_t options,
jack_status_t *status, ...); jack_status_t *status, ...);
LIB_EXPORT int jack_client_close (jack_client_t *client);
LIB_EXPORT int jack_get_client_pid (const char *name);
SERVER_EXPORT int jack_client_close (jack_client_t *client);
SERVER_EXPORT int jack_get_client_pid (const char *name);


#ifdef __cplusplus #ifdef __cplusplus
} }
@@ -153,7 +150,7 @@ jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t opti
} }
} }


LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
SERVER_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
{ {
#ifdef __CLIENTDEBUG__ #ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_client_open"); JackGlobals::CheckContext("jack_client_open");
@@ -176,7 +173,7 @@ LIB_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_opt
} }
} }


LIB_EXPORT int jack_client_close(jack_client_t* ext_client)
SERVER_EXPORT int jack_client_close(jack_client_t* ext_client)
{ {
#ifdef __CLIENTDEBUG__ #ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_client_close"); JackGlobals::CheckContext("jack_client_close");
@@ -198,7 +195,7 @@ LIB_EXPORT int jack_client_close(jack_client_t* ext_client)
return res; return res;
} }


LIB_EXPORT int jack_get_client_pid(const char *name)
SERVER_EXPORT int jack_get_client_pid(const char *name)
{ {
return (JackServerGlobals::fInstance != NULL) return (JackServerGlobals::fInstance != NULL)
? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name) ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name)


+ 12
- 9
common/JackShmMem.h View File

@@ -156,11 +156,12 @@ class JackShmReadWritePtr
{ {
if (fInfo.index < 0 && index >= 0) { if (fInfo.index < 0 && index >= 0) {
jack_log("JackShmReadWritePtr::Init %ld %ld", index, fInfo.index); jack_log("JackShmReadWritePtr::Init %ld %ld", index, fInfo.index);
if (jack_initialize_shm(server_name) < 0)
throw - 1;
if (jack_initialize_shm(server_name) < 0) {
throw std::bad_alloc();
}
fInfo.index = index; fInfo.index = index;
if (jack_attach_lib_shm(&fInfo)) { if (jack_attach_lib_shm(&fInfo)) {
throw - 2;
throw std::bad_alloc();
} }
GetShmAddress()->LockMemory(); GetShmAddress()->LockMemory();
} }
@@ -237,11 +238,12 @@ class JackShmReadWritePtr1
{ {
if (fInfo.index < 0 && index >= 0) { if (fInfo.index < 0 && index >= 0) {
jack_log("JackShmReadWritePtr1::Init %ld %ld", index, fInfo.index); jack_log("JackShmReadWritePtr1::Init %ld %ld", index, fInfo.index);
if (jack_initialize_shm(server_name) < 0)
throw - 1;
if (jack_initialize_shm(server_name) < 0) {
throw std::bad_alloc();
}
fInfo.index = index; fInfo.index = index;
if (jack_attach_lib_shm(&fInfo)) { if (jack_attach_lib_shm(&fInfo)) {
throw - 2;
throw std::bad_alloc();
} }
/* /*
nobody else needs to access this shared memory any more, so nobody else needs to access this shared memory any more, so
@@ -324,11 +326,12 @@ class JackShmReadPtr
{ {
if (fInfo.index < 0 && index >= 0) { if (fInfo.index < 0 && index >= 0) {
jack_log("JackShmPtrRead::Init %ld %ld", index, fInfo.index); jack_log("JackShmPtrRead::Init %ld %ld", index, fInfo.index);
if (jack_initialize_shm(server_name) < 0)
throw - 1;
if (jack_initialize_shm(server_name) < 0) {
throw std::bad_alloc();
}
fInfo.index = index; fInfo.index = index;
if (jack_attach_lib_shm_read(&fInfo)) { if (jack_attach_lib_shm_read(&fInfo)) {
throw - 2;
throw std::bad_alloc();
} }
GetShmAddress()->LockMemory(); GetShmAddress()->LockMemory();
} }


+ 21
- 17
common/JackThreadedDriver.cpp View File

@@ -21,6 +21,7 @@
#include "JackSystemDeps.h" #include "JackSystemDeps.h"
#include "JackThreadedDriver.h" #include "JackThreadedDriver.h"
#include "JackError.h" #include "JackError.h"
#include "JackTools.h"
#include "JackGlobals.h" #include "JackGlobals.h"
#include "JackEngineControl.h" #include "JackEngineControl.h"


@@ -67,11 +68,6 @@ int JackThreadedDriver::Process()
return fDriver->Process(); return fDriver->Process();
} }


int JackThreadedDriver::ProcessNull()
{
return fDriver->ProcessNull();
}

int JackThreadedDriver::Attach() int JackThreadedDriver::Attach()
{ {
return fDriver->Attach(); return fDriver->Attach();
@@ -228,22 +224,30 @@ bool JackThreadedDriver::Execute()
bool JackThreadedDriver::Init() bool JackThreadedDriver::Init()
{ {
if (fDriver->Initialize()) { if (fDriver->Initialize()) {
if (fDriver->IsRealTime()) {
jack_log("JackThreadedDriver::Init IsRealTime");
// Will do "something" on OSX only...
GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000;
GetEngineControl()->fComputation = ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000;
fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) {
jack_error("AcquireSelfRealTime error");
} else {
set_threaded_log_function();
}
}
SetRealTime();
return true; return true;
} else { } else {
return false; return false;
} }
} }


void JackThreadedDriver::SetRealTime()
{
if (fDriver->IsRealTime()) {
jack_log("JackThreadedDriver::Init real-time");
// Will do "something" on OSX only...
GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000;
GetEngineControl()->fComputation = JackTools::ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000;
fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) {
jack_error("AcquireSelfRealTime error");
} else {
set_threaded_log_function();
}
} else {
jack_log("JackThreadedDriver::Init non non-realtime ");
}
}


} // end of namespace } // end of namespace

+ 2
- 13
common/JackThreadedDriver.h View File

@@ -39,6 +39,8 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi
JackThread fThread; JackThread fThread;
JackDriver* fDriver; JackDriver* fDriver;


void SetRealTime();

public: public:


JackThreadedDriver(JackDriver* driver); JackThreadedDriver(JackDriver* driver);
@@ -72,7 +74,6 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi
virtual int Close(); virtual int Close();


virtual int Process(); virtual int Process();
virtual int ProcessNull();


virtual int Attach(); virtual int Attach();
virtual int Detach(); virtual int Detach();
@@ -110,18 +111,6 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi
virtual bool Execute(); virtual bool Execute();
virtual bool Init(); virtual bool Init();


// For OSX only
int ComputationMicroSec(int buffer_size)
{
if (buffer_size < 128) {
return 500;
} else if (buffer_size < 256) {
return 300;
} else {
return 100;
}
}

}; };


} // end of namespace } // end of namespace


+ 86
- 0
common/JackTimedDriver.cpp View File

@@ -0,0 +1,86 @@
/*
Copyright (C) 2001 Paul Davis
Copyright (C) 2004-2008 Grame

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#include "JackTimedDriver.h"
#include "JackEngineControl.h"
#include "JackTime.h"
#include "JackCompilerDeps.h"
#include <iostream>
#include <unistd.h>
#include <math.h>

namespace Jack
{

int JackTimedDriver::FirstCycle(jack_time_t cur_time)
{
fAnchorTime = cur_time;
return int((double(fEngineControl->fBufferSize) * 1000000) / double(fEngineControl->fSampleRate));
}
int JackTimedDriver::CurrentCycle(jack_time_t cur_time)
{
return int((double(fCycleCount) * double(fEngineControl->fBufferSize) * 1000000.) / double(fEngineControl->fSampleRate)) - (cur_time - fAnchorTime);
}

int JackTimedDriver::ProcessAux()
{
jack_time_t cur_time = GetMicroSeconds();
int wait_time;
if (fCycleCount++ == 0) {
wait_time = FirstCycle(cur_time);
} else {
wait_time = CurrentCycle(cur_time);
}
if (wait_time < 0) {
NotifyXRun(cur_time, float(cur_time -fBeginDateUst));
fCycleCount = 0;
wait_time = 0;
}
//jack_log("JackTimedDriver::Process wait_time = %d", wait_time);
JackSleep(wait_time);
return 0;
}

int JackTimedDriver::Process()
{
JackDriver::CycleTakeBeginTime();
JackAudioDriver::Process();
return ProcessAux();
}

int JackTimedDriver::ProcessNull()
{
JackDriver::CycleTakeBeginTime();
if (fEngineControl->fSyncMode) {
ProcessGraphSyncMaster();
} else {
ProcessGraphAsyncMaster();
}
return ProcessAux();
}

} // end of namespace

+ 66
- 0
common/JackTimedDriver.h View File

@@ -0,0 +1,66 @@
/*
Copyright (C) 2001 Paul Davis
Copyright (C) 2004-2008 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 __JackTimedDriver__
#define __JackTimedDriver__

#include "JackAudioDriver.h"

namespace Jack
{

/*!
\brief The timed driver.
*/

class SERVER_EXPORT JackTimedDriver : public JackAudioDriver
{
private:

int fCycleCount;
jack_time_t fAnchorTime;
int FirstCycle(jack_time_t cur_time);
int CurrentCycle(jack_time_t cur_time);
int ProcessAux();

public:

JackTimedDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
: JackAudioDriver(name, alias, engine, table), fCycleCount(0), fAnchorTime(0)
{}
virtual ~JackTimedDriver()
{}

virtual int Process();
virtual int ProcessNull();
// BufferSize can be changed
bool IsFixedBufferSize()
{
return false;
}

};

} // end of namespace

#endif

+ 13
- 1
common/JackTools.h View File

@@ -68,8 +68,20 @@ namespace Jack
static void CleanupFiles ( const char* server_name ); static void CleanupFiles ( const char* server_name );
static int GetTmpdir(); static int GetTmpdir();
static void RewriteName ( const char* name, char* new_name ); static void RewriteName ( const char* name, char* new_name );
static void ThrowJackNetException(); static void ThrowJackNetException();

// For OSX only
static int ComputationMicroSec(int buffer_size)
{
if (buffer_size < 128) {
return 500;
} else if (buffer_size < 256) {
return 300;
} else {
return 100;
}
}
}; };


/*! /*!


+ 19
- 18
common/JackWaitThreadedDriver.cpp View File

@@ -25,6 +25,7 @@
#include "JackEngineControl.h" #include "JackEngineControl.h"
#include "JackException.h" #include "JackException.h"
#include "JackError.h" #include "JackError.h"
#include "JackTools.h"


namespace Jack namespace Jack
{ {
@@ -37,44 +38,44 @@ bool JackWaitThreadedDriver::Init()
bool JackWaitThreadedDriver::Execute() bool JackWaitThreadedDriver::Execute()
{ {
try { try {

SetRealTime();

// Process a null cycle until NetDriver has started // Process a null cycle until NetDriver has started
while (!fStarter.fRunning && fThread.GetStatus() == JackThread::kRunning) { while (!fStarter.fRunning && fThread.GetStatus() == JackThread::kRunning) {
fDriver->ProcessNull();
}

// Set RT
if (fDriver->IsRealTime()) {
jack_log("JackWaitThreadedDriver::Init IsRealTime");
// Will do "something" on OSX only...
GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000;
GetEngineControl()->fComputation = ComputationMicroSec(GetEngineControl()->fBufferSize) * 1000;
fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) {
jack_error("AcquireSelfRealTime error");
} else {
set_threaded_log_function();
}
// Use the base method
assert(static_cast<JackTimedDriver*>(fDriver));
static_cast<JackTimedDriver*>(fDriver)->ProcessNull();
} }


// Switch to keep running even in case of error // Switch to keep running even in case of error
while (fThread.GetStatus() == JackThread::kRunning) { while (fThread.GetStatus() == JackThread::kRunning) {
fDriver->Process(); fDriver->Process();
} }

return false; return false;

} catch (JackNetException& e) { } catch (JackNetException& e) {

e.PrintMessage(); e.PrintMessage();
jack_info("Driver is restarted"); jack_info("Driver is restarted");
fThread.DropSelfRealTime(); fThread.DropSelfRealTime();

// Thread has been stopped...
if (fThread.GetStatus() == JackThread::kIdle) {
return false;
}

// Thread in kIniting status again... // Thread in kIniting status again...
fThread.SetStatus(JackThread::kIniting); fThread.SetStatus(JackThread::kIniting);
if (Init()) { if (Init()) {
// Thread in kRunning status again... // Thread in kRunning status again...
fThread.SetStatus(JackThread::kRunning); fThread.SetStatus(JackThread::kRunning);
return true; return true;
} else {
return false;
} }
}

return false;
}
} }


} // end of namespace } // end of namespace

+ 3
- 3
common/JackWaitThreadedDriver.h View File

@@ -22,7 +22,7 @@
#define __JackWaitThreadedDriver__ #define __JackWaitThreadedDriver__


#include "JackThreadedDriver.h" #include "JackThreadedDriver.h"
#include "JackDriver.h"
#include "JackTimedDriver.h"


namespace Jack namespace Jack
{ {
@@ -31,7 +31,7 @@ namespace Jack
\brief To be used as a wrapper of JackNetDriver. \brief To be used as a wrapper of JackNetDriver.


The idea is to behave as the "dummy" driver, until the network connection is really started and processing starts. The idea is to behave as the "dummy" driver, until the network connection is really started and processing starts.
The Execute method will call the ProcessNull method until the decorated driver Init method returns.
The Execute method will call the Process method from the base JackTimedDriver, until the decorated driver Init method returns.
A helper JackDriverStarter thread is used for that purpose. A helper JackDriverStarter thread is used for that purpose.
*/ */


@@ -81,7 +81,7 @@ class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver
public: public:


JackWaitThreadedDriver(JackDriver* net_driver) JackWaitThreadedDriver(JackDriver* net_driver)
:JackThreadedDriver(net_driver), fStarter(net_driver)
: JackThreadedDriver(net_driver), fStarter(net_driver)
{} {}
virtual ~JackWaitThreadedDriver() virtual ~JackWaitThreadedDriver()
{} {}


+ 3
- 3
common/driver_interface.h View File

@@ -115,16 +115,16 @@ typedef struct {
} }
jack_driver_desc_filler_t; jack_driver_desc_filler_t;


LIB_EXPORT int jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr);
SERVER_EXPORT int jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr);


LIB_EXPORT jack_driver_desc_t * /* newlly allocated driver descriptor, NULL on failure */
SERVER_EXPORT jack_driver_desc_t * /* newlly allocated driver descriptor, NULL on failure */
jack_driver_descriptor_construct( jack_driver_descriptor_construct(
const char * name, /* driver name */ const char * name, /* driver name */
const char * description, /* driver description */ const char * description, /* driver description */
jack_driver_desc_filler_t * filler); /* Pointer to stack var to be supplied to jack_driver_descriptor_add_parameter() as well. jack_driver_desc_filler_t * filler); /* Pointer to stack var to be supplied to jack_driver_descriptor_add_parameter() as well.
Can be NULL for drivers that have no parameters. */ Can be NULL for drivers that have no parameters. */


LIB_EXPORT int /* 0 on failure */
SERVER_EXPORT int /* 0 on failure */
jack_driver_descriptor_add_parameter( jack_driver_descriptor_add_parameter(
jack_driver_desc_t * driver_descr, /* pointer to driver descriptor as returned by jack_driver_descriptor_construct() */ jack_driver_desc_t * driver_descr, /* pointer to driver descriptor as returned by jack_driver_descriptor_construct() */
jack_driver_desc_filler_t * filler, /* Pointer to the stack var that was supplied to jack_driver_descriptor_add_parameter(). */ jack_driver_desc_filler_t * filler, /* Pointer to the stack var that was supplied to jack_driver_descriptor_add_parameter(). */


+ 0
- 1
common/jack/jack.h View File

@@ -735,7 +735,6 @@ int jack_port_unregister (jack_client_t *, jack_port_t *) JACK_OPTIONAL_WEAK_EXP
* Port buffers have to be retrieved in each callback for proper functionning. * Port buffers have to be retrieved in each callback for proper functionning.
*/ */
void * jack_port_get_buffer (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; void * jack_port_get_buffer (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT;
void * jack_port_get_buffer_nulled(jack_port_t* port, jack_nframes_t frames) JACK_OPTIONAL_WEAK_EXPORT;


/** /**
* @return the full name of the jack_port_t (including the @a * @return the full name of the jack_port_t (including the @a


+ 22
- 31
common/jack/net.h View File

@@ -28,25 +28,18 @@ extern "C"
#include <jack/systemdeps.h> #include <jack/systemdeps.h>
#include <jack/types.h> #include <jack/types.h>


#define DEFAULT_MULTICAST_IP "225.3.19.154"
#define DEFAULT_PORT 19000
#define DEFAULT_MTU 1500
#define MASTER_NAME_SIZE 256
#define DEFAULT_MULTICAST_IP "225.3.19.154"
#define DEFAULT_PORT 19000
#define DEFAULT_MTU 1500
#define MASTER_NAME_SIZE 256


#define SOCKET_ERROR -1 #define SOCKET_ERROR -1


enum JackNetMode {

JackFastMode = 'f',
JackNormalMode = 'n',
JackSlowMode = 's',
};

enum JackNetEncoder { enum JackNetEncoder {


JackFloatEncoder = 0, // Samples are transmitted as float
JackIntEncoder = 1, // Samples are transmitted as 16 bits integer
JackCeltEncoder = 2, // Samples are transmitted using CELT codec (http://www.celt-codec.org/)
JackFloatEncoder = 0, // samples are transmitted as float
JackIntEncoder = 1, // samples are transmitted as 16 bits integer
JackCeltEncoder = 2, // samples are transmitted using CELT codec (http://www.celt-codec.org/)
}; };


typedef struct { typedef struct {
@@ -57,9 +50,9 @@ typedef struct {
int midi_output; // to master or from slave (-1 for get master MIDI physical inputs) int midi_output; // to master or from slave (-1 for get master MIDI physical inputs)
int mtu; // network Maximum Transmission Unit int mtu; // network Maximum Transmission Unit
int time_out; // in second, -1 means in infinite int time_out; // in second, -1 means in infinite
int encoder; // Encoder type (one of JackNetEncoder)
int encoder; // encoder type (one of JackNetEncoder)
int kbps; // KB per second for CELT encoder int kbps; // KB per second for CELT encoder
char mode; // one of JackNetMode
int latency; // network latency


} jack_slave_t; } jack_slave_t;


@@ -111,7 +104,7 @@ int jack_net_slave_close(jack_net_slave_t* net);
* @param audio_output_buffer an array of audio output buffers (to master) * @param audio_output_buffer an array of audio output buffers (to master)
* @param midi_output number of MIDI outputs * @param midi_output number of MIDI outputs
* @param midi_output_buffer an array of MIDI output buffers (to master) * @param midi_output_buffer an array of MIDI output buffers (to master)
* @param arg pointer to a client supplied structure supplied by jack_set_net_process_callback().
* @param arg pointer to a client supplied structure supplied by jack_set_net_process_callback()
* *
* @return zero on success, non-zero on error * @return zero on success, non-zero on error
*/ */
@@ -155,16 +148,16 @@ int jack_net_slave_deactivate(jack_net_slave_t* net);
/** /**
* Prototype for BufferSize callback. * Prototype for BufferSize callback.
* @param nframes buffer size * @param nframes buffer size
* @param arg pointer to a client supplied structure supplied by jack_set_net_buffer_size_callback().
* @param arg pointer to a client supplied structure supplied by jack_set_net_buffer_size_callback()
* *
* @return zero on success, non-zero on error * @return zero on success, non-zero on error
*/ */
typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg); typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg);


/** /**
* Prototype for SampleRate callback
* Prototype for SampleRate callback.
* @param nframes sample rate * @param nframes sample rate
* @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback().
* @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback()
* *
* @return zero on success, non-zero on error * @return zero on success, non-zero on error
*/ */
@@ -191,8 +184,8 @@ int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveB
int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg);


/** /**
* Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again.)
* @param arg pointer to a client supplied structure supplied by jack_set_net_shutdown_callback().
* Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again).
* @param arg pointer to a client supplied structure supplied by jack_set_net_shutdown_callback()
*/ */
typedef void (*JackNetSlaveShutdownCallback)(void* data); typedef void (*JackNetSlaveShutdownCallback)(void* data);


@@ -207,8 +200,7 @@ typedef void (*JackNetSlaveShutdownCallback)(void* data);
int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg);


/** /**
* jack_net_master_t is an opaque type. You may only access it using the
* API provided.
* jack_net_master_t is an opaque type, you may only access it using the API provided.
*/ */
typedef struct _jack_net_master jack_net_master_t; typedef struct _jack_net_master jack_net_master_t;


@@ -224,7 +216,7 @@ typedef struct _jack_net_master jack_net_master_t;
jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result); jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result);


/** /**
* Close the network connection with the master machine.
* Close the network connection with the slave machine.
* @param net the network connection to be closed * @param net the network connection to be closed
* *
* @return 0 on success, otherwise a non-zero error code * @return 0 on success, otherwise a non-zero error code
@@ -232,7 +224,7 @@ jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* na
int jack_net_master_close(jack_net_master_t* net); int jack_net_master_close(jack_net_master_t* net);


/** /**
* Receive sync and data from the network
* Receive sync and data from the network.
* @param net the network connection * @param net the network connection
* @param audio_input number of audio inputs * @param audio_input number of audio inputs
* @param audio_input_buffer an array of audio input buffers * @param audio_input_buffer an array of audio input buffers
@@ -244,7 +236,7 @@ int jack_net_master_close(jack_net_master_t* net);
int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer);


/** /**
* Send sync and data to the network
* Send sync and data to the network.
* @param net the network connection * @param net the network connection
* @param audio_output number of audio outputs * @param audio_output number of audio outputs
* @param audio_output_buffer an array of audio output buffers * @param audio_output_buffer an array of audio output buffers
@@ -258,8 +250,7 @@ int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio
// Experimental Adapter API // Experimental Adapter API


/** /**
* jack_adapter_t is an opaque type. You may only access it using the
* API provided.
* jack_adapter_t is an opaque type, you may only access it using the API provided.
*/ */
typedef struct _jack_adapter jack_adapter_t; typedef struct _jack_adapter jack_adapter_t;


@@ -297,7 +288,7 @@ int jack_destroy_adapter(jack_adapter_t* adapter);
void jack_flush_adapter(jack_adapter_t* adapter); void jack_flush_adapter(jack_adapter_t* adapter);


/** /**
* Push input to and pull output from adapter ringbuffer
* Push input to and pull output from adapter ringbuffer.
* @param adapter the adapter * @param adapter the adapter
* @param input an array of audio input buffers * @param input an array of audio input buffers
* @param output an array of audio ouput buffers * @param output an array of audio ouput buffers
@@ -308,7 +299,7 @@ void jack_flush_adapter(jack_adapter_t* adapter);
int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames); int jack_adapter_push_and_pull(jack_adapter_t* adapter, float** input, float** output, unsigned int frames);


/** /**
* Pull input to and push output from adapter ringbuffer
* Pull input to and push output from adapter ringbuffer.
* @param adapter the adapter * @param adapter the adapter
* @param input an array of audio input buffers * @param input an array of audio input buffers
* @param output an array of audio ouput buffers * @param output an array of audio ouput buffers


+ 1
- 0
common/wscript View File

@@ -114,6 +114,7 @@ def build(bld):
serverlib.source = [] + common_libsources serverlib.source = [] + common_libsources
serverlib.source += [ serverlib.source += [
'JackAudioDriver.cpp', 'JackAudioDriver.cpp',
'JackTimedDriver.cpp',
'JackMidiDriver.cpp', 'JackMidiDriver.cpp',
'JackDriver.cpp', 'JackDriver.cpp',
'JackEngine.cpp', 'JackEngine.cpp',


+ 2
- 2
example-clients/alias.c View File

@@ -55,7 +55,7 @@ main (int argc, char *argv[])
int option_index; int option_index;
extern int optind; extern int optind;
jack_port_t* port; jack_port_t* port;
struct option long_options[] = { struct option long_options[] = {
{ "unalias", 0, 0, 'u' }, { "unalias", 0, 0, 'u' },
{ "help", 0, 0, 'h' }, { "help", 0, 0, 'h' },
@@ -129,5 +129,5 @@ main (int argc, char *argv[])
jack_client_close (client); jack_client_close (client);


return ret; return ret;
} }

+ 1
- 1
example-clients/bufsize.c View File

@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
jack_on_shutdown(client, jack_shutdown, 0); jack_on_shutdown(client, jack_shutdown, 0);


if (just_print_bufsize) { if (just_print_bufsize) {
fprintf(stdout, "%d\n", jack_get_buffer_size( client ) );
fprintf(stdout, "buffer size = %d sample rate = %d\n", jack_get_buffer_size(client), jack_get_sample_rate(client));
rc=0; rc=0;
} }
else else


+ 9
- 9
example-clients/capture_client.c View File

@@ -1,7 +1,7 @@
/* /*
Copyright (C) 2001 Paul Davis Copyright (C) 2001 Paul Davis
Copyright (C) 2003 Jack O'Quin Copyright (C) 2003 Jack O'Quin
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
@@ -100,7 +100,7 @@ disk_thread (void *arg)
info->status = EIO; /* write failed */ info->status = EIO; /* write failed */
goto done; goto done;
} }
if (++total_captured >= info->duration) { if (++total_captured >= info->duration) {
printf ("disk thread finished\n"); printf ("disk thread finished\n");
goto done; goto done;
@@ -116,7 +116,7 @@ disk_thread (void *arg)
free (framebuf); free (framebuf);
return 0; return 0;
} }
static int static int
process (jack_nframes_t nframes, void *arg) process (jack_nframes_t nframes, void *arg)
{ {
@@ -168,10 +168,10 @@ setup_disk_thread (jack_thread_info_t *info)
{ {
SF_INFO sf_info; SF_INFO sf_info;
int short_mask; int short_mask;
sf_info.samplerate = jack_get_sample_rate (info->client); sf_info.samplerate = jack_get_sample_rate (info->client);
sf_info.channels = info->channels; sf_info.channels = info->channels;
switch (info->bitdepth) { switch (info->bitdepth) {
case 8: short_mask = SF_FORMAT_PCM_U8; case 8: short_mask = SF_FORMAT_PCM_U8;
break; break;
@@ -183,7 +183,7 @@ setup_disk_thread (jack_thread_info_t *info)
break; break;
default: short_mask = SF_FORMAT_PCM_16; default: short_mask = SF_FORMAT_PCM_16;
break; break;
}
}
sf_info.format = SF_FORMAT_WAV|short_mask; sf_info.format = SF_FORMAT_WAV|short_mask;


if ((info->sf = sf_open (info->path, SFM_WRITE, &sf_info)) == NULL) { if ((info->sf = sf_open (info->path, SFM_WRITE, &sf_info)) == NULL) {
@@ -253,7 +253,7 @@ setup_ports (int sources, char *source_names[], jack_thread_info_t *info)
fprintf (stderr, "cannot connect input port %s to %s\n", jack_port_name (ports[i]), source_names[i]); fprintf (stderr, "cannot connect input port %s to %s\n", jack_port_name (ports[i]), source_names[i]);
jack_client_close (info->client); jack_client_close (info->client);
exit (1); exit (1);
}
}
} }


info->can_process = 1; /* process() can start, now */ info->can_process = 1; /* process() can start, now */
@@ -315,7 +315,7 @@ main (int argc, char *argv[])
} }


if ((client = jack_client_open ("jackrec", JackNullOption, NULL)) == 0) { if ((client = jack_client_open ("jackrec", JackNullOption, NULL)) == 0) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
exit (1); exit (1);
} }


@@ -333,7 +333,7 @@ main (int argc, char *argv[])
} }


setup_ports (argc - optind, &argv[optind], &thread_info); setup_ports (argc - optind, &argv[optind], &thread_info);
/* install a signal handler to properly quits jack client */ /* install a signal handler to properly quits jack client */
signal(SIGQUIT, signal_handler); signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);


+ 1
- 1
example-clients/connect.c View File

@@ -133,7 +133,7 @@ main (int argc, char *argv[])
/* try to become a client of the JACK server */ /* try to become a client of the JACK server */


if ((client = jack_client_open (my_name, options, &status, server_name)) == 0) { if ((client = jack_client_open (my_name, options, &status, server_name)) == 0) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
return 1; return 1;
} }




+ 2
- 2
example-clients/freewheel.c View File

@@ -2,7 +2,7 @@
* freewheel - start/stop JACK "freewheeling" mode * freewheel - start/stop JACK "freewheeling" mode
* *
* Copyright (C) 2003 Paul Davis. * Copyright (C) 2003 Paul Davis.
*
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@@ -58,7 +58,7 @@ static void parse_arguments(int argc, char *argv[])
} }
} }


int
int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
parse_arguments (argc, argv); parse_arguments (argc, argv);


+ 7
- 7
example-clients/impulse_grabber.c View File

@@ -36,7 +36,7 @@ unsigned long response_duration;
unsigned long response_pos; unsigned long response_pos;
int grab_finished = 0; int grab_finished = 0;
jack_client_t *client; jack_client_t *client;
static void signal_handler(int sig) static void signal_handler(int sig)
{ {
jack_client_close(client); jack_client_close(client);
@@ -60,7 +60,7 @@ process (jack_nframes_t nframes, void *arg)
} }
if (response_pos >= response_duration) { if (response_pos >= response_duration) {
grab_finished = 1; grab_finished = 1;
}
}
for (i=0; i<nframes; i++) { for (i=0; i<nframes; i++) {
out[i] = 0.0f;; out[i] = 0.0f;;
} }
@@ -72,7 +72,7 @@ process (jack_nframes_t nframes, void *arg)
impulse_sent = 1; impulse_sent = 1;
} }


return 0;
return 0;
} }


static void static void
@@ -132,7 +132,7 @@ main (int argc, char *argv[])
/* try to become a client of the JACK server */ /* try to become a client of the JACK server */


if ((client = jack_client_open("impulse_grabber", JackNullOption, NULL)) == 0) { if ((client = jack_client_open("impulse_grabber", JackNullOption, NULL)) == 0) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
return 1; return 1;
} }


@@ -149,7 +149,7 @@ main (int argc, char *argv[])


jack_on_shutdown (client, jack_shutdown, 0); jack_on_shutdown (client, jack_shutdown, 0);


/* display the current sample rate. once the client is activated
/* display the current sample rate. once the client is activated
(see below), you should rely on your own sample rate (see below), you should rely on your own sample rate
callback (see above) for this value. callback (see above) for this value.
*/ */
@@ -187,7 +187,7 @@ main (int argc, char *argv[])
} }


free (ports); free (ports);
if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) {
fprintf(stderr, "Cannot find any physical playback ports"); fprintf(stderr, "Cannot find any physical playback ports");
exit(1); exit(1);
@@ -198,7 +198,7 @@ main (int argc, char *argv[])
} }


free (ports); free (ports);
/* install a signal handler to properly quits jack client */ /* install a signal handler to properly quits jack client */
signal(SIGQUIT, signal_handler); signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);


+ 3
- 3
example-clients/ipunload.c View File

@@ -85,9 +85,9 @@ main (int argc, char *argv[])
} else { } else {
fprintf (stdout, "%s unloaded.\n", client_name); fprintf (stdout, "%s unloaded.\n", client_name);
} }
jack_client_close(client); jack_client_close(client);
return 0; return 0;
} }

+ 2
- 1
example-clients/lsp.c View File

@@ -20,7 +20,7 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <string.h> #include <string.h>
#include <getopt.h>
#include <getopt.h>
#include <inttypes.h> #include <inttypes.h>
#include <jack/jack.h> #include <jack/jack.h>


@@ -246,3 +246,4 @@ error:
jack_client_close (client); jack_client_close (client);
exit (0); exit (0);
} }


+ 22
- 10
example-clients/metro.c View File

@@ -1,6 +1,6 @@
/* /*
Copyright (C) 2002 Anthony Van Groningen Copyright (C) 2002 Anthony Van Groningen
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
@@ -69,18 +69,21 @@ usage ()
} }


static void static void
process_silence (jack_nframes_t nframes)
process_silence (jack_nframes_t nframes)
{ {
sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes); sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes);
memset (buffer, 0, sizeof (jack_default_audio_sample_t) * nframes); memset (buffer, 0, sizeof (jack_default_audio_sample_t) * nframes);
} }


jack_nframes_t last_time;
jack_time_t last_micro_time;

static void static void
process_audio (jack_nframes_t nframes)
process_audio (jack_nframes_t nframes)
{ {
sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes); sample_t *buffer = (sample_t *) jack_port_get_buffer (output_port, nframes);
jack_nframes_t frames_left = nframes; jack_nframes_t frames_left = nframes;
while (wave_length - offset < frames_left) { while (wave_length - offset < frames_left) {
memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * (wave_length - offset)); memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * (wave_length - offset));
frames_left -= wave_length - offset; frames_left -= wave_length - offset;
@@ -90,6 +93,15 @@ process_audio (jack_nframes_t nframes)
memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * frames_left); memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * frames_left);
offset += frames_left; offset += frames_left;
} }

/*
jack_nframes_t cur_time = jack_frame_time(client);
jack_time_t cur_micro_time = jack_get_time();

printf("jack_frame_timed %lld micro %lld delta %d\n", cur_time, (cur_micro_time - last_micro_time), cur_time - last_time);
last_time = cur_time;
last_micro_time = cur_micro_time;
*/
} }


static int static int
@@ -141,7 +153,7 @@ main (int argc, char *argv[])
{"verbose", 0, 0, 'v'}, {"verbose", 0, 0, 'v'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
switch (opt) { switch (opt) {
case 'f': case 'f':
@@ -193,7 +205,7 @@ main (int argc, char *argv[])
transport_aware = 1; transport_aware = 1;
break; break;
default: default:
fprintf (stderr, "unknown option %c\n", opt);
fprintf (stderr, "unknown option %c\n", opt);
case 'h': case 'h':
usage (); usage ();
return -1; return -1;
@@ -211,7 +223,7 @@ main (int argc, char *argv[])
strcpy (client_name, "metro"); strcpy (client_name, "metro");
} }
if ((client = jack_client_open (client_name, JackNoStartServer, &status)) == 0) { if ((client = jack_client_open (client_name, JackNoStartServer, &status)) == 0) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
return 1; return 1;
} }
jack_set_process_callback (client, process, 0); jack_set_process_callback (client, process, 0);
@@ -259,7 +271,7 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot activate client\n"); fprintf (stderr, "cannot activate client\n");
goto error; goto error;
} }
/* install a signal handler to properly quits jack client */ /* install a signal handler to properly quits jack client */
#ifdef WIN32 #ifdef WIN32
signal(SIGINT, signal_handler); signal(SIGINT, signal_handler);
@@ -280,9 +292,9 @@ main (int argc, char *argv[])
sleep(1); sleep(1);
#endif #endif
}; };
jack_client_close(client); jack_client_close(client);
error: error:
free(amp); free(amp);
free(wave); free(wave);


+ 4
- 4
example-clients/midiseq.c View File

@@ -1,6 +1,6 @@
/* /*
Copyright (C) 2004 Ian Esten Copyright (C) 2004 Ian Esten
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
@@ -93,7 +93,7 @@ int main(int narg, char **args)
} }
if((client = jack_client_open (args[1], JackNullOption, NULL)) == 0) if((client = jack_client_open (args[1], JackNullOption, NULL)) == 0)
{ {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
return 1; return 1;
} }
jack_set_process_callback (client, process, 0); jack_set_process_callback (client, process, 0);
@@ -117,7 +117,7 @@ int main(int narg, char **args)
fprintf (stderr, "cannot activate client"); fprintf (stderr, "cannot activate client");
return 1; return 1;
} }
/* install a signal handler to properly quits jack client */ /* install a signal handler to properly quits jack client */
signal(SIGQUIT, signal_handler); signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);
@@ -128,7 +128,7 @@ int main(int narg, char **args)
while (1) { while (1) {
sleep(1); sleep(1);
}; };
jack_client_close(client); jack_client_close(client);
exit (0); exit (0);
} }

+ 6
- 6
example-clients/midisine.c View File

@@ -1,6 +1,6 @@
/* /*
Copyright (C) 2004 Ian Esten Copyright (C) 2004 Ian Esten
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
@@ -76,7 +76,7 @@ static int process(jack_nframes_t nframes, void *arg)
if ((in_event.time == i) && (event_index < event_count)) if ((in_event.time == i) && (event_index < event_count))
{ {
if (((*(in_event.buffer) & 0xf0)) == 0x90) if (((*(in_event.buffer) & 0xf0)) == 0x90)
{
{
/* note on */ /* note on */
note = *(in_event.buffer + 1); note = *(in_event.buffer + 1);
if (*(in_event.buffer + 2) == 0) { if (*(in_event.buffer + 2) == 0) {
@@ -99,7 +99,7 @@ static int process(jack_nframes_t nframes, void *arg)
ramp = (ramp > 1.0) ? ramp - 2.0 : ramp; ramp = (ramp > 1.0) ? ramp - 2.0 : ramp;
out[i] = note_on*sin(2*M_PI*ramp); out[i] = note_on*sin(2*M_PI*ramp);
} }
return 0;
return 0;
} }


static int srate(jack_nframes_t nframes, void *arg) static int srate(jack_nframes_t nframes, void *arg)
@@ -118,10 +118,10 @@ int main(int narg, char **args)
{ {
if ((client = jack_client_open("midisine", JackNullOption, NULL)) == 0) if ((client = jack_client_open("midisine", JackNullOption, NULL)) == 0)
{ {
fprintf(stderr, "jack server not running?\n");
fprintf(stderr, "JACK server not running?\n");
return 1; return 1;
} }
calc_note_frqs(jack_get_sample_rate (client)); calc_note_frqs(jack_get_sample_rate (client));


jack_set_process_callback (client, process, 0); jack_set_process_callback (client, process, 0);
@@ -138,7 +138,7 @@ int main(int narg, char **args)
fprintf(stderr, "cannot activate client"); fprintf(stderr, "cannot activate client");
return 1; return 1;
} }
/* install a signal handler to properly quits jack client */ /* install a signal handler to properly quits jack client */
signal(SIGQUIT, signal_handler); signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);


+ 1
- 1
example-clients/monitor_client.c View File

@@ -42,7 +42,7 @@ main (int argc, char *argv[])
} }


if ((client = jack_client_open ("input monitoring", JackNullOption, NULL)) == 0) { if ((client = jack_client_open ("input monitoring", JackNullOption, NULL)) == 0) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
return 1; return 1;
} }




+ 1
- 1
example-clients/netmaster.c View File

@@ -108,7 +108,7 @@ main (int argc, char *argv[])
printf("Waiting for a slave...\n"); printf("Waiting for a slave...\n");


if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_master", &request, &result)) == 0) { if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_master", &request, &result)) == 0) {
fprintf(stderr, "jack server not running?\n");
fprintf(stderr, "NetJack master can not be opened\n");
return 1; return 1;
} }




+ 23
- 23
example-clients/netslave.c View File

@@ -1,6 +1,6 @@
/* /*
Copyright (C) 2009 Grame Copyright (C) 2009 Grame
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
@@ -55,18 +55,18 @@ static void net_shutdown(void* data)
} }


static int net_process(jack_nframes_t buffer_size, static int net_process(jack_nframes_t buffer_size,
int audio_input,
float** audio_input_buffer,
int audio_input,
float** audio_input_buffer,
int midi_input, int midi_input,
void** midi_input_buffer, void** midi_input_buffer,
int audio_output, int audio_output,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer,
void* data) void* data)
{ {
int i; int i;
// Copy input to output // Copy input to output
for (i = 0; i < audio_input; i++) { for (i = 0; i < audio_input; i++) {
memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float));
@@ -84,7 +84,7 @@ main (int argc, char *argv[])
const char *options = "C:P:a:p:"; const char *options = "C:P:a:p:";
int option_index; int option_index;
int opt; int opt;
struct option long_options[] = struct option long_options[] =
{ {
{"audio input", 1, 0, 'C'}, {"audio input", 1, 0, 'C'},
@@ -93,53 +93,53 @@ main (int argc, char *argv[])
{"port", 1, 0, 'p'}, {"port", 1, 0, 'p'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
switch (opt) { switch (opt) {
case 'C': case 'C':
audio_input = atoi(optarg); audio_input = atoi(optarg);
break; break;
case 'P': case 'P':
audio_output = atoi(optarg); audio_output = atoi(optarg);
break; break;
case 'a': case 'a':
multicast_ip = strdup(optarg); multicast_ip = strdup(optarg);
break; break;
case 'p': case 'p':
port = atoi(optarg); port = atoi(optarg);
break; break;
case 'h': case 'h':
usage(); usage();
return -1; return -1;
} }
} }


jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, JackSlowMode };
jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, JackFloatEncoder, 0, 2 };
jack_master_t result; jack_master_t result;
printf("Waiting for a master...\n"); printf("Waiting for a master...\n");


if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_slave", &request, &result)) == 0) { if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_slave", &request, &result)) == 0) {
fprintf(stderr, "jack server not running?\n");
fprintf(stderr, "JACK server not running?\n");
return 1; return 1;
} }


printf("Slave is found and running...\n");
printf("Master is found and running...\n");


jack_set_net_slave_process_callback(net, net_process, NULL); jack_set_net_slave_process_callback(net, net_process, NULL);
jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL);


if (jack_net_slave_activate(net) != 0) { if (jack_net_slave_activate(net) != 0) {
fprintf(stderr, "Cannot sactivate client\n");
fprintf(stderr, "Cannot activate slave client\n");
return 1; return 1;
} }
/* install a signal handler to properly quits jack client */ /* install a signal handler to properly quits jack client */
#ifdef WIN32 #ifdef WIN32
signal(SIGINT, signal_handler); signal(SIGINT, signal_handler);
@@ -160,9 +160,9 @@ main (int argc, char *argv[])
sleep(1); sleep(1);
#endif #endif
}; };
// Wait for application end // Wait for application end
jack_net_slave_deactivate(net); jack_net_slave_deactivate(net);
jack_net_slave_close(net); jack_net_slave_close(net);
exit (0);
exit(0);
} }

+ 3
- 3
example-clients/showtime.c View File

@@ -34,7 +34,7 @@ showtime ()


transport_state = jack_transport_query (client, &current); transport_state = jack_transport_query (client, &current);
frame_time = jack_frame_time (client); frame_time = jack_frame_time (client);
printf ("frame = %u frame_time = %u usecs = %lld \t", current.frame, frame_time, current.usecs); printf ("frame = %u frame_time = %u usecs = %lld \t", current.frame, frame_time, current.usecs);


switch (transport_state) { switch (transport_state) {
@@ -81,7 +81,7 @@ main (int argc, char *argv[])
/* try to become a client of the JACK server */ /* try to become a client of the JACK server */


if ((client = jack_client_open ("showtime", JackNullOption, NULL)) == 0) { if ((client = jack_client_open ("showtime", JackNullOption, NULL)) == 0) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
return 1; return 1;
} }


@@ -103,7 +103,7 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot activate client"); fprintf (stderr, "cannot activate client");
return 1; return 1;
} }
while (1) { while (1) {
usleep (20); usleep (20);
showtime (); showtime ();


+ 1
- 1
example-clients/zombie.c View File

@@ -54,7 +54,7 @@ main (int argc, char *argv[])
jack_client_t* client = NULL; jack_client_t* client = NULL;
/* try to become a client of the JACK server */ /* try to become a client of the JACK server */
if ((client = jack_client_open ("zombie", JackNullOption, NULL)) == 0) { if ((client = jack_client_open ("zombie", JackNullOption, NULL)) == 0) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
goto error; goto error;
} }




+ 1
- 1
linux/JackLinuxTime.c View File

@@ -143,7 +143,7 @@ static jack_time_t jack_get_mhz (void)
exit(1); exit(1);
} }


for ( ; ; )
for (;;)
{ {
jack_time_t mhz; jack_time_t mhz;
int ret; int ret;


+ 70
- 0
macosx/Jackdmp.xcodeproj/project.pbxproj View File

@@ -123,6 +123,12 @@
4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; }; 4B19B31C0E2362E800DD4A82 /* JackLibSampleRateResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19B30F0E2362E700DD4A82 /* JackLibSampleRateResampler.h */; };
4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; }; 4B19B31F0E2362E800DD4A82 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */; };
4B20220A133A9C1C0019E213 /* midi_latency_test.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B202209133A9C1C0019E213 /* midi_latency_test.c */; }; 4B20220A133A9C1C0019E213 /* midi_latency_test.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B202209133A9C1C0019E213 /* midi_latency_test.c */; };
4B21794F13E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */; };
4B21795013E2EEA60095B3E5 /* JackTimedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */; };
4B21795113E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */; };
4B21795213E2EEA60095B3E5 /* JackTimedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */; };
4B21795313E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */; };
4B21795413E2EEA60095B3E5 /* JackTimedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */; };
4B2209E112F6BBF300E5DC26 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; }; 4B2209E112F6BBF300E5DC26 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; };
4B2209E212F6BBF400E5DC26 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; }; 4B2209E212F6BBF400E5DC26 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; };
4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; }; 4B2209E312F6BBF500E5DC26 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; };
@@ -590,6 +596,32 @@
4B6C738A0CC60A85001AFFD4 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C738A0CC60A85001AFFD4 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; };
4B6C738B0CC60A86001AFFD4 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4B6C738B0CC60A86001AFFD4 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; };
4B6F7AEE0CD0CDBD00F48A9D /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; 4B6F7AEE0CD0CDBD00F48A9D /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; };
4B6FE13A13DDABE000B4B943 /* JackSocketServerNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B60E703B8D0066E42F /* JackSocketServerNotifyChannel.h */; };
4B6FE13B13DDABE700B4B943 /* JackSocketServerNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B50E703B8D0066E42F /* JackSocketServerNotifyChannel.cpp */; };
4B6FE13C13DDABF100B4B943 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; };
4B6FE13D13DDABFA00B4B943 /* JackSocketServerChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B30E703B8D0066E42F /* JackSocketServerChannel.cpp */; };
4B6FE13E13DDAC0500B4B943 /* JackSocketNotifyChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B20E703B8D0066E42F /* JackSocketNotifyChannel.h */; };
4B6FE13F13DDAC0C00B4B943 /* JackSocketNotifyChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B10E703B8D0066E42F /* JackSocketNotifyChannel.cpp */; };
4B6FE14413DDAC4700B4B943 /* JackSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6AD0E703B8D0066E42F /* JackSocket.cpp */; };
4B6FE14513DDAC4C00B4B943 /* JackSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6AE0E703B8D0066E42F /* JackSocket.h */; };
4B6FE14D13DDACCC00B4B943 /* JackMidiAsyncQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193931133F311400547810 /* JackMidiAsyncQueue.cpp */; };
4B6FE14E13DDACD200B4B943 /* JackMidiAsyncQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193932133F311400547810 /* JackMidiAsyncQueue.h */; };
4B6FE15313DDACEF00B4B943 /* JackMidiBufferWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193968133F319000547810 /* JackMidiBufferWriteQueue.cpp */; };
4B6FE15413DDACF300B4B943 /* JackMidiBufferWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193969133F319000547810 /* JackMidiBufferWriteQueue.h */; };
4B6FE15B13DDAD3D00B4B943 /* JackMidiWriteQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19397A133F31CB00547810 /* JackMidiWriteQueue.h */; };
4B6FE15C13DDAD4600B4B943 /* JackMidiWriteQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193979133F31CB00547810 /* JackMidiWriteQueue.cpp */; };
4B6FE15D13DDAD4E00B4B943 /* JackMidiUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193978133F31CB00547810 /* JackMidiUtil.h */; };
4B6FE15E13DDAD5300B4B943 /* JackMidiUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193977133F31CB00547810 /* JackMidiUtil.cpp */; };
4B6FE15F13DDAD5900B4B943 /* JackMidiSendQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193976133F31CB00547810 /* JackMidiSendQueue.h */; };
4B6FE16013DDAD5F00B4B943 /* JackMidiSendQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193975133F31CB00547810 /* JackMidiSendQueue.cpp */; };
4B6FE16113DDAD6600B4B943 /* JackMidiReceiveQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193974133F31CB00547810 /* JackMidiReceiveQueue.h */; };
4B6FE16213DDAD6F00B4B943 /* JackMidiReceiveQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193973133F31CB00547810 /* JackMidiReceiveQueue.cpp */; };
4B6FE16313DDAD7700B4B943 /* JackMidiReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B193946133F315200547810 /* JackMidiReadQueue.h */; };
4B6FE16413DDAD7F00B4B943 /* JackMidiReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B193945133F315200547810 /* JackMidiReadQueue.cpp */; };
4B6FE16513DDAD8800B4B943 /* JackMidiBufferReadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19395E133F317300547810 /* JackMidiBufferReadQueue.h */; };
4B6FE16613DDAD8F00B4B943 /* JackMidiBufferReadQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19395D133F317300547810 /* JackMidiBufferReadQueue.cpp */; };
4B6FE16713DDAD9700B4B943 /* JackMidiAsyncWaitQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B19393C133F313000547810 /* JackMidiAsyncWaitQueue.h */; };
4B6FE16813DDAD9F00B4B943 /* JackMidiAsyncWaitQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B19393B133F313000547810 /* JackMidiAsyncWaitQueue.cpp */; };
4B80D7E80BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; 4B80D7E80BA0D17400F035BB /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; };
4B80D7E90BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; 4B80D7E90BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; };
4B80D7EA0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; 4B80D7EA0BA0D17400F035BB /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; };
@@ -1578,6 +1610,8 @@
4B19B3120E2362E700DD4A82 /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; 4B19B3120E2362E700DD4A82 /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; };
4B2021E6133A9BA40019E213 /* jack_midi_latency_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_latency_test; sourceTree = BUILT_PRODUCTS_DIR; }; 4B2021E6133A9BA40019E213 /* jack_midi_latency_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_latency_test; sourceTree = BUILT_PRODUCTS_DIR; };
4B202209133A9C1C0019E213 /* midi_latency_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midi_latency_test.c; path = "../example-clients/midi_latency_test.c"; sourceTree = SOURCE_ROOT; }; 4B202209133A9C1C0019E213 /* midi_latency_test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midi_latency_test.c; path = "../example-clients/midi_latency_test.c"; sourceTree = SOURCE_ROOT; };
4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackTimedDriver.cpp; path = ../common/JackTimedDriver.cpp; sourceTree = SOURCE_ROOT; };
4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackTimedDriver.h; path = ../common/JackTimedDriver.h; sourceTree = SOURCE_ROOT; };
4B2C28F908DAD01E00249230 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../common/JackGlobals.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; }; 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; }; 4B3224E810A315B100838A8E /* JackNetOneDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetOneDriver.cpp; path = ../common/JackNetOneDriver.cpp; sourceTree = SOURCE_ROOT; };
@@ -3048,6 +3082,8 @@
4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */, 4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */,
4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */, 4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */,
4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */, 4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */,
4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */,
4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */,
4BF3390D0F8B86AF0080FB5B /* MIDI */, 4BF3390D0F8B86AF0080FB5B /* MIDI */,
4B19B3010E23629800DD4A82 /* Adapter */, 4B19B3010E23629800DD4A82 /* Adapter */,
BA222AEA0DC88379001A17F4 /* Net */, BA222AEA0DC88379001A17F4 /* Net */,
@@ -3496,6 +3532,7 @@
4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */, 4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */,
4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */, 4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */,
4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */, 4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */,
4B21795213E2EEA60095B3E5 /* JackTimedDriver.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -3968,6 +4005,7 @@
4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */, 4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */,
4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */, 4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */,
4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */, 4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */,
4B21795013E2EEA60095B3E5 /* JackTimedDriver.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -4172,6 +4210,20 @@
4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */, 4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */,
4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */, 4B5160AE13215EF900BB7DCB /* systemdeps.h in Headers */,
4B193996133F321500547810 /* JackFilters.h in Headers */, 4B193996133F321500547810 /* JackFilters.h in Headers */,
4B6FE13A13DDABE000B4B943 /* JackSocketServerNotifyChannel.h in Headers */,
4B6FE13C13DDABF100B4B943 /* JackSocketServerChannel.h in Headers */,
4B6FE13E13DDAC0500B4B943 /* JackSocketNotifyChannel.h in Headers */,
4B6FE14513DDAC4C00B4B943 /* JackSocket.h in Headers */,
4B6FE14E13DDACD200B4B943 /* JackMidiAsyncQueue.h in Headers */,
4B6FE15413DDACF300B4B943 /* JackMidiBufferWriteQueue.h in Headers */,
4B6FE15B13DDAD3D00B4B943 /* JackMidiWriteQueue.h in Headers */,
4B6FE15D13DDAD4E00B4B943 /* JackMidiUtil.h in Headers */,
4B6FE15F13DDAD5900B4B943 /* JackMidiSendQueue.h in Headers */,
4B6FE16113DDAD6600B4B943 /* JackMidiReceiveQueue.h in Headers */,
4B6FE16313DDAD7700B4B943 /* JackMidiReadQueue.h in Headers */,
4B6FE16513DDAD8800B4B943 /* JackMidiBufferReadQueue.h in Headers */,
4B6FE16713DDAD9700B4B943 /* JackMidiAsyncWaitQueue.h in Headers */,
4B21795413E2EEA60095B3E5 /* JackTimedDriver.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -6972,6 +7024,7 @@
4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */, 4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */,
4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */, 4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */,
4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */, 4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */,
4B21795113E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -7433,6 +7486,7 @@
4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */, 4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */,
4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */, 4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */,
4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */, 4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */,
4B21794F13E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -7642,6 +7696,20 @@
4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */, 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */,
4BC2CA5D113C6CC90076717C /* JackNetInterface.cpp in Sources */, 4BC2CA5D113C6CC90076717C /* JackNetInterface.cpp in Sources */,
4BC2CA5F113C6CD10076717C /* JackNetUnixSocket.cpp in Sources */, 4BC2CA5F113C6CD10076717C /* JackNetUnixSocket.cpp in Sources */,
4B6FE13B13DDABE700B4B943 /* JackSocketServerNotifyChannel.cpp in Sources */,
4B6FE13D13DDABFA00B4B943 /* JackSocketServerChannel.cpp in Sources */,
4B6FE13F13DDAC0C00B4B943 /* JackSocketNotifyChannel.cpp in Sources */,
4B6FE14413DDAC4700B4B943 /* JackSocket.cpp in Sources */,
4B6FE14D13DDACCC00B4B943 /* JackMidiAsyncQueue.cpp in Sources */,
4B6FE15313DDACEF00B4B943 /* JackMidiBufferWriteQueue.cpp in Sources */,
4B6FE15C13DDAD4600B4B943 /* JackMidiWriteQueue.cpp in Sources */,
4B6FE15E13DDAD5300B4B943 /* JackMidiUtil.cpp in Sources */,
4B6FE16013DDAD5F00B4B943 /* JackMidiSendQueue.cpp in Sources */,
4B6FE16213DDAD6F00B4B943 /* JackMidiReceiveQueue.cpp in Sources */,
4B6FE16413DDAD7F00B4B943 /* JackMidiReadQueue.cpp in Sources */,
4B6FE16613DDAD8F00B4B943 /* JackMidiBufferReadQueue.cpp in Sources */,
4B6FE16813DDAD9F00B4B943 /* JackMidiAsyncWaitQueue.cpp in Sources */,
4B21795313E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -16793,6 +16861,7 @@
); );
OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\"";
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
libcelt.a,
"-framework", "-framework",
Carbon, Carbon,
"-framework", "-framework",
@@ -16865,6 +16934,7 @@
OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\"";
OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\""; OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\"";
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
libcelt.a,
"-framework", "-framework",
Carbon, Carbon,
"-framework", "-framework",


+ 23
- 15
macosx/coreaudio/JackCoreAudioAdapter.cpp View File

@@ -391,27 +391,35 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra
fPlaying = true; fPlaying = true;
} }


if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0)
throw -1;
if (SetupDevices(fCaptureUID, fPlaybackUID, captureName, playbackName, fAdaptedSampleRate) < 0) {
throw std::bad_alloc();
}


if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0)
throw -1;
if (SetupChannels(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, true) < 0) {
throw std::bad_alloc();
}


if (SetupBufferSize(fAdaptedBufferSize) < 0)
throw -1;
if (SetupBufferSize(fAdaptedBufferSize) < 0) {
throw std::bad_alloc();
}


if (SetupSampleRate(fAdaptedSampleRate) < 0)
throw -1;
if (SetupSampleRate(fAdaptedSampleRate) < 0) {
throw std::bad_alloc();
}


if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate) < 0)
throw -1;
if (OpenAUHAL(fCapturing, fPlaying, fCaptureChannels, fPlaybackChannels, in_nChannels, out_nChannels, fAdaptedBufferSize, fAdaptedSampleRate) < 0) {
throw std::bad_alloc();
}


if (fCapturing && fCaptureChannels > 0)
if (SetupBuffers(fCaptureChannels) < 0)
throw -1;
if (fCapturing && fCaptureChannels > 0) {
if (SetupBuffers(fCaptureChannels) < 0) {
throw std::bad_alloc();
}
}


if (AddListeners() < 0)
throw -1;
if (AddListeners() < 0) {
throw std::bad_alloc();
}
} }


OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id) OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id)


+ 201
- 56
macosx/coreaudio/JackCoreAudioDriver.cpp View File

@@ -29,6 +29,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackCompilerDeps.h" #include "JackCompilerDeps.h"
#include "JackLockedEngine.h" #include "JackLockedEngine.h"


#include <sstream>
#include <iostream> #include <iostream>
#include <CoreServices/CoreServices.h> #include <CoreServices/CoreServices.h>
#include <CoreFoundation/CFNumber.h> #include <CoreFoundation/CFNumber.h>
@@ -137,15 +138,17 @@ static OSStatus DisplayDeviceNames()
CFStringRef UIname; CFStringRef UIname;


err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
return err; return err;
}


deviceNum = size / sizeof(AudioDeviceID); deviceNum = size / sizeof(AudioDeviceID);
AudioDeviceID devices[deviceNum]; AudioDeviceID devices[deviceNum];


err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices);
if (err != noErr)
if (err != noErr) {
return err; return err;
}


for (i = 0; i < deviceNum; i++) { for (i = 0; i < deviceNum; i++) {
char device_name[256]; char device_name[256];
@@ -162,8 +165,9 @@ static OSStatus DisplayDeviceNames()


size = 256; size = 256;
err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name); err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name);
if (err != noErr)
if (err != noErr) {
return err; return err;
}


jack_info("Device name = \'%s\', internal name = \'%s\' (to be used as -C, -P, or -d parameter)", device_name, internal_name); jack_info("Device name = \'%s\', internal name = \'%s\' (to be used as -C, -P, or -d parameter)", device_name, internal_name);
} }
@@ -171,8 +175,9 @@ static OSStatus DisplayDeviceNames()
return noErr; return noErr;


error: error:
if (UIname != NULL)
if (UIname != NULL) {
CFRelease(UIname); CFRelease(UIname);
}
return err; return err;
} }


@@ -184,6 +189,20 @@ static CFStringRef GetDeviceName(AudioDeviceID id)
return (err == noErr) ? UIname : NULL; return (err == noErr) ? UIname : NULL;
} }


static void ParseChannelList(const string& list, vector<int>& result)
{
stringstream ss(list);
string token;
int chan;

while (ss >> token) {
istringstream ins;
ins.str(token);
ins >> chan;
result.push_back(chan);
}
}

OSStatus JackCoreAudioDriver::Render(void *inRefCon, OSStatus JackCoreAudioDriver::Render(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags, AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp, const AudioTimeStamp *inTimeStamp,
@@ -241,8 +260,9 @@ int JackCoreAudioDriver::Write()
int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize;
memcpy((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, buffer, size); memcpy((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, buffer, size);
// Monitor ports // Monitor ports
if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0)
if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) {
memcpy(GetMonitorBuffer(i), buffer, size); memcpy(GetMonitorBuffer(i), buffer, size);
}
} else { } else {
memset((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, 0, sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); memset((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, 0, sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize);
} }
@@ -349,8 +369,9 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice,
Float64 sample_rate = 0; Float64 sample_rate = 0;
UInt32 outsize = sizeof(Float64); UInt32 outsize = sizeof(Float64);
OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate); OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate);
if (err != noErr)
if (err != noErr) {
return kAudioHardwareUnsupportedOperationError; return kAudioHardwareUnsupportedOperationError;
}


char device_name[256]; char device_name[256];
const char* digidesign_name = "Digidesign"; const char* digidesign_name = "Digidesign";
@@ -420,11 +441,13 @@ OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID* id)
AudioDeviceID inDefault; AudioDeviceID inDefault;
AudioDeviceID outDefault; AudioDeviceID outDefault;


if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) {
return res; return res;
}


if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) {
return res; return res;
}


jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault);


@@ -447,8 +470,9 @@ OSStatus JackCoreAudioDriver::GetDefaultInputDevice(AudioDeviceID* id)
UInt32 theSize = sizeof(UInt32); UInt32 theSize = sizeof(UInt32);
AudioDeviceID inDefault; AudioDeviceID inDefault;


if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) {
return res; return res;
}


if (inDefault == 0) { if (inDefault == 0) {
jack_error("Error : input device is 0, please select a correct one !!"); jack_error("Error : input device is 0, please select a correct one !!");
@@ -465,8 +489,9 @@ OSStatus JackCoreAudioDriver::GetDefaultOutputDevice(AudioDeviceID* id)
UInt32 theSize = sizeof(UInt32); UInt32 theSize = sizeof(UInt32);
AudioDeviceID outDefault; AudioDeviceID outDefault;


if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) {
return res; return res;
}


if (outDefault == 0) { if (outDefault == 0) {
jack_error("Error : output device is 0, please select a correct one !!"); jack_error("Error : output device is 0, please select a correct one !!");
@@ -495,8 +520,9 @@ OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channe
AudioBufferList bufferList[outSize]; AudioBufferList bufferList[outSize];
err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList);
if (err == noErr) { if (err == noErr) {
for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++)
for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) {
channelCount += bufferList->mBuffers[i].mNumberChannels; channelCount += bufferList->mBuffers[i].mNumberChannels;
}
} }
} }
return err; return err;
@@ -526,7 +552,7 @@ OSStatus JackCoreAudioDriver::DestroyAggregateDevice()
pluginAOPA.mElement = kAudioObjectPropertyElementMaster; pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
UInt32 outDataSize; UInt32 outDataSize;


if (fPluginID > 0) {
if (fPluginID > 0) {


osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize); osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
if (osErr != noErr) { if (osErr != noErr) {
@@ -771,8 +797,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
vector<CFStringRef> captureDeviceUID; vector<CFStringRef> captureDeviceUID;
for (UInt32 i = 0; i < captureDeviceID.size(); i++) { for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
CFStringRef ref = GetDeviceName(captureDeviceID[i]); CFStringRef ref = GetDeviceName(captureDeviceID[i]);
if (ref == NULL)
if (ref == NULL) {
return -1; return -1;
}
captureDeviceUID.push_back(ref); captureDeviceUID.push_back(ref);
// input sub-devices in this example, so append the sub-device's UID to the CFArray // input sub-devices in this example, so append the sub-device's UID to the CFArray
CFArrayAppendValue(subDevicesArray, ref); CFArrayAppendValue(subDevicesArray, ref);
@@ -781,8 +808,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
vector<CFStringRef> playbackDeviceUID; vector<CFStringRef> playbackDeviceUID;
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
CFStringRef ref = GetDeviceName(playbackDeviceID[i]); CFStringRef ref = GetDeviceName(playbackDeviceID[i]);
if (ref == NULL)
if (ref == NULL) {
return -1; return -1;
}
playbackDeviceUID.push_back(ref); playbackDeviceUID.push_back(ref);
// output sub-devices in this example, so append the sub-device's UID to the CFArray // output sub-devices in this example, so append the sub-device's UID to the CFArray
CFArrayAppendValue(subDevicesArray, ref); CFArrayAppendValue(subDevicesArray, ref);
@@ -908,8 +936,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
CFRelease(aggDeviceDict); CFRelease(aggDeviceDict);
CFRelease(subDevicesArray); CFRelease(subDevicesArray);


if (subDevicesArrayClock)
if (subDevicesArrayClock) {
CFRelease(subDevicesArrayClock); CFRelease(subDevicesArrayClock);
}


// release the device UID // release the device UID
for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { for (UInt32 i = 0; i < captureDeviceUID.size(); i++) {
@@ -977,8 +1006,9 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
} }
} }


if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr)
if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) {
return -1; return -1;
}
} }


// Capture only // Capture only
@@ -1036,8 +1066,9 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid,
} }
} }


if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr)
if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) {
return -1; return -1;
}
} }
} }


@@ -1081,14 +1112,16 @@ int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchan


if (inchannels > in_nChannels) { if (inchannels > in_nChannels) {
jack_error("This device hasn't required input channels inchannels = %d in_nChannels = %d", inchannels, in_nChannels); jack_error("This device hasn't required input channels inchannels = %d in_nChannels = %d", inchannels, in_nChannels);
if (strict)
if (strict) {
return -1; return -1;
}
} }


if (outchannels > out_nChannels) { if (outchannels > out_nChannels) {
jack_error("This device hasn't required output channels outchannels = %d out_nChannels = %d", outchannels, out_nChannels); jack_error("This device hasn't required output channels outchannels = %d out_nChannels = %d", outchannels, out_nChannels);
if (strict)
if (strict) {
return -1; return -1;
}
} }


if (inchannels == -1) { if (inchannels == -1) {
@@ -1261,6 +1294,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
int outchannels, int outchannels,
int in_nChannels, int in_nChannels,
int out_nChannels, int out_nChannels,
const vector<int>& chan_in_list,
const vector<int>& chan_out_list,
jack_nframes_t buffer_size, jack_nframes_t buffer_size,
jack_nframes_t sample_rate) jack_nframes_t sample_rate)
{ {
@@ -1270,7 +1305,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
AudioDeviceID currAudioDeviceID; AudioDeviceID currAudioDeviceID;
UInt32 size; UInt32 size;


jack_log("OpenAUHAL capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d", capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels);
jack_log("OpenAUHAL capturing = %d playing = %d inchannels = %d outchannels = %d in_nChannels = %d out_nChannels = %d chan_in_list = %d chan_out_list = %d",
capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, chan_in_list.size(), chan_out_list.size());


if (inchannels == 0 && outchannels == 0) { if (inchannels == 0 && outchannels == 0) {
jack_error("No input and output channels..."); jack_error("No input and output channels...");
@@ -1363,34 +1399,69 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
} }
} }


// Setup channel map
if (capturing && inchannels > 0 && inchannels < in_nChannels) {
// Setup input channel map
if (capturing && inchannels > 0 && inchannels <= in_nChannels) {
SInt32 chanArr[in_nChannels]; SInt32 chanArr[in_nChannels];
for (int i = 0; i < in_nChannels; i++) { for (int i = 0; i < in_nChannels; i++) {
chanArr[i] = -1; chanArr[i] = -1;
} }
for (int i = 0; i < inchannels; i++) {
chanArr[i] = i;
// Explicit mapping
if (chan_in_list.size() > 0) {
for (uint i = 0; i < chan_in_list.size(); i++) {
int chan = chan_in_list[i];
if (chan < out_nChannels) {
// The wanted JACK input index for the 'chan' channel value
chanArr[chan] = i;
jack_info("Input channel = %d ==> JACK input port = %d", chan, i);
} else {
jack_info("Error input channel number is incorrect : %d", chan);
goto error;
}
}
} else {
for (int i = 0; i < inchannels; i++) {
chanArr[i] = i;
jack_info("Input channel = %d ==> JACK input port = %d", chanArr[i], i);
}
} }

AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels); AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels);
if (err1 != noErr) { if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1");
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for input");
printError(err1); printError(err1);
goto error; goto error;
} }
} }


if (playing && outchannels > 0 && outchannels < out_nChannels) {
// Setup output channel map
if (playing && outchannels > 0 && outchannels <= out_nChannels) {
SInt32 chanArr[out_nChannels]; SInt32 chanArr[out_nChannels];
for (int i = 0; i < out_nChannels; i++) { for (int i = 0; i < out_nChannels; i++) {
chanArr[i] = -1; chanArr[i] = -1;
} }
for (int i = 0; i < outchannels; i++) {
chanArr[i] = i;
// Explicit mapping
if (chan_out_list.size() > 0) {
for (uint i = 0; i < chan_out_list.size(); i++) {
int chan = chan_out_list[i];
if (chan < out_nChannels) {
// The wanted JACK output index for the 'chan' channel value
chanArr[chan] = i;
jack_info("JACK output port = %d ==> output channel = %d", i, chan);
} else {
jack_info("Error output channel number is incorrect : %d", chan);
goto error;
}
}
} else {
for (int i = 0; i < outchannels; i++) {
chanArr[i] = i;
jack_info("JACK output port = %d ==> output channel = %d", i, chanArr[i]);
}
} }

err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels); err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels);
if (err1 != noErr) { if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0");
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for output");
printError(err1); printError(err1);
goto error; goto error;
} }
@@ -1588,6 +1659,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
bool playing, bool playing,
int inchannels, int inchannels,
int outchannels, int outchannels,
const char* chan_in_list,
const char* chan_out_list,
bool monitor, bool monitor,
const char* capture_driver_uid, const char* capture_driver_uid,
const char* playback_driver_uid, const char* playback_driver_uid,
@@ -1618,6 +1691,21 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMajor, &major);
Gestalt(gestaltSystemVersionMinor, &minor); Gestalt(gestaltSystemVersionMinor, &minor);


vector<int> parsed_chan_in_list;
vector<int> parsed_chan_out_list;

ParseChannelList(chan_in_list, parsed_chan_in_list);
if (parsed_chan_in_list.size() > 0) {
jack_info("Explicit input channel list size = %d", parsed_chan_in_list.size());
inchannels = parsed_chan_in_list.size();
}

ParseChannelList(chan_out_list, parsed_chan_out_list);
if (parsed_chan_out_list.size() > 0) {
jack_info("Explicit output channel list size = %d", parsed_chan_out_list.size());
outchannels = parsed_chan_out_list.size();
}

// Starting with 10.6 systems, the HAL notification thread is created internally // Starting with 10.6 systems, the HAL notification thread is created internally
if (major == 10 && minor >= 6) { if (major == 10 && minor >= 6) {
CFRunLoopRef theRunLoop = NULL; CFRunLoopRef theRunLoop = NULL;
@@ -1629,31 +1717,47 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
} }
} }


if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, sample_rate) < 0)
if (SetupDevices(capture_driver_uid, playback_driver_uid, capture_driver_name, playback_driver_name, sample_rate) < 0) {
goto error; goto error;
}


// Generic JackAudioDriver Open // Generic JackAudioDriver Open
if (JackAudioDriver::Open(buffer_size, sample_rate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency) != 0)
if (JackAudioDriver::Open(buffer_size, sample_rate,
capturing, playing,
inchannels, outchannels,
monitor,
capture_driver_name,
playback_driver_name,
capture_latency,
playback_latency) != 0) {
goto error; goto error;
}


if (SetupChannels(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, true) < 0)
if (SetupChannels(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, true) < 0) {
goto error; goto error;
}


if (SetupBufferSize(buffer_size) < 0)
if (SetupBufferSize(buffer_size) < 0) {
goto error; goto error;
}


if (SetupSampleRate(sample_rate) < 0)
if (SetupSampleRate(sample_rate) < 0) {
goto error; goto error;
}


if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, buffer_size, sample_rate) < 0)
if (OpenAUHAL(capturing, playing, inchannels, outchannels, in_nChannels, out_nChannels, parsed_chan_in_list, parsed_chan_out_list, buffer_size, sample_rate) < 0) {
goto error; goto error;
}


if (capturing && inchannels > 0)
if (SetupBuffers(inchannels) < 0)
if (capturing && inchannels > 0) {
if (SetupBuffers(inchannels) < 0) {
goto error; goto error;
}
}


if (AddListeners() < 0)
if (AddListeners() < 0) {
goto error; goto error;
}


// Core driver may have changed the in/out values // Core driver may have changed the in/out values
fCaptureChannels = inchannels; fCaptureChannels = inchannels;
@@ -1692,11 +1796,13 @@ void JackCoreAudioDriver::UpdateLatencies()
UInt32 value1 = 0; UInt32 value1 = 0;
UInt32 value2 = 0; UInt32 value2 = 0;
err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1); err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error");
}
err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2); err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error");
}


range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency;
fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range);
@@ -1707,11 +1813,13 @@ void JackCoreAudioDriver::UpdateLatencies()
UInt32 value1 = 0; UInt32 value1 = 0;
UInt32 value2 = 0; UInt32 value2 = 0;
err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error");
}
err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2); err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error");
}


// Add more latency if "async" mode is used... // Add more latency if "async" mode is used...
range.min = range.max range.min = range.max
@@ -1742,12 +1850,14 @@ int JackCoreAudioDriver::Attach()
for (int i = 0; i < fCaptureChannels; i++) { for (int i = 0; i < fCaptureChannels; i++) {


err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, &isWritable); err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error"); jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error");
}
if (err == noErr && size > 0) { if (err == noErr && size > 0) {
err = AudioDeviceGetProperty(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, channel_name); err = AudioDeviceGetProperty(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, channel_name);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error");
}
snprintf(alias, sizeof(alias) - 1, "%s:%s:out_%s%u", fAliasName, fCaptureDriverName, channel_name, i + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:out_%s%u", fAliasName, fCaptureDriverName, channel_name, i + 1);
} else { } else {
snprintf(alias, sizeof(alias) - 1, "%s:%s:out%u", fAliasName, fCaptureDriverName, i + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:out%u", fAliasName, fCaptureDriverName, i + 1);
@@ -1768,12 +1878,14 @@ int JackCoreAudioDriver::Attach()
for (int i = 0; i < fPlaybackChannels; i++) { for (int i = 0; i < fPlaybackChannels; i++) {


err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable); err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error"); jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error");
}
if (err == noErr && size > 0) { if (err == noErr && size > 0) {
err = AudioDeviceGetProperty(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, channel_name); err = AudioDeviceGetProperty(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, channel_name);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error"); jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error");
}
snprintf(alias, sizeof(alias) - 1, "%s:%s:in_%s%u", fAliasName, fPlaybackDriverName, channel_name, i + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:in_%s%u", fAliasName, fPlaybackDriverName, channel_name, i + 1);
} else { } else {
snprintf(alias, sizeof(alias) - 1, "%s:%s:in%u", fAliasName, fPlaybackDriverName, i + 1); snprintf(alias, sizeof(alias) - 1, "%s:%s:in%u", fAliasName, fPlaybackDriverName, i + 1);
@@ -1854,8 +1966,9 @@ int JackCoreAudioDriver::Stop()


int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size)
{ {
if (SetupBufferSize(buffer_size) < 0)
if (SetupBufferSize(buffer_size) < 0) {
return -1; return -1;
}


JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails


@@ -1950,8 +2063,12 @@ extern "C"


value.i = -1; value.i = -1;
jack_driver_descriptor_add_parameter(desc, &filler, "channels", 'c', JackDriverParamInt, &value, NULL, "Maximum number of channels", "Maximum number of channels. If -1, max possible number of channels will be used"); jack_driver_descriptor_add_parameter(desc, &filler, "channels", 'c', JackDriverParamInt, &value, NULL, "Maximum number of channels", "Maximum number of channels. If -1, max possible number of channels will be used");
jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", "Maximum number of input channels. If -1, max possible number of input channels will be used");
jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used");
jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", "Maximum number of input channels. If -1, max possible number of input channels will be used");
jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used");

value.str[0] = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "input-list", 'n', JackDriverParamString, &value, NULL, "Input channel list", "List of input channel number to be opened");
jack_driver_descriptor_add_parameter(desc, &filler, "output-list", 'N', JackDriverParamString, &value, NULL, "Output channel list", "List of output channel number to be opened");


value.str[0] = 0; value.str[0] = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input CoreAudio device name", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input CoreAudio device name", NULL);
@@ -1966,7 +2083,7 @@ extern "C"
value.ui = 44100U; value.ui = 44100U;
jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);


value.ui = 128U;
value.ui = 256U;
jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);


value.str[0] = 0; value.str[0] = 0;
@@ -1997,11 +2114,13 @@ extern "C"
SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
{ {
jack_nframes_t srate = 44100; jack_nframes_t srate = 44100;
jack_nframes_t frames_per_interrupt = 128;
jack_nframes_t frames_per_interrupt = 256;
bool capture = false; bool capture = false;
bool playback = false; bool playback = false;
int chan_in = -1; // Default: if not explicitely set, then max possible will be used... int chan_in = -1; // Default: if not explicitely set, then max possible will be used...
int chan_out = -1; // Default: if not explicitely set, then max possible will be used... int chan_out = -1; // Default: if not explicitely set, then max possible will be used...
const char* chan_in_list = "";
const char* chan_out_list = "";
bool monitor = false; bool monitor = false;
const char* capture_driver_uid = ""; const char* capture_driver_uid = "";
const char* playback_driver_uid = ""; const char* playback_driver_uid = "";
@@ -2030,15 +2149,23 @@ extern "C"
break; break;


case 'c': case 'c':
chan_in = chan_out = (int)param->value.ui;
chan_in = chan_out = param->value.i;
break; break;


case 'i': case 'i':
chan_in = (int)param->value.ui;
chan_in = param->value.i;
break; break;


case 'o': case 'o':
chan_out = (int)param->value.ui;
chan_out = param->value.i;
break;

case 'n':
chan_in_list = param->value.str;
break;

case 'N':
chan_out_list = param->value.str;
break; break;


case 'C': case 'C':
@@ -2103,9 +2230,27 @@ extern "C"
playback = true; playback = true;
} }


if (strcmp(chan_in_list, "") != 0 && chan_in >= 0) {
printf("Input channel list and in channels are both specified, input channel list will take over...\n");
}

if (strcmp(chan_out_list, "") != 0 && chan_out >= 0) {
printf("Output channel list and out channels are both specified, output channel list will take over...\n");
}

Jack::JackCoreAudioDriver* driver = new Jack::JackCoreAudioDriver("system", "coreaudio", engine, table); 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, clock_drift) == 0) {
if (driver->Open(frames_per_interrupt,
srate, capture,
playback, chan_in,
chan_out, chan_in_list,
chan_out_list, monitor,
capture_driver_uid,
playback_driver_uid,
systemic_input_latency,
systemic_output_latency,
async_output_latency,
computation_grain,
hogged, clock_drift) == 0) {
return driver; return driver;
} else { } else {
delete driver; delete driver;


+ 6
- 2
macosx/coreaudio/JackCoreAudioDriver.h View File

@@ -141,6 +141,8 @@ class JackCoreAudioDriver : public JackAudioDriver
int outchannels, int outchannels,
int in_nChannels, int in_nChannels,
int out_nChannels, int out_nChannels,
const vector<int>& chan_in_list,
const vector<int>& chan_out_list,
jack_nframes_t nframes, jack_nframes_t nframes,
jack_nframes_t samplerate); jack_nframes_t samplerate);
void CloseAUHAL(); void CloseAUHAL();
@@ -162,8 +164,10 @@ class JackCoreAudioDriver : public JackAudioDriver
jack_nframes_t samplerate, jack_nframes_t samplerate,
bool capturing, bool capturing,
bool playing, bool playing,
int chan_in,
int chan_out,
int inchannels,
int outchannels,
const char* chan_in_list,
const char* chan_out_list,
bool monitor, bool monitor,
const char* capture_driver_name, const char* capture_driver_name,
const char* playback_driver_name, const char* playback_driver_name,


+ 69
- 69
macosx/iphone/freeverb.mm View File

@@ -25,7 +25,7 @@
#include <pwd.h> #include <pwd.h>
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
#include <pthread.h>
#include <pthread.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <libgen.h> #include <libgen.h>
#include <jack/net.h> #include <jack/net.h>
@@ -52,7 +52,7 @@ using namespace std;
#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000) #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
#endif #endif
#else #else
#define AVOIDDENORMALS
#define AVOIDDENORMALS
#endif #endif


//#define BENCHMARKMODE //#define BENCHMARKMODE
@@ -61,7 +61,7 @@ struct Meta : map<const char*, const char*>
{ {
void declare (const char* key, const char* value) { (*this)[key]=value; } void declare (const char* key, const char* value) { (*this)[key]=value; }
}; };


#define max(x,y) (((x)>(y)) ? (x) : (y)) #define max(x,y) (((x)>(y)) ? (x) : (y))
#define min(x,y) (((x)<(y)) ? (x) : (y)) #define min(x,y) (((x)<(y)) ? (x) : (y))
@@ -91,37 +91,37 @@ class UI
{ {
bool fStopped; bool fStopped;
public: public:
UI() : fStopped(false) {} UI() : fStopped(false) {}
virtual ~UI() {} virtual ~UI() {}
// -- active widgets // -- active widgets
virtual void addButton(const char* label, float* zone) = 0; virtual void addButton(const char* label, float* zone) = 0;
virtual void addToggleButton(const char* label, float* zone) = 0; virtual void addToggleButton(const char* label, float* zone) = 0;
virtual void addCheckButton(const char* label, float* zone) = 0; virtual void addCheckButton(const char* label, float* zone) = 0;
virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0; virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0; virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0; virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
// -- passive widgets // -- passive widgets
virtual void addNumDisplay(const char* label, float* zone, int precision) = 0; virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0; virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0; virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0; virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
// -- frames and labels // -- frames and labels
virtual void openFrameBox(const char* label) = 0; virtual void openFrameBox(const char* label) = 0;
virtual void openTabBox(const char* label) = 0; virtual void openTabBox(const char* label) = 0;
virtual void openHorizontalBox(const char* label) = 0; virtual void openHorizontalBox(const char* label) = 0;
virtual void openVerticalBox(const char* label) = 0; virtual void openVerticalBox(const char* label) = 0;
virtual void closeBox() = 0; virtual void closeBox() = 0;
virtual void show() = 0; virtual void show() = 0;
virtual void run() = 0; virtual void run() = 0;
void stop() { fStopped = true; } void stop() { fStopped = true; }
bool stopped() { return fStopped; } bool stopped() { return fStopped; }


@@ -132,24 +132,24 @@ struct param {
float* fZone; float fMin; float fMax; float* fZone; float fMin; float fMax;
param(float* z, float a, float b) : fZone(z), fMin(a), fMax(b) {} param(float* z, float a, float b) : fZone(z), fMin(a), fMax(b) {}
}; };
class CMDUI : public UI class CMDUI : public UI
{ {
int fArgc; int fArgc;
char** fArgv; char** fArgv;
stack<string> fPrefix; stack<string> fPrefix;
map<string, param> fKeyParam; map<string, param> fKeyParam;
void addOption(const char* label, float* zone, float min, float max) void addOption(const char* label, float* zone, float min, float max)
{ {
string fullname = fPrefix.top() + label; string fullname = fPrefix.top() + label;
fKeyParam.insert(make_pair(fullname, param(zone, min, max))); fKeyParam.insert(make_pair(fullname, param(zone, min, max)));
} }
void openAnyBox(const char* label) void openAnyBox(const char* label)
{ {
string prefix; string prefix;
if (label && label[0]) { if (label && label[0]) {
prefix = fPrefix.top() + "-" + label; prefix = fPrefix.top() + "-" + label;
} else { } else {
@@ -157,21 +157,21 @@ class CMDUI : public UI
} }
fPrefix.push(prefix); fPrefix.push(prefix);
} }
public: public:
CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); } CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); }
virtual ~CMDUI() {} virtual ~CMDUI() {}
virtual void addButton(const char* label, float* zone) {}; virtual void addButton(const char* label, float* zone) {};
virtual void addToggleButton(const char* label, float* zone) {}; virtual void addToggleButton(const char* label, float* zone) {};
virtual void addCheckButton(const char* label, float* zone) {}; virtual void addCheckButton(const char* label, float* zone) {};
virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
{ {
addOption(label,zone,min,max); addOption(label,zone,min,max);
} }
virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
{ {
addOption(label,zone,min,max); addOption(label,zone,min,max);
@@ -181,9 +181,9 @@ public:
{ {
addOption(label,zone,min,max); addOption(label,zone,min,max);
} }
// -- passive widgets // -- passive widgets
virtual void addNumDisplay(const char* label, float* zone, int precision) {} virtual void addNumDisplay(const char* label, float* zone, int precision) {}
virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) {} virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) {}
virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) {} virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) {}
@@ -193,11 +193,11 @@ public:
virtual void openTabBox(const char* label) { openAnyBox(label); } virtual void openTabBox(const char* label) { openAnyBox(label); }
virtual void openHorizontalBox(const char* label) { openAnyBox(label); } virtual void openHorizontalBox(const char* label) { openAnyBox(label); }
virtual void openVerticalBox(const char* label) { openAnyBox(label); } virtual void openVerticalBox(const char* label) { openAnyBox(label); }
virtual void closeBox() { fPrefix.pop(); } virtual void closeBox() { fPrefix.pop(); }
virtual void show() {} virtual void show() {}
virtual void run()
virtual void run()
{ {
char c; char c;
printf("Type 'q' to quit\n"); printf("Type 'q' to quit\n");
@@ -205,8 +205,8 @@ public:
sleep(1); sleep(1);
} }
} }
void print()
void print()
{ {
map<string, param>::iterator i; map<string, param>::iterator i;
cout << fArgc << "\n"; cout << fArgc << "\n";
@@ -215,13 +215,13 @@ public:
cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] "; cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] ";
} }
} }
void process_command() void process_command()
{ {
map<string, param>::iterator p; map<string, param>::iterator p;
for (int i = 1; i < fArgc; i++) { for (int i = 1; i < fArgc; i++) {
if (fArgv[i][0] == '-') { if (fArgv[i][0] == '-') {
p = fKeyParam.find(fArgv[i]);
p = fKeyParam.find(fArgv[i]);
if (p == fKeyParam.end()) { if (p == fKeyParam.end()) {
cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
print(); print();
@@ -233,13 +233,13 @@ public:
} }
} }
} }
void process_init() void process_init()
{ {
map<string, param>::iterator p; map<string, param>::iterator p;
for (int i = 1; i < fArgc; i++) { for (int i = 1; i < fArgc; i++) {
if (fArgv[i][0] == '-') { if (fArgv[i][0] == '-') {
p = fKeyParam.find(fArgv[i]);
p = fKeyParam.find(fArgv[i]);
if (p == fKeyParam.end()) { if (p == fKeyParam.end()) {
cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
exit(1); exit(1);
@@ -256,14 +256,14 @@ public:
//---------------------------------------------------------------- //----------------------------------------------------------------
// Signal processor definition // Signal processor definition
//---------------------------------------------------------------- //----------------------------------------------------------------
class dsp { class dsp {
protected: protected:
int fSamplingFreq; int fSamplingFreq;
public: public:
dsp() {} dsp() {}
virtual ~dsp() {} virtual ~dsp() {}
virtual int getNumInputs() = 0; virtual int getNumInputs() = 0;
virtual int getNumOutputs() = 0; virtual int getNumOutputs() = 0;
virtual void buildUserInterface(UI* interface) = 0; virtual void buildUserInterface(UI* interface) = 0;
@@ -271,12 +271,12 @@ class dsp {
virtual void compute(int len, float** inputs, float** outputs) = 0; virtual void compute(int len, float** inputs, float** outputs) = 0;
virtual void conclude() {} virtual void conclude() {}
}; };


//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// FAUST generated code // FAUST generated code
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------


class mydsp : public dsp { class mydsp : public dsp {
private: private:
@@ -349,7 +349,7 @@ class mydsp : public dsp {
float fVec23[256]; float fVec23[256];
float fRec24[2]; float fRec24[2];
public: public:
static void metadata(Meta* m) {
static void metadata(Meta* m) {
m->declare("name", "freeverb"); m->declare("name", "freeverb");
m->declare("version", "1.0"); m->declare("version", "1.0");
m->declare("author", "Grame"); m->declare("author", "Grame");
@@ -580,8 +580,8 @@ class mydsp : public dsp {
}; };




mydsp DSP; mydsp DSP;




@@ -601,7 +601,7 @@ int gNumInChans;
int gNumOutChans; int gNumOutChans;


//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Jack Callbacks
// Jack Callbacks
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------


static void net_shutdown(void *) static void net_shutdown(void *)
@@ -633,7 +633,7 @@ void printstats()
low = hi = tot = (stops[KSKIP] - starts[KSKIP]); low = hi = tot = (stops[KSKIP] - starts[KSKIP]);


if (mesure < KMESURE) { if (mesure < KMESURE) {
for (int i = KSKIP+1; i<mesure; i++) { for (int i = KSKIP+1; i<mesure; i++) {
unsigned long long int m = stops[i] - starts[i]; unsigned long long int m = stops[i] - starts[i];
if (m<low) low = m; if (m<low) low = m;
@@ -643,7 +643,7 @@ void printstats()
cout << low << ' ' << tot/(mesure-KSKIP) << ' ' << hi << endl; cout << low << ' ' << tot/(mesure-KSKIP) << ' ' << hi << endl;


} else { } else {
for (int i = KSKIP+1; i<KMESURE; i++) { for (int i = KSKIP+1; i<KMESURE; i++) {
unsigned long long int m = stops[i] - starts[i]; unsigned long long int m = stops[i] - starts[i];
if (m<low) low = m; if (m<low) low = m;
@@ -652,7 +652,7 @@ void printstats()
} }
cout << low << ' ' << tot/(KMESURE-KSKIP) << ' ' << hi << endl; cout << low << ' ' << tot/(KMESURE-KSKIP) << ' ' << hi << endl;


}
}
} }


#else #else
@@ -663,20 +663,20 @@ void printstats()
#endif #endif


static int net_process(jack_nframes_t buffer_size, static int net_process(jack_nframes_t buffer_size,
int audio_input,
float** audio_input_buffer,
int audio_input,
float** audio_input_buffer,
int midi_input, int midi_input,
void** midi_input_buffer, void** midi_input_buffer,
int audio_output, int audio_output,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer,
void* data) void* data)
{ {
AVOIDDENORMALS; AVOIDDENORMALS;
STARTMESURE STARTMESURE
DSP.compute(buffer_size, audio_input_buffer, audio_output_buffer); DSP.compute(buffer_size, audio_input_buffer, audio_output_buffer);
STOPMESURE
STOPMESURE
return 0; return 0;
} }


@@ -687,68 +687,68 @@ static int net_process(jack_nframes_t buffer_size,


******************************************************************************* *******************************************************************************
*******************************************************************************/ *******************************************************************************/
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// MAIN // MAIN
//------------------------------------------------------------------------- //-------------------------------------------------------------------------




#define TEST_MASTER "194.5.49.5" #define TEST_MASTER "194.5.49.5"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
UI* interface = new CMDUI(argc, argv); UI* interface = new CMDUI(argc, argv);
jack_net_slave_t* net; jack_net_slave_t* net;
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//Jack::JackAudioQueueAdapter audio(2, 2, 1024, 44100, NULL); //Jack::JackAudioQueueAdapter audio(2, 2, 1024, 44100, NULL);
gNumInChans = DSP.getNumInputs(); gNumInChans = DSP.getNumInputs();
gNumOutChans = DSP.getNumOutputs(); gNumOutChans = DSP.getNumOutputs();
jack_slave_t request = { gNumInChans, gNumOutChans, 0, 0, DEFAULT_MTU, -1, JackSlowMode };
jack_slave_t request = { gNumInChans, gNumOutChans, 0, 0, DEFAULT_MTU, -1, 2 };
jack_master_t result; jack_master_t result;
printf("Network\n"); printf("Network\n");
//if (audio.Open() < 0) { //if (audio.Open() < 0) {
// fprintf(stderr, "Cannot open audio\n"); // fprintf(stderr, "Cannot open audio\n");
// return 1; // return 1;
//} //}
//audio.Start(); //audio.Start();
// Hang around forever... // Hang around forever...
//while(1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false); //while(1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false);
if ((net = jack_net_slave_open(TEST_MASTER, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { if ((net = jack_net_slave_open(TEST_MASTER, DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
fprintf(stderr, "jack remote server not running ?\n"); fprintf(stderr, "jack remote server not running ?\n");
return 1; return 1;
} }
jack_set_net_slave_process_callback(net, net_process, NULL); jack_set_net_slave_process_callback(net, net_process, NULL);
// We want to restart (that is "wait for available master" again) // We want to restart (that is "wait for available master" again)
//jack_set_net_shutdown_callback(net, net_shutdown, 0); //jack_set_net_shutdown_callback(net, net_shutdown, 0);
DSP.init(result.sample_rate); DSP.init(result.sample_rate);
DSP.buildUserInterface(interface); DSP.buildUserInterface(interface);
if (jack_net_slave_activate(net) != 0) { if (jack_net_slave_activate(net) != 0) {
fprintf(stderr, "cannot activate net"); fprintf(stderr, "cannot activate net");
return 1; return 1;
} }
int retVal = UIApplicationMain(argc, argv, nil, nil); int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release]; [pool release];
// Wait for application end // Wait for application end
jack_net_slave_deactivate(net); jack_net_slave_deactivate(net);
jack_net_slave_close(net); jack_net_slave_close(net);
//if (audio.Close() < 0) { //if (audio.Close() < 0) {
// fprintf(stderr, "Cannot close audio\n"); // fprintf(stderr, "Cannot close audio\n");
//} //}
return retVal; return retVal;
} }

+ 29
- 29
macosx/iphone/main_master.mm View File

@@ -24,7 +24,7 @@ int buffer_size = 1024;
int sample_rate = 22050; int sample_rate = 22050;
//int sample_rate = 32000; //int sample_rate = 32000;


jack_master_t request = { buffer_size, sample_rate, "master" };
jack_master_t request = { -1, -1, -1, -1, buffer_size, sample_rate, "master" };
jack_slave_t result; jack_slave_t result;


static void MixAudio(float** dst, float** src1, float** src2, int channels, int buffer_size) static void MixAudio(float** dst, float** src1, float** src2, int channels, int buffer_size)
@@ -38,33 +38,33 @@ static void MixAudio(float** dst, float** src1, float** src2, int channels, int


static void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg) static void MasterAudioCallback(int frames, float** inputs, float** outputs, void* arg)
{ {
int i;
int i;
// Copy from iPod input to network buffers // Copy from iPod input to network buffers
for (i = 0; i < result.audio_input; i++) { for (i = 0; i < result.audio_input; i++) {
memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float)); memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float));
} }
/* /*
// Copy from network out buffers to network in buffers (audio thru) // Copy from network out buffers to network in buffers (audio thru)
for (i = 0; i < result.audio_input; i++) { for (i = 0; i < result.audio_input; i++) {
memcpy(audio_input_buffer[i], audio_output_buffer[i], buffer_size * sizeof(float)); memcpy(audio_input_buffer[i], audio_output_buffer[i], buffer_size * sizeof(float));
} }
*/ */
// Mix iPod input and network in buffers to network out buffers // Mix iPod input and network in buffers to network out buffers
//MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size); //MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size);
// Send network buffers // Send network buffers
if (jack_net_master_send(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { if (jack_net_master_send(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) {
printf("jack_net_master_send error..\n"); printf("jack_net_master_send error..\n");
} }
// Recv network buffers // Recv network buffers
if (jack_net_master_recv(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { if (jack_net_master_recv(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) {
printf("jack_net_master_recv error..\n"); printf("jack_net_master_recv error..\n");
} }
// Copy from network buffers to iPod output // Copy from network buffers to iPod output
for (i = 0; i < result.audio_output; i++) { for (i = 0; i < result.audio_output; i++) {
memcpy(outputs[i], audio_output_buffer[i], buffer_size * sizeof(float)); memcpy(outputs[i], audio_output_buffer[i], buffer_size * sizeof(float));
@@ -72,17 +72,17 @@ static void MasterAudioCallback(int frames, float** inputs, float** outputs, voi
} }


int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int i; int i;
if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
printf("jack_net_master_open error..\n"); printf("jack_net_master_open error..\n");
return -1; return -1;
} }
TiPhoneCoreAudioRenderer audio_device(result.audio_input, result.audio_output); TiPhoneCoreAudioRenderer audio_device(result.audio_input, result.audio_output);
// Allocate buffers // Allocate buffers
if (result.audio_input > 0) { if (result.audio_input > 0) {
audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*)); audio_input_buffer = (float**)calloc(result.audio_input, sizeof(float*));
@@ -90,66 +90,66 @@ int main(int argc, char *argv[]) {
audio_input_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); audio_input_buffer[i] = (float*)(calloc(buffer_size, sizeof(float)));
} }
} }
if (result.audio_output > 0) { if (result.audio_output > 0) {
audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*)); audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*));
for (i = 0; i < result.audio_output; i++) { for (i = 0; i < result.audio_output; i++) {
audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float))); audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float)));
} }
} }
if (audio_device.Open(buffer_size, sample_rate) < 0) { if (audio_device.Open(buffer_size, sample_rate) < 0) {
return -1; return -1;
} }
audio_device.SetAudioCallback(MasterAudioCallback, NULL); audio_device.SetAudioCallback(MasterAudioCallback, NULL);
if (audio_device.Start() < 0) { if (audio_device.Start() < 0) {
return -1; return -1;
} }
/* /*
// Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead... // Quite brutal way, the application actually does not start completely, the netjack audio processing loop is used instead...
// Run until interrupted
// Run until interrupted
int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f); int wait_usec = (unsigned long)((((float)buffer_size) / ((float)sample_rate)) * 1000000.0f);
while (1) { while (1) {
// Copy input to output // Copy input to output
for (i = 0; i < result.audio_input; i++) { for (i = 0; i < result.audio_input; i++) {
memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float));
} }
if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) { if (jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) {
printf("jack_net_master_send error..\n"); printf("jack_net_master_send error..\n");
} }
if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) { if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) {
printf("jack_net_master_recv error..\n"); printf("jack_net_master_recv error..\n");
} }
usleep(wait_usec); usleep(wait_usec);
}; };
*/ */
int retVal = UIApplicationMain(argc, argv, nil, nil); int retVal = UIApplicationMain(argc, argv, nil, nil);
audio_device.Stop(); audio_device.Stop();
audio_device.Close(); audio_device.Close();
// Wait for application end // Wait for application end
jack_net_master_close(net); jack_net_master_close(net);
for (i = 0; i < result.audio_input; i++) { for (i = 0; i < result.audio_input; i++) {
free(audio_input_buffer[i]); free(audio_input_buffer[i]);
} }
free(audio_input_buffer); free(audio_input_buffer);
for (i = 0; i < result.audio_output; i++) { for (i = 0; i < result.audio_output; i++) {
free(audio_output_buffer[i]); free(audio_output_buffer[i]);
} }
free(audio_output_buffer); free(audio_output_buffer);
[pool release]; [pool release];
return retVal; return retVal;
} }

+ 26
- 25
macosx/iphone/main_slave.mm View File

@@ -21,18 +21,18 @@ int buffer_size;
int sample_rate; int sample_rate;


static int net_process(jack_nframes_t buffer_size, static int net_process(jack_nframes_t buffer_size,
int audio_input,
float** audio_input_buffer,
int audio_input,
float** audio_input_buffer,
int midi_input, int midi_input,
void** midi_input_buffer, void** midi_input_buffer,
int audio_output, int audio_output,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer,
float** audio_output_buffer,
int midi_output,
void** midi_output_buffer,
void* data) void* data)
{ {
jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size); jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size);
// Process input, produce output // Process input, produce output
if (audio_input == audio_output) { if (audio_input == audio_output) {
// Copy net input to net output // Copy net input to net output
@@ -59,52 +59,53 @@ static void SlaveAudioCallback(int frames, float** inputs, float** outputs, void
#define WIFI_MTU 1500 #define WIFI_MTU 1500


int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackCeltEncoder, 128, JackSlowMode };
jack_slave_t request = { NUM_OUTPUT, NUM_INPUT, 0, 0, WIFI_MTU, -1, JackCeltEncoder, 128, 2 };
jack_master_t result; jack_master_t result;


//if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) { //if ((net = jack_net_slave_open("169.254.112.119", DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) { if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPod", &request, &result)) == 0) {
printf("jack_net_slave_open error..\n");
printf("jack_net_slave_open error...\n");
return -1; return -1;
} }
if ((adapter = jack_create_adapter(NUM_INPUT,
NUM_OUTPUT,
result.buffer_size,
result.sample_rate,
result.buffer_size,
if ((adapter = jack_create_adapter(NUM_INPUT,
NUM_OUTPUT,
result.buffer_size,
result.sample_rate,
result.buffer_size,
result.sample_rate)) == 0) { result.sample_rate)) == 0) {
return -1; return -1;
} }
TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT); TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT);
jack_set_net_slave_process_callback(net, net_process, NULL); jack_set_net_slave_process_callback(net, net_process, NULL);
jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL); jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL);
if (jack_net_slave_activate(net) != 0) { if (jack_net_slave_activate(net) != 0) {
printf("Cannot activate slave client\n");
return -1; return -1;
} }
if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) { if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) {
return -1; return -1;
} }
audio_device.SetAudioCallback(SlaveAudioCallback, NULL); audio_device.SetAudioCallback(SlaveAudioCallback, NULL);
if (audio_device.Start() < 0) { if (audio_device.Start() < 0) {
return -1; return -1;
} }
int retVal = UIApplicationMain(argc, argv, nil, nil); int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release]; [pool release];
audio_device.Stop(); audio_device.Stop();
audio_device.Close(); audio_device.Close();
// Wait for application end // Wait for application end
jack_net_slave_deactivate(net); jack_net_slave_deactivate(net);
jack_net_slave_close(net); jack_net_slave_close(net);


+ 1
- 1
man/jack_connect.0 View File

@@ -5,7 +5,7 @@
\fB jack_connect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2 \fB jack_connect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2
\fB jack_disconnect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2 \fB jack_disconnect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2
.SH DESCRIPTION .SH DESCRIPTION
\fBjack_connect\fR connects the two named ports. \fBjack_connect\fR disconnects the two named ports.
\fBjack_connect\fR connects the two named ports. \fBjack_disconnect\fR disconnects the two named ports.
.SH RETURNS .SH RETURNS
The exit status is zero if successful, 1 otherwise The exit status is zero if successful, 1 otherwise



+ 1
- 1
posix/JackPosixSemaphore.cpp View File

@@ -187,7 +187,7 @@ bool JackPosixSemaphore::ConnectOutput(const char* name, const char* server_name
bool JackPosixSemaphore::Disconnect() bool JackPosixSemaphore::Disconnect()
{ {
if (fSemaphore) { if (fSemaphore) {
jack_log("JackPosixSemaphore::Disconnect name = %s", fName);
jack_log("JackPosixSemaphore::Disconnect name = %s", fName);
if (sem_close(fSemaphore) != 0) { if (sem_close(fSemaphore) != 0) {
jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno)); jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno));
return false; return false;


+ 2
- 0
posix/JackSocket.cpp View File

@@ -188,6 +188,7 @@ int JackClientSocket::Read(void* data, int len)
jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
return 0; return 0;
} else { } else {
jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
return -1; return -1;
} }
} else { } else {
@@ -232,6 +233,7 @@ int JackClientSocket::Write(void* data, int len)
jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno)); jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
return 0; return 0;
} else { } else {
jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
return -1; return -1;
} }
} else { } else {


+ 6
- 5
posix/JackSocketClientChannel.cpp View File

@@ -62,13 +62,14 @@ int JackSocketClientChannel::Open(const char* server_name, const char* name, int
} }


// Check name in server // Check name in server
ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true);
if (result < 0) { if (result < 0) {
int status1 = *status; int status1 = *status;
if (status1 & JackVersionError)
if (status1 & JackVersionError) {
jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
else
} else {
jack_error("Client name = %s conflits with another running client", name); jack_error("Client name = %s conflits with another running client", name);
}
goto error; goto error;
} }


@@ -141,9 +142,9 @@ void JackSocketClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res,
} }
} }


void JackSocketClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result)
void JackSocketClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open)
{ {
JackClientCheckRequest req(name, protocol, options, uuid);
JackClientCheckRequest req(name, protocol, options, uuid, open);
JackClientCheckResult res; JackClientCheckResult res;
ServerSyncCall(&req, &res, result); ServerSyncCall(&req, &res, result);
*status = res.fStatus; *status = res.fStatus;


+ 1
- 1
posix/JackSocketClientChannel.h View File

@@ -60,7 +60,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi


int ServerCheck(const char* server_name); int ServerCheck(const char* server_name);


void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result);
void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open);
void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result);
void ClientOpen(const char* name, int* ref, int uuid, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) void ClientOpen(const char* name, int* ref, int uuid, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result)
{} {}


+ 4
- 1
posix/JackSocketServerChannel.cpp View File

@@ -164,7 +164,7 @@ bool JackSocketServerChannel::HandleRequest(int fd)
JackRequest header; JackRequest header;
if (header.Read(socket) < 0) { if (header.Read(socket) < 0) {
jack_log("HandleRequest: cannot read header"); jack_log("HandleRequest: cannot read header");
ClientKill(fd); // TO CHECK SOLARIS
ClientKill(fd);
return false; return false;
} }


@@ -185,6 +185,9 @@ bool JackSocketServerChannel::HandleRequest(int fd)
res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus); res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
if (res.Write(socket) < 0) if (res.Write(socket) < 0)
jack_error("JackRequest::ClientCheck write error name = %s", req.fName); jack_error("JackRequest::ClientCheck write error name = %s", req.fName);
// Atomic ClientCheck followed by ClientOpen on same socket
if (req.fOpen)
HandleRequest(fd);
break; break;
} }




+ 13
- 9
windows/JackWinNamedPipeClientChannel.cpp View File

@@ -55,10 +55,10 @@ int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* nam


/* /*
16/08/07: was called before doing "fRequestPipe.Connect" .... still necessary? 16/08/07: was called before doing "fRequestPipe.Connect" .... still necessary?
if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) {
jack_error("Cannot bind pipe");
goto error;
}
if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) {
jack_error("Cannot bind pipe");
goto error;
}
*/ */


if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) { if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) {
@@ -67,10 +67,14 @@ int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* nam
} }


// Check name in server // Check name in server
ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true);
if (result < 0) { if (result < 0) {
jack_error("Client name = %s conflits with another running client", name);
goto error;
int status1 = *status;
if (status1 & JackVersionError) {
jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
} else {
jack_error("Client name = %s conflits with another running client", name);
}
} }


if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) { if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) {
@@ -142,9 +146,9 @@ void JackWinNamedPipeClientChannel::ServerAsyncCall(JackRequest* req, JackResult
} }
} }


void JackWinNamedPipeClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result)
void JackWinNamedPipeClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open)
{ {
JackClientCheckRequest req(name, protocol, options, uuid);
JackClientCheckRequest req(name, protocol, options, uuid, open);
JackClientCheckResult res; JackClientCheckResult res;
ServerSyncCall(&req, &res, result); ServerSyncCall(&req, &res, result);
*status = res.fStatus; *status = res.fStatus;


+ 1
- 1
windows/JackWinNamedPipeClientChannel.h View File

@@ -59,7 +59,7 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface,


int ServerCheck(const char* server_name); int ServerCheck(const char* server_name);


void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result);
void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open);
void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result);
void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result)
{} {}


+ 7
- 4
windows/JackWinNamedPipeServerChannel.cpp View File

@@ -117,6 +117,9 @@ bool JackClientPipeThread::HandleRequest()
if (req.Read(fPipe) == 0) if (req.Read(fPipe) == 0)
res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus); res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
res.Write(fPipe); res.Write(fPipe);
// Atomic ClientCheck followed by ClientOpen on same pipe
if (req.fOpen)
HandleRequest();
break; break;
} }


@@ -477,11 +480,11 @@ int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* ser
void JackWinNamedPipeServerChannel::Close() void JackWinNamedPipeServerChannel::Close()
{ {
/* TODO : solve WIN32 thread Kill issue /* TODO : solve WIN32 thread Kill issue
This would hang the server... since we are quitting it, its not really problematic,
all ressources will be deallocated at the end.
This would hang the server... since we are quitting it, its not really problematic,
all ressources will be deallocated at the end.


fRequestListenPipe.Close();
fThread.Stop();
fRequestListenPipe.Close();
fThread.Stop();
*/ */


fThread.Kill(); fThread.Kill();


+ 1
- 0
windows/libjackserver.cbp View File

@@ -241,6 +241,7 @@
<Unit filename="..\common\JackActivationCount.cpp" /> <Unit filename="..\common\JackActivationCount.cpp" />
<Unit filename="..\common\JackArgParser.cpp" /> <Unit filename="..\common\JackArgParser.cpp" />
<Unit filename="..\common\JackAudioDriver.cpp" /> <Unit filename="..\common\JackAudioDriver.cpp" />
<Unit filename="..\common\JackTimedDriver.cpp" />
<Unit filename="..\common\JackAudioPort.cpp" /> <Unit filename="..\common\JackAudioPort.cpp" />
<Unit filename="..\common\JackClient.cpp" /> <Unit filename="..\common\JackClient.cpp" />
<Unit filename="..\common\JackConnectionManager.cpp" /> <Unit filename="..\common\JackConnectionManager.cpp" />


Loading…
Cancel
Save