Browse Source

Merge branch 'master' into js-dbus

tags/1.9.8
Stephane Letz 13 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
---------------------------

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>

* NetJack2: improve error reporting.


+ 0
- 17
common/JackAPI.cpp View File

@@ -127,7 +127,6 @@ extern "C"
unsigned long buffer_size);
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_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_short_name(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)
{
#ifdef __CLIENTDEBUG__


+ 8
- 3
common/JackAudioAdapter.cpp View File

@@ -42,9 +42,12 @@ namespace Jack
// Always clear output
for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) {
#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));
}
#else
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));
@@ -53,7 +56,9 @@ namespace Jack

for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) {
#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
outputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames);
#endif


+ 6
- 21
common/JackAudioDriver.cpp View File

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

/*
void JackAudioDriver::WaitUntilNextCycle()
{
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)
JackSleep(wait_time_usec);
}
*/

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

void WaitUntilNextCycle();

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

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

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

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


+ 1
- 1
common/JackChannel.h View File

@@ -74,7 +74,7 @@ class JackClientChannelInterface
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)
{}


+ 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;

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

// Done all time: redirected on subclass implementation JackLibClient and JackInternalClient
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);
}

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

LIB_EXPORT void
SERVER_EXPORT void
jackctl_wait_signals(sigset_t signals)
{
int sig;
@@ -631,7 +631,7 @@ get_realtime_priority_constraint()
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),
void (* on_device_release)(const char * device_name))
{
@@ -813,7 +813,7 @@ fail:
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_internals(server_ptr);
@@ -821,18 +821,18 @@ LIB_EXPORT void jackctl_server_destroy(jackctl_server *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;
}

LIB_EXPORT bool jackctl_server_stop(jackctl_server *server_ptr)
SERVER_EXPORT bool jackctl_server_stop(jackctl_server *server_ptr)
{
server_ptr->engine->Stop();
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();
delete server_ptr->engine;
@@ -855,12 +855,12 @@ LIB_EXPORT bool jackctl_server_close(jackctl_server *server_ptr)
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;
}

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

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_start(
jackctl_server *server_ptr)
{
@@ -957,47 +957,47 @@ jackctl_server_start(
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;
}

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;
}

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;
}

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;
}

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;
}

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;
}

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;
}

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;
}

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))
{
@@ -1007,7 +1007,7 @@ LIB_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_paramet
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;
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;
}

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;
}

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)
{
@@ -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;
}

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;
}

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;
}

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;
}

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;
}

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;
}

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)
{
@@ -1103,7 +1103,7 @@ LIB_EXPORT bool jackctl_parameter_reset(jackctl_parameter *parameter_ptr)
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;

@@ -1162,29 +1162,29 @@ LIB_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, co
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;
}

// 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;
}

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;
}

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;
}

LIB_EXPORT bool jackctl_server_load_internal(
SERVER_EXPORT bool jackctl_server_load_internal(
jackctl_server * server_ptr,
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_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->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->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) {
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 */
#endif

LIB_EXPORT sigset_t
SERVER_EXPORT sigset_t
jackctl_setup_signals(
unsigned int flags);

LIB_EXPORT void
SERVER_EXPORT void
jackctl_wait_signals(
sigset_t signals);

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

LIB_EXPORT void
SERVER_EXPORT void
jackctl_server_destroy(
jackctl_server_t * server);

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

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

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_start(
jackctl_server_t * server);

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_stop(
jackctl_server_t * server);

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_close(
jackctl_server_t * server);

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

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

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

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

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

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

LIB_EXPORT jackctl_param_type_t
SERVER_EXPORT jackctl_param_type_t
jackctl_parameter_get_type(
jackctl_parameter_t * parameter);

LIB_EXPORT char
SERVER_EXPORT char
jackctl_parameter_get_id(
jackctl_parameter_t * parameter);

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_is_set(
jackctl_parameter_t * parameter);

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_reset(
jackctl_parameter_t * parameter);

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

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_set_value(
jackctl_parameter_t * parameter,
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_t * parameter);

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

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_has_range_constraint(
jackctl_parameter_t * parameter_ptr);

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_has_enum_constraint(
jackctl_parameter_t * parameter_ptr);

LIB_EXPORT uint32_t
SERVER_EXPORT uint32_t
jackctl_parameter_get_enum_constraints_count(
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_t * parameter_ptr,
uint32_t index);

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

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

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_constraint_is_strict(
jackctl_parameter_t * parameter_ptr);

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_parameter_constraint_is_fake_value(
jackctl_parameter_t * parameter_ptr);

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

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

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

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

LIB_EXPORT bool jackctl_server_unload_internal(
SERVER_EXPORT bool jackctl_server_unload_internal(
jackctl_server * server,
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);

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

LIB_EXPORT bool
SERVER_EXPORT bool
jackctl_server_switch_master(jackctl_server_t * server,
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.
*/

class SERVER_EXPORT JackDebugClient : public JackClient
class LIB_EXPORT JackDebugClient : public JackClient
{
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)
{
jack_log("JackDriver::ClientNotify ref = %ld driver = %s name = %s notify = %ld", refnum, fClientControl.fName, name, notify);

switch (notify) {

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

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

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

int JackDriver::Attach()
{
return 0;


+ 17
- 19
common/JackDriver.h View File

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

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,
jack_nframes_t samplerate,
@@ -88,7 +88,6 @@ class SERVER_EXPORT JackDriverInterface
virtual int SetSampleRate(jack_nframes_t sample_rate) = 0;

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

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

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,
jack_nframes_t samplerate,
@@ -199,8 +198,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface
virtual int Close();

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

virtual int Attach();
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)
{
struct option * long_options;
@@ -173,10 +173,10 @@ jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSLi
if (optarg) {
switch (desc->params[param_index].type) {
case JackDriverParamInt:
driver_param->value.i = atoi (optarg);
driver_param->value.i = atoi(optarg);
break;
case JackDriverParamUInt:
driver_param->value.ui = strtoul (optarg, NULL, 10);
driver_param->value.ui = strtoul(optarg, NULL, 10);
break;
case JackDriverParamChar:
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);
break;
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;

} else {
@@ -317,11 +308,11 @@ jackctl_parse_driver_params(jackctl_driver *driver_ptr, int argc, char* argv[])
if (optarg) {
switch (jackctl_parameter_get_type(param)) {
case JackDriverParamInt:
value.i = atoi (optarg);
value.i = atoi(optarg);
jackctl_parameter_set_value(param, &value);
break;
case JackDriverParamUInt:
value.ui = strtoul (optarg, NULL, 10);
value.ui = strtoul(optarg, NULL, 10);
jackctl_parameter_set_value(param, &value);
break;
case JackDriverParamChar:
@@ -329,23 +320,15 @@ jackctl_parse_driver_params(jackctl_driver *driver_ptr, int argc, char* argv[])
jackctl_parameter_set_value(param, &value);
break;
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);
break;
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;
} else {
value.i = true;
@@ -835,7 +818,7 @@ JackDriverInfo::~JackDriverInfo()
UnloadDriverModule(fHandle);
}

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

LIB_EXPORT
SERVER_EXPORT
int
jack_driver_descriptor_add_parameter(
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 "JackEngineControl.h"
#include "JackGraphManager.h"
#include "JackDriverLoader.h"
#include "JackThreadedDriver.h"
#include "JackCompilerDeps.h"
@@ -28,61 +26,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <unistd.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
extern "C"
@@ -117,10 +60,10 @@ extern "C"

SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) {
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 playback_ports = 2;
unsigned long wait_time = 0;
int wait_time = 0;
const JSList * node;
const jack_driver_param_t * param;
bool monitor = false;
@@ -143,7 +86,7 @@ extern "C"
break;

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

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;
} else {
delete driver;


+ 5
- 30
common/JackDummyDriver.h View File

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

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

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

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

long fWaitTime;

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()
{}

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


+ 6
- 11
common/JackEngine.cpp View File

@@ -140,7 +140,6 @@ void JackEngine::ProcessNext(jack_time_t cur_cycle_begin)
fLastSwitchUsecs = cur_cycle_begin;
if (fGraphManager->RunNextGraph()) { // True if the graph actually switched to a new state
fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0);
//NotifyGraphReorder();
}
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) {
jack_error("JackEngine::XRun: client = %s was not run: state = %ld", client->GetClientControl()->fName, status);
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients
//NotifyXRun(ALL_CLIENTS);
}

if (status == Finished && (long)(finished_date - callback_usecs) > 0) {
jack_error("JackEngine::XRun: client %s finished after current callback", client->GetClientControl()->fName);
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.
for (int i = 0; i < CLIENT_NUM; 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) {
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) {
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++) {
JackClientInterface* client = fClientTable[i];
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
fEngineControl->NotifyXRun(callback_usecs, delayed_usecs);
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0);
//NotifyXRun(ALL_CLIENTS);
}

void JackEngine::NotifyXRun(int refnum)
@@ -427,7 +423,7 @@ int JackEngine::ClientCheck(const char* name, int uuid, char* name_res, int prot
*status = 0;
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) {
*status |= (JackFailure | JackVersionError);
@@ -563,7 +559,6 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref
} else {
strncpy(real_name, name, JACK_CLIENT_NAME_SIZE);
}

EnsureUUID(uuid);
}

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

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]);
}

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]);
}



+ 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 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);
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);
return -1;
}
// Use "placement new" to allocate object in shared memory
JackShmMemAble* shared_mem = static_cast<JackShmMemAble*>(JackShmMem::operator new(sizeof(JackClientControl)));
shared_mem->Init();
fClientControl = new(shared_mem) JackClientControl(name, pid, refnum, uuid);
if (!fClientControl) {
jack_error("Cannot allocate client shared memory segment");
return -1;
}
*shared_client = shared_mem->GetShmIndex();
jack_log("JackExternalClient::Open name = %s index = %ld base = %x", name, shared_mem->GetShmIndex(), shared_mem->GetShmAddress());
return 0;


+ 2
- 2
common/JackExternalClient.h View File

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

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:



+ 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.
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



+ 7
- 6
common/JackInternalClient.cpp View File

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

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

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

LIB_EXPORT JackSynchro* GetSynchroTable()
SERVER_EXPORT JackSynchro* 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));

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) {
int status1 = *status;
if (status1 & JackVersionError)
if (status1 & JackVersionError) {
jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
else
} else {
jack_error("Client name = %s conflits with another running client", name);
}
goto error;
}



+ 1
- 1
common/JackInternalClientChannel.h View File

@@ -50,7 +50,7 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface
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);
}


+ 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_options_t options,
jack_status_t *status, va_list ap);

LIB_EXPORT jack_client_t * jack_client_open (const char *client_name,
jack_options_t options,
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.

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.

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

SetupDriverSync(false);
// 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)) {
jack_error("Cannot ConnectSemaphore %s client", name_res);
goto error;
}
JackGlobals::fClientTable[GetClientControl()->fRefNum] = this;
JackGlobals::fServerRunning = true;
SetClockSource(GetEngineControl()->fClockSource);
@@ -146,7 +143,7 @@ int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int

case kRemoveClient:
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;
break;
}


+ 1
- 1
common/JackLibClient.h View File

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

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

private:


+ 1
- 1
common/JackLibGlobals.h View File

@@ -50,7 +50,7 @@ class JackClient;
\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<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)
{
JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer;
if (!buf || !buf->IsValid())
if (!buf || !buf->IsValid()) {
return 0;
}
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)
{
JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer;
if (!buf || !buf->IsValid())
if (!buf || !buf->IsValid()) {
return -EINVAL;
if (event_index >= buf->event_count)
}
if (event_index >= buf->event_count) {
return -ENOBUFS;
}
JackMidiEvent* ev = &buf->events[event_index];
event->time = ev->time;
event->size = ev->size;
@@ -81,8 +84,9 @@ LIB_EXPORT
void jack_midi_clear_buffer(void* port_buffer)
{
JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer;
if (buf && buf->IsValid())
if (buf && buf->IsValid()) {
buf->Reset(buf->nframes);
}
}

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)
{
JackMidiBuffer *buf = (JackMidiBuffer*)port_buffer;
if (!buf && !buf->IsValid())
if (!buf && !buf->IsValid()) {
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;
}
jack_midi_data_t* dest = buf->ReserveEvent(time, data_size);
if (!dest)
if (!dest) {
return -ENOBUFS;
}
memcpy(dest, data, data_size);
return 0;
}


+ 0
- 5
common/JackMidiDriver.cpp View File

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

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

int JackMidiDriver::ProcessRead()
{
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 ProcessWrite();

virtual int ProcessNull();

virtual int Attach();
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
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

enum JackNetMode {

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

enum JackNetEncoder {

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

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

} 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_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

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

// 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
if (fSocket.SetLocalLoop() == SOCKET_ERROR)
if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
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)
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));
}

//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 rx_bytes = 0;

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

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

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

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

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

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

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

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
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut))
if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) {
return -1;
}

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

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

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

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

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

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

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

void AllocPorts()
{
int port_index;

// Set buffers
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];
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];
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];
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()
{
int port_index;

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;
fAudioCaptureBuffer = NULL;
}

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;
fMidiCaptureBuffer = NULL;
}

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;
fAudioPlaybackBuffer = NULL;
}

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;
fMidiPlaybackBuffer = NULL;
}
@@ -621,7 +629,11 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
bool Init()
{
// 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
}

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

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();
return DataRecv();
@@ -665,18 +678,19 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
{
EncodeSyncPacket();

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

return DataSend();
}

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;
}

fProcessCallback(fParams.fPeriodSize,
fParams.fSendAudioChannels,
@@ -689,10 +703,10 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf
(void**)fMidiPlaybackBuffer,
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 0;
}
@@ -777,17 +791,20 @@ struct JackNetAdapter : public JackAudioAdapterInterface {
{
//ringbuffers

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

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

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

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

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_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)


+ 13
- 15
common/JackNetAdapter.cpp View File

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

@@ -94,15 +95,11 @@ namespace Jack
}
break;
#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;
case 'q':
@@ -276,20 +273,20 @@ namespace Jack
{
case JackTransportStopped :
jack_transport_stop(fJackClient);
jack_info("NetMaster : transport stops.");
jack_info("NetMaster : transport stops");
break;

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

case JackTransportRolling :
// TODO, we need to :
// - find a way to call TransportEngine->SetNetworkSync()
// - turn the transport state to JackTransportRolling
jack_info("NetMaster : transport rolls.");
jack_info("NetMaster : transport rolls");
break;
}
}
@@ -412,8 +409,8 @@ extern "C"
value.ui = 1U;
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;
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 (...) {
jack_info("NetAdapter allocation error");
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

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,
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);

// 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);
}

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

//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()
{
#ifdef JACK_MONITOR
if (fNetTimeMon)
if (fNetTimeMon) {
fNetTimeMon->Save();
}
#endif
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)
@@ -185,20 +169,7 @@ namespace Jack
plot_name = string(fParams.fName);
plot_name += string("_slave");
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);
string net_time_mon_fields[] =
{
@@ -216,8 +187,8 @@ namespace Jack
fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 5);
#endif
// Driver parametering
JackAudioDriver::SetBufferSize(fParams.fPeriodSize);
JackAudioDriver::SetSampleRate(fParams.fSampleRate);
JackTimedDriver::SetBufferSize(fParams.fPeriodSize);
JackTimedDriver::SetSampleRate(fParams.fSampleRate);

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

//audio
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(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, audio_port_index + 1);
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);
return -1;
}

//port latency
port = fGraphManager->GetPort(port_index);
port->SetAlias(alias);
//port latency
range.min = range.max = fEngineControl->fBufferSize;
port->SetLatencyRange(JackCaptureLatency, &range);
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());
}

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(name, sizeof(name) - 1, "%s:playback_%d",fClientControl.fName, audio_port_index + 1);
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);
return -1;
}

//port latency
port = fGraphManager->GetPort(port_index);
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);
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());
}

//midi
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(name, sizeof (name) - 1, "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1);
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);
return -1;
}
port = fGraphManager->GetPort(port_index);
//port latency
port = fGraphManager->GetPort(port_index);
range.min = range.max = fEngineControl->fBufferSize;
port->SetLatencyRange(JackCaptureLatency, &range);
fMidiCapturePortList[midi_port_index] = port_index;
@@ -342,30 +301,18 @@ namespace Jack
}

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(name, sizeof(name) - 1, "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1);
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);
return -1;
}
port = fGraphManager->GetPort(port_index);
//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);
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());
@@ -413,7 +360,7 @@ namespace Jack
const char** connections;
fConnections.clear();

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

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

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

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

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

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

#ifdef JACK_MONITOR
// For timing
@@ -581,7 +537,7 @@ namespace Jack
for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
#ifdef OPTIMIZED_PROTOCOL
// 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));
} else {
fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL);
@@ -599,16 +555,18 @@ namespace Jack
EncodeSyncPacket();

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

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

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

#ifdef JACK_MONITOR
fNetTimeMon->AddLast(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
@@ -655,11 +613,11 @@ namespace Jack
strcpy(value.str, "'hostname'");
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);

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

@@ -732,15 +691,12 @@ namespace Jack
case 't' :
transport_sync = param->value.ui;
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;
}
}
@@ -751,7 +707,7 @@ namespace Jack
new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu,
midi_input_ports, midi_output_ports,
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) {
return driver;
} 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

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__
#define __JackNetDriver__

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

//#define JACK_MONITOR

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

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

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

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

// The
int Process();
int Attach();
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

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
{

#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
@@ -40,7 +52,7 @@ namespace Jack
JackNetSocket fSocket;
char fMulticastIP[32];

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

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

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

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

//utility methods
// utility methods
int SetNetBufferSize();
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 Init() = 0;

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

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

@@ -84,14 +96,23 @@ namespace Jack
virtual int Send(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(const char* multicast_ip, int port);
JackNetInterface(session_params_t& params, JackNetSocket& socket, const char* multicast_ip);

public:

virtual ~JackNetInterface();

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

bool fRunning;
int fCycleOffset;

int fCurrentCycleOffset;
int fMaxCycleOffset;
int fLastfCycleOffset;

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

//sync packet
// sync packet
void EncodeSyncPacket();
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();

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

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;

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

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

//sync packet
// sync packet
void EncodeSyncPacket();
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:

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

#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

+ 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
it under the terms of the GNU General Public License as published by
@@ -29,13 +29,13 @@ namespace Jack
{
//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
fClientName = const_cast<char*> ( fParams.fName );
fClientName = const_cast<char*>(fParams.fName);
fJackClient = NULL;
fSendTransportData.fState = -1;
fReturnTransportData.fState = -1;
@@ -44,64 +44,59 @@ namespace Jack

//jack audio ports
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;
}

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;
}

//jack midi ports
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;
}

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;
}

//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;
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 ( "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 ( "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
}

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();
jack_client_close ( fJackClient );
jack_client_close(fJackClient);
}
delete[] fAudioCapturePorts;
delete[] fAudioPlaybackPorts;
@@ -117,33 +112,33 @@ namespace Jack
{
//network init
if (!JackNetMasterInterface::Init()) {
jack_error("JackNetMasterInterface::Init() error..." );
jack_error("JackNetMasterInterface::Init() error...");
return false;
}

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

//jack client and process
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;
}

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;
}

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

//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;
}

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

fail:
FreePorts();
jack_client_close ( fJackClient );
jack_client_close(fJackClient);
fJackClient = NULL;
return false;
}
@@ -174,76 +169,47 @@ namespace Jack
{
int i;
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_log ( "JackNetMaster::AllocPorts" );
jack_log("JackNetMaster::AllocPorts");

//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;
//port latency
range.min = range.max = 0;
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;
//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
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;
//port latency
range.min = range.max = 0;
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;
//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;
}
@@ -271,21 +237,29 @@ namespace Jack

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

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---------------------------------------------------------------------------
@@ -296,26 +270,26 @@ namespace Jack
fSendTransportData.fTimebaseMaster = NO_CHANGE;

//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 ?
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;
}

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

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

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 < 0)
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 ?
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 :
jack_transport_stop ( fJackClient );
jack_info ( "'%s' stops transport", fParams.fName );
jack_transport_stop(fJackClient);
jack_info("'%s' stops transport", fParams.fName);
break;

case JackTransportStarting :
if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) == EINVAL )
jack_error ( "Can't set new position" );
jack_transport_start ( fJackClient );
jack_info ( "'%s' starts transport frame = %d", 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;

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

case JackTransportRolling :
jack_info ( "'%s' is rolling", fParams.fName );
jack_info("'%s' is rolling", fParams.fName);
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->beat = fReturnTransportData.fPosition.beat;
@@ -393,7 +367,7 @@ namespace Jack

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

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

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

#ifdef JACK_MONITOR
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++) {

#ifdef OPTIMIZED_PROTOCOL
if ((intptr_t)fNetAudioCaptureBuffer->GetBuffer(audio_port_index) == -1) {
if (fNetAudioCaptureBuffer->GetConnected(audio_port_index)) {
// Port is connected on other side...
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 {
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++) {

#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
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
}

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

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

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

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

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

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

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

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

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

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

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

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

//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;
fManagerName = jack_get_client_name ( fManagerClient );
fManagerName = jack_get_client_name(fManagerClient);
fGlobalID = 0;
fRunning = true;
fAutoConnect = false;
@@ -588,20 +573,21 @@ namespace Jack
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' :
if (strlen (param->value.str) < 32)
if (strlen(param->value.str) < 32) {
strcpy(fMulticastIP, param->value.str);
else
} else {
jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP);
}
break;

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

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

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

//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
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()
{
jack_log ( "JackNetMasterManager::~JackNetMasterManager" );
jack_info ( "Exiting net manager..." );
jack_log("JackNetMasterManager::~JackNetMasterManager");
jack_info("Exiting NetManager...");
fRunning = false;
jack_client_kill_thread ( fManagerClient, fManagerThread );
jack_client_kill_thread(fManagerClient, fManagerThread);
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();
SocketAPIEnd();
}
@@ -653,35 +642,37 @@ namespace Jack
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
int ret = 1;
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;
jack_log ( "JackNetMasterManager::SyncCallback returns '%s'", ( ret ) ? "true" : "false" );
}
}
jack_log("JackNetMasterManager::SyncCallback returns '%s'", (ret) ? "true" : "false");
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();
return NULL;
}

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

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

//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;
}

//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;
}

//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();
return;
}

//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
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)
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
do
{
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);
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;
}
}
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:
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;
case KILL_MASTER:
if ( KillMaster ( &host_params ) )
jack_info ( "Waiting for a slave..." );
if (KillMaster(&host_params)) {
jack_info("Waiting for a slave...");
}
break;
default:
break;
}
}
}
while ( fRunning );
while (fRunning);
}

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

//check MASTER <<==> SLAVE network protocol coherency
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;
}

//settings
fSocket.GetName ( params.fMasterNetName );
fSocket.GetName(params.fMasterNetName);
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) {
params.fSendAudioChannels = CountIO(JackPortIsPhysical | JackPortIsOutput);
@@ -800,35 +791,38 @@ namespace Jack
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;
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;
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;
}

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;
return 1;
}
@@ -851,7 +845,7 @@ extern "C"

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

value.i = DEFAULT_PORT;
@@ -863,48 +857,46 @@ extern "C"
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;
}
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;
bool parse_params = true;
int res = 1;
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) {
res = jack_internal_initialize ( jack_client, params );
parser.FreeParams ( params );
res = jack_internal_initialize(jack_client, params);
parser.FreeParams(params);
}
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;
master_manager = NULL;
}
}

#ifdef __cplusplus
}
#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
it under the terms of the GNU General Public License as published by
@@ -40,9 +40,9 @@ namespace Jack

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_t* fJackClient;
@@ -72,13 +72,13 @@ namespace Jack
void DecodeTransportData();

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

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();
};
@@ -96,8 +96,8 @@ namespace Jack

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;
const char* fManagerName;
@@ -110,18 +110,18 @@ namespace Jack
bool fAutoConnect;

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

public:

JackNetMasterManager ( jack_client_t* jack_client, const JSList* params);
JackNetMasterManager(jack_client_t* jack_client, const JSList* params);
~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
it under the terms of the GNU General Public License as published by
@@ -46,21 +45,21 @@ using namespace std;

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 sample_rate, int period_size, int resample_factor,
const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig,
int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val )
: JackAudioDriver ( name, alias, engine, table )
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
WSADATA wsa;
int rc = WSAStartup(MAKEWORD(2, 0), &wsa);
#endif

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

//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()
{
// Generic audio driver close
int res = JackAudioDriver::Close();
int res = JackTimedDriver::Close();

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

//monitor
//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::NotifySampleRate ( netj.sample_rate );
@@ -269,6 +251,12 @@ bool JackNetOneDriver::Initialize()
//jack ports and buffers--------------------------------------------------------------

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

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


+ 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
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__
#define __JackNetDriver__

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

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

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

@@ -59,15 +58,13 @@ class JackNetOneDriver : public JackAudioDriver
int sample_rate, int period_size, int resample_factor,
const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig,
int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val);
~JackNetOneDriver();

int Open(jack_nframes_t frames_per_cycle, jack_nframes_t rate, bool capturing, bool playing,
int inchannels, int outchannels, bool monitor, const char* capture_driver_name,
const char* playback_driver_name, jack_nframes_t capture_latency, jack_nframes_t playback_latency);
virtual ~JackNetOneDriver();

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

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

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

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

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



+ 368
- 244
common/JackNetTool.cpp View File

@@ -97,12 +97,14 @@ namespace Jack
fMaxPcktSize = params->fMtu - sizeof(packet_header_t);
fBuffer = new char[fMaxBufsize];
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;
}
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()
@@ -113,14 +115,14 @@ namespace Jack

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

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)
@@ -137,10 +139,11 @@ namespace Jack
{
for (int port_index = 0; port_index < fNPorts; port_index++) {
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",
port_index + 1, event + 1, fPortBuffer[port_index]->event_count,
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);
memcpy(fBuffer + pos, fPortBuffer[port_index], 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;

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

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

// 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)
: 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()
{}

// needed size in bytes for an entire cycle
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 *********************************************************************************

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

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];
fCeltEncoder = new CELTEncoder *[fNPorts];
fCeltDecoder = new CELTDecoder *[fNPorts];
@@ -278,77 +495,84 @@ namespace Jack

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

#if HAVE_CELT_API_0_11

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

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

#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8

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

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

#else

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

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

#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:

@@ -360,22 +584,25 @@ namespace Jack
{
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;
delete [] fPortBuffer;
}

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

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

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

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

int NetCeltAudioBuffer::GetNumPackets()
int NetCeltAudioBuffer::GetNumPackets(int active_ports)
{
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++) {
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
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
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
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()
@@ -436,47 +654,42 @@ namespace Jack
int res = celt_decode_float(fCeltDecoder[port_index], fCompressedBuffer[port_index], fCompressedSizeByte, fPortBuffer[port_index]);
#endif
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
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) {
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);
}
} 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);
}
}

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) {
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);
}
return fNPorts * fLastSubPeriodBytesSize;
} 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);
}
return fNPorts * fSubPeriodBytesSize;
}
}
@@ -484,42 +697,34 @@ namespace Jack
#endif

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;

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];
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];
}

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;

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

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);
fCycleSize = params->fMtu * fNumPackets;
fCycleBytesSize = params->fMtu * fNumPackets;

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

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;
delete [] fPortBuffer;
}

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

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

int NetIntAudioBuffer::GetNumPackets()
int NetIntAudioBuffer::GetNumPackets(int active_ports)
{
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 (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);
}
}

// All ports active
return fNPorts;
}

void NetIntAudioBuffer::RenderToJackPorts()
{
float coef = 1.f / 32768.f;
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);
}
}

// 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) {
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);
}
} 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);
}
}

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) {
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);
}
return fNPorts * fLastSubPeriodBytesSize;
} 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);
}
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 ************************************************************************************

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->fSampleEncoder = htonl(src_params->fSampleEncoder);
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)
@@ -707,6 +845,7 @@ namespace Jack
dst_params->fPeriodSize = ntohl(src_params->fPeriodSize);
dst_params->fSampleEncoder = ntohl(src_params->fSampleEncoder);
dst_params->fSlaveSyncMode = ntohl(src_params->fSlaveSyncMode);
dst_params->fNetworkLatency = ntohl(src_params->fNetworkLatency);
}

SERVER_EXPORT void SessionParamsDisplay(session_params_t* params)
@@ -725,19 +864,6 @@ namespace Jack
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("Name : %s", params->fName);
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("Sample rate : %u frames per second", params->fSampleRate);
jack_info("Period size : %u frames per period", params->fPeriodSize);
jack_info("Network latency : %u cycles", params->fNetworkLatency);
switch (params->fSampleEncoder) {
case (JackFloatEncoder):
jack_info("SampleEncoder : %s", "Float");
@@ -763,7 +890,6 @@ namespace Jack
break;
};
jack_info("Slave mode : %s", (params->fSlaveSyncMode) ? "sync" : "async");
jack_info("Network mode : %s", mode);
jack_info("****************************************************");
}

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

if (WSAStartup(wVersionRequested, &wsaData) != 0)
{
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
jack_error("WSAStartup error : %s", strerror(NET_ERROR_CODE));
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");
WSACleanup();
return -1;


+ 70
- 516
common/JackNetTool.h View File

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

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

#define NET_PACKET_ERROR -2

#define OPTIMIZED_PROTOCOL

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

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

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

char* fBuffer;
char* fNetBuffer;
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:

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

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

int GetNumPackets(int data_sizen, int max_size);

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

//utility
void DisplayEvents();

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

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

// audio data *********************************************************************************
@@ -270,12 +274,33 @@ namespace Jack
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:

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
virtual size_t GetCycleSize() = 0;
@@ -283,414 +308,55 @@ namespace Jack
// cycle duration in sec
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
virtual void RenderFromJackPorts() = 0;
virtual void RenderToJackPorts() = 0;
virtual int RenderFromJackPorts();
virtual void RenderToJackPorts();

//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
{

private:

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

void UpdateParams(int active_ports);

public:

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

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

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

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

//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
@@ -706,45 +372,33 @@ namespace Jack
CELTDecoder** fCeltDecoder;

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

size_t fSubPeriodBytesSize;
size_t fLastSubPeriodBytesSize;

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

int fNPorts;
int fLastSubCycle;

void FreeCelt();

public:

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

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

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

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

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

//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
@@ -754,133 +408,33 @@ namespace Jack
private:

int fCompressedSizeByte;
jack_nframes_t fPeriodSize;

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;

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

int fNPorts;
int fLastSubCycle;
short** fIntBuffer;

public:

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

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

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

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

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

//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 *************************************************************************************

//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)
{
jack_port_type_id_t id = GetPortTypeId(port_type);
assert(id >= 0 && id <= PORT_TYPES_MAX);
if (id == PORT_TYPES_MAX)
return false;
fTypeId = id;


+ 7
- 4
common/JackRequest.h View File

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

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);
}
@@ -163,7 +164,8 @@ struct JackClientCheckRequest : public JackRequest
CheckRes(trans->Read(&fName, sizeof(fName)));
CheckRes(trans->Read(&fProtocol, 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)
@@ -172,7 +174,8 @@ struct JackClientCheckRequest : public JackRequest
CheckRes(trans->Write(&fName, sizeof(fName)));
CheckRes(trans->Write(&fProtocol, 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 "JackTime.h"
#include "JackFreewheelDriver.h"
#include "JackDummyDriver.h"
#include "JackThreadedDriver.h"
#include "JackGlobals.h"
#include "JackLockedEngine.h"


+ 9
- 12
common/JackServerAPI.cpp View File

@@ -33,17 +33,14 @@ extern "C"
{
#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_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
}
@@ -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__
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__
JackGlobals::CheckContext("jack_client_close");
@@ -198,7 +195,7 @@ LIB_EXPORT int jack_client_close(jack_client_t* ext_client)
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)
? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name)


+ 12
- 9
common/JackShmMem.h View File

@@ -156,11 +156,12 @@ class JackShmReadWritePtr
{
if (fInfo.index < 0 && index >= 0) {
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;
if (jack_attach_lib_shm(&fInfo)) {
throw - 2;
throw std::bad_alloc();
}
GetShmAddress()->LockMemory();
}
@@ -237,11 +238,12 @@ class JackShmReadWritePtr1
{
if (fInfo.index < 0 && index >= 0) {
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;
if (jack_attach_lib_shm(&fInfo)) {
throw - 2;
throw std::bad_alloc();
}
/*
nobody else needs to access this shared memory any more, so
@@ -324,11 +326,12 @@ class JackShmReadPtr
{
if (fInfo.index < 0 && index >= 0) {
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;
if (jack_attach_lib_shm_read(&fInfo)) {
throw - 2;
throw std::bad_alloc();
}
GetShmAddress()->LockMemory();
}


+ 21
- 17
common/JackThreadedDriver.cpp View File

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

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

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

int JackThreadedDriver::Attach()
{
return fDriver->Attach();
@@ -228,22 +224,30 @@ bool JackThreadedDriver::Execute()
bool JackThreadedDriver::Init()
{
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;
} else {
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

+ 2
- 13
common/JackThreadedDriver.h View File

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

void SetRealTime();

public:

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

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

virtual int Attach();
virtual int Detach();
@@ -110,18 +111,6 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi
virtual bool Execute();
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


+ 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 int GetTmpdir();
static void RewriteName ( const char* name, char* new_name );
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 "JackException.h"
#include "JackError.h"
#include "JackTools.h"

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

SetRealTime();

// Process a null cycle until NetDriver has started
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
while (fThread.GetStatus() == JackThread::kRunning) {
fDriver->Process();
}

return false;

} catch (JackNetException& e) {

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

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

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

return false;
}
}

} // end of namespace

+ 3
- 3
common/JackWaitThreadedDriver.h View File

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

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

namespace Jack
{
@@ -31,7 +31,7 @@ namespace Jack
\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 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.
*/

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

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


+ 3
- 3
common/driver_interface.h View File

@@ -115,16 +115,16 @@ typedef struct {
}
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(
const char * name, /* driver name */
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.
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_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(). */


+ 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.
*/
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


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

@@ -28,25 +28,18 @@ extern "C"
#include <jack/systemdeps.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

enum JackNetMode {

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

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 {
@@ -57,9 +50,9 @@ typedef struct {
int midi_output; // to master or from slave (-1 for get master MIDI physical inputs)
int mtu; // network Maximum Transmission Unit
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
char mode; // one of JackNetMode
int latency; // network latency

} 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 midi_output number of MIDI outputs
* @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
*/
@@ -155,16 +148,16 @@ int jack_net_slave_deactivate(jack_net_slave_t* net);
/**
* Prototype for BufferSize callback.
* @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
*/
typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg);

/**
* Prototype for SampleRate callback
* Prototype for SampleRate callback.
* @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
*/
@@ -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);

/**
* 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);

@@ -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);

/**
* 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;

@@ -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);

/**
* Close the network connection with the master machine.
* Close the network connection with the slave machine.
* @param net the network connection to be closed
*
* @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);

/**
* Receive sync and data from the network
* Receive sync and data from the network.
* @param net the network connection
* @param audio_input number of audio inputs
* @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);

/**
* Send sync and data to the network
* Send sync and data to the network.
* @param net the network connection
* @param audio_output number of audio outputs
* @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

/**
* 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;

@@ -297,7 +288,7 @@ int jack_destroy_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 input an array of audio input 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);

/**
* Pull input to and push output from adapter ringbuffer
* Pull input to and push output from adapter ringbuffer.
* @param adapter the adapter
* @param input an array of audio input 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 += [
'JackAudioDriver.cpp',
'JackTimedDriver.cpp',
'JackMidiDriver.cpp',
'JackDriver.cpp',
'JackEngine.cpp',


+ 2
- 2
example-clients/alias.c View File

@@ -55,7 +55,7 @@ main (int argc, char *argv[])
int option_index;
extern int optind;
jack_port_t* port;
struct option long_options[] = {
{ "unalias", 0, 0, 'u' },
{ "help", 0, 0, 'h' },
@@ -129,5 +129,5 @@ main (int argc, char *argv[])
jack_client_close (client);

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

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;
}
else


+ 9
- 9
example-clients/capture_client.c View File

@@ -1,7 +1,7 @@
/*
Copyright (C) 2001 Paul Davis
Copyright (C) 2003 Jack O'Quin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -100,7 +100,7 @@ disk_thread (void *arg)
info->status = EIO; /* write failed */
goto done;
}
if (++total_captured >= info->duration) {
printf ("disk thread finished\n");
goto done;
@@ -116,7 +116,7 @@ disk_thread (void *arg)
free (framebuf);
return 0;
}
static int
process (jack_nframes_t nframes, void *arg)
{
@@ -168,10 +168,10 @@ setup_disk_thread (jack_thread_info_t *info)
{
SF_INFO sf_info;
int short_mask;
sf_info.samplerate = jack_get_sample_rate (info->client);
sf_info.channels = info->channels;
switch (info->bitdepth) {
case 8: short_mask = SF_FORMAT_PCM_U8;
break;
@@ -183,7 +183,7 @@ setup_disk_thread (jack_thread_info_t *info)
break;
default: short_mask = SF_FORMAT_PCM_16;
break;
}
}
sf_info.format = SF_FORMAT_WAV|short_mask;

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]);
jack_client_close (info->client);
exit (1);
}
}
}

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) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
exit (1);
}

@@ -333,7 +333,7 @@ main (int argc, char *argv[])
}

setup_ports (argc - optind, &argv[optind], &thread_info);
/* install a signal handler to properly quits jack client */
signal(SIGQUIT, 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 */

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;
}



+ 2
- 2
example-clients/freewheel.c View File

@@ -2,7 +2,7 @@
* freewheel - start/stop JACK "freewheeling" mode
*
* Copyright (C) 2003 Paul Davis.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -58,7 +58,7 @@ static void parse_arguments(int argc, char *argv[])
}
}

int
int
main (int argc, char *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;
int grab_finished = 0;
jack_client_t *client;
static void signal_handler(int sig)
{
jack_client_close(client);
@@ -60,7 +60,7 @@ process (jack_nframes_t nframes, void *arg)
}
if (response_pos >= response_duration) {
grab_finished = 1;
}
}
for (i=0; i<nframes; i++) {
out[i] = 0.0f;;
}
@@ -72,7 +72,7 @@ process (jack_nframes_t nframes, void *arg)
impulse_sent = 1;
}

return 0;
return 0;
}

static void
@@ -132,7 +132,7 @@ main (int argc, char *argv[])
/* try to become a client of the JACK server */

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;
}

@@ -149,7 +149,7 @@ main (int argc, char *argv[])

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
callback (see above) for this value.
*/
@@ -187,7 +187,7 @@ main (int argc, char *argv[])
}

free (ports);
if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) {
fprintf(stderr, "Cannot find any physical playback ports");
exit(1);
@@ -198,7 +198,7 @@ main (int argc, char *argv[])
}

free (ports);
/* install a signal handler to properly quits jack client */
signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler);


+ 3
- 3
example-clients/ipunload.c View File

@@ -85,9 +85,9 @@ main (int argc, char *argv[])
} else {
fprintf (stdout, "%s unloaded.\n", client_name);
}
jack_client_close(client);
return 0;
}

+ 2
- 1
example-clients/lsp.c View File

@@ -20,7 +20,7 @@
#include <unistd.h>
#endif
#include <string.h>
#include <getopt.h>
#include <getopt.h>
#include <inttypes.h>
#include <jack/jack.h>

@@ -246,3 +246,4 @@ error:
jack_client_close (client);
exit (0);
}


+ 22
- 10
example-clients/metro.c View File

@@ -1,6 +1,6 @@
/*
Copyright (C) 2002 Anthony Van Groningen
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
@@ -69,18 +69,21 @@ usage ()
}

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);
memset (buffer, 0, sizeof (jack_default_audio_sample_t) * nframes);
}

jack_nframes_t last_time;
jack_time_t last_micro_time;

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);
jack_nframes_t frames_left = nframes;
while (wave_length - offset < frames_left) {
memcpy (buffer + (nframes - frames_left), wave + offset, sizeof (sample_t) * (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);
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
@@ -141,7 +153,7 @@ main (int argc, char *argv[])
{"verbose", 0, 0, 'v'},
{0, 0, 0, 0}
};
while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
switch (opt) {
case 'f':
@@ -193,7 +205,7 @@ main (int argc, char *argv[])
transport_aware = 1;
break;
default:
fprintf (stderr, "unknown option %c\n", opt);
fprintf (stderr, "unknown option %c\n", opt);
case 'h':
usage ();
return -1;
@@ -211,7 +223,7 @@ main (int argc, char *argv[])
strcpy (client_name, "metro");
}
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;
}
jack_set_process_callback (client, process, 0);
@@ -259,7 +271,7 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot activate client\n");
goto error;
}
/* install a signal handler to properly quits jack client */
#ifdef WIN32
signal(SIGINT, signal_handler);
@@ -280,9 +292,9 @@ main (int argc, char *argv[])
sleep(1);
#endif
};
jack_client_close(client);
error:
free(amp);
free(wave);


+ 4
- 4
example-clients/midiseq.c View File

@@ -1,6 +1,6 @@
/*
Copyright (C) 2004 Ian Esten
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -93,7 +93,7 @@ int main(int narg, char **args)
}
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;
}
jack_set_process_callback (client, process, 0);
@@ -117,7 +117,7 @@ int main(int narg, char **args)
fprintf (stderr, "cannot activate client");
return 1;
}
/* install a signal handler to properly quits jack client */
signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler);
@@ -128,7 +128,7 @@ int main(int narg, char **args)
while (1) {
sleep(1);
};
jack_client_close(client);
exit (0);
}

+ 6
- 6
example-clients/midisine.c View File

@@ -1,6 +1,6 @@
/*
Copyright (C) 2004 Ian Esten
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -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.buffer) & 0xf0)) == 0x90)
{
{
/* note on */
note = *(in_event.buffer + 1);
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;
out[i] = note_on*sin(2*M_PI*ramp);
}
return 0;
return 0;
}

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)
{
fprintf(stderr, "jack server not running?\n");
fprintf(stderr, "JACK server not running?\n");
return 1;
}
calc_note_frqs(jack_get_sample_rate (client));

jack_set_process_callback (client, process, 0);
@@ -138,7 +138,7 @@ int main(int narg, char **args)
fprintf(stderr, "cannot activate client");
return 1;
}
/* install a signal handler to properly quits jack client */
signal(SIGQUIT, 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) {
fprintf (stderr, "jack server not running?\n");
fprintf (stderr, "JACK server not running?\n");
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");

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;
}



+ 23
- 23
example-clients/netslave.c View File

@@ -1,6 +1,6 @@
/*
Copyright (C) 2009 Grame
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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,
int audio_input,
float** audio_input_buffer,
int audio_input,
float** audio_input_buffer,
int midi_input,
void** midi_input_buffer,
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)
{
int i;
// Copy input to output
for (i = 0; i < audio_input; i++) {
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:";
int option_index;
int opt;
struct option long_options[] =
{
{"audio input", 1, 0, 'C'},
@@ -93,53 +93,53 @@ main (int argc, char *argv[])
{"port", 1, 0, 'p'},
{0, 0, 0, 0}
};
while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) {
switch (opt) {
case 'C':
audio_input = atoi(optarg);
break;
case 'P':
audio_output = atoi(optarg);
break;
case 'a':
multicast_ip = strdup(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'h':
usage();
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;
printf("Waiting for a master...\n");

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;
}

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_shutdown_callback(net, net_shutdown, NULL);

if (jack_net_slave_activate(net) != 0) {
fprintf(stderr, "Cannot sactivate client\n");
fprintf(stderr, "Cannot activate slave client\n");
return 1;
}
/* install a signal handler to properly quits jack client */
#ifdef WIN32
signal(SIGINT, signal_handler);
@@ -160,9 +160,9 @@ main (int argc, char *argv[])
sleep(1);
#endif
};
// Wait for application end
jack_net_slave_deactivate(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);
frame_time = jack_frame_time (client);
printf ("frame = %u frame_time = %u usecs = %lld \t", current.frame, frame_time, current.usecs);

switch (transport_state) {
@@ -81,7 +81,7 @@ main (int argc, char *argv[])
/* try to become a client of the JACK server */

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;
}

@@ -103,7 +103,7 @@ main (int argc, char *argv[])
fprintf (stderr, "cannot activate client");
return 1;
}
while (1) {
usleep (20);
showtime ();


+ 1
- 1
example-clients/zombie.c View File

@@ -54,7 +54,7 @@ main (int argc, char *argv[])
jack_client_t* client = NULL;
/* try to become a client of the JACK server */
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;
}



+ 1
- 1
linux/JackLinuxTime.c View File

@@ -143,7 +143,7 @@ static jack_time_t jack_get_mhz (void)
exit(1);
}

for ( ; ; )
for (;;)
{
jack_time_t mhz;
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 */; };
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 */; };
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 */; };
4B2209E212F6BBF400E5DC26 /* JackSocketServerChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B40E703B8D0066E42F /* JackSocketServerChannel.h */; };
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, ); }; };
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 */; };
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 */; };
4B80D7E90BA0D17400F035BB /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.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; };
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; };
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; };
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; };
@@ -3048,6 +3082,8 @@
4BF8D1B60834EEE400C94B91 /* JackDriver.cpp */,
4BC3988A08B3CF6C00B6F371 /* JackDummyDriver.h */,
4BC3988908B3CF6C00B6F371 /* JackDummyDriver.cpp */,
4B21794E13E2EEA60095B3E5 /* JackTimedDriver.h */,
4B21794D13E2EEA60095B3E5 /* JackTimedDriver.cpp */,
4BF3390D0F8B86AF0080FB5B /* MIDI */,
4B19B3010E23629800DD4A82 /* Adapter */,
BA222AEA0DC88379001A17F4 /* Net */,
@@ -3496,6 +3532,7 @@
4B97B6781344B50800794F57 /* JackMidiSendQueue.h in Headers */,
4B97B67A1344B51600794F57 /* JackMidiUtil.h in Headers */,
4B97B67C1344B52800794F57 /* JackMidiWriteQueue.h in Headers */,
4B21795213E2EEA60095B3E5 /* JackTimedDriver.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3968,6 +4005,7 @@
4B97B65B1344B45600794F57 /* JackMidiSendQueue.h in Headers */,
4B97B65D1344B46400794F57 /* JackMidiUtil.h in Headers */,
4B97B65F1344B47100794F57 /* JackMidiWriteQueue.h in Headers */,
4B21795013E2EEA60095B3E5 /* JackTimedDriver.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4172,6 +4210,20 @@
4BC2CA60113C6CD20076717C /* JackNetUnixSocket.h in Headers */,
4B5160AE13215EF900BB7DCB /* systemdeps.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;
};
@@ -6972,6 +7024,7 @@
4B97B6721344B4F000794F57 /* JackMidiSendQueue.cpp in Sources */,
4B97B6791344B50F00794F57 /* JackMidiUtil.cpp in Sources */,
4B97B67B1344B51D00794F57 /* JackMidiWriteQueue.cpp in Sources */,
4B21795113E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -7433,6 +7486,7 @@
4B97B65A1344B44F00794F57 /* JackMidiSendQueue.cpp in Sources */,
4B97B65C1344B45D00794F57 /* JackMidiUtil.cpp in Sources */,
4B97B65E1344B46B00794F57 /* JackMidiWriteQueue.cpp in Sources */,
4B21794F13E2EEA60095B3E5 /* JackTimedDriver.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -7642,6 +7696,20 @@
4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */,
4BC2CA5D113C6CC90076717C /* JackNetInterface.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;
};
@@ -16793,6 +16861,7 @@
);
OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\"";
OTHER_LDFLAGS = (
libcelt.a,
"-framework",
Carbon,
"-framework",
@@ -16865,6 +16934,7 @@
OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\"";
OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DLIB_DIR=\\\"lib\\\"";
OTHER_LDFLAGS = (
libcelt.a,
"-framework",
Carbon,
"-framework",


+ 23
- 15
macosx/coreaudio/JackCoreAudioAdapter.cpp View File

@@ -391,27 +391,35 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra
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)


+ 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 "JackLockedEngine.h"

#include <sstream>
#include <iostream>
#include <CoreServices/CoreServices.h>
#include <CoreFoundation/CFNumber.h>
@@ -137,15 +138,17 @@ static OSStatus DisplayDeviceNames()
CFStringRef UIname;

err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
return err;
}

deviceNum = size / sizeof(AudioDeviceID);
AudioDeviceID devices[deviceNum];

err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices);
if (err != noErr)
if (err != noErr) {
return err;
}

for (i = 0; i < deviceNum; i++) {
char device_name[256];
@@ -162,8 +165,9 @@ static OSStatus DisplayDeviceNames()

size = 256;
err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name);
if (err != noErr)
if (err != noErr) {
return err;
}

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;

error:
if (UIname != NULL)
if (UIname != NULL) {
CFRelease(UIname);
}
return err;
}

@@ -184,6 +189,20 @@ static CFStringRef GetDeviceName(AudioDeviceID id)
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,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
@@ -241,8 +260,9 @@ int JackCoreAudioDriver::Write()
int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize;
memcpy((jack_default_audio_sample_t*)fDriverOutputData->mBuffers[i].mData, buffer, size);
// Monitor ports
if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0)
if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) {
memcpy(GetMonitorBuffer(i), buffer, size);
}
} else {
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;
UInt32 outsize = sizeof(Float64);
OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sample_rate);
if (err != noErr)
if (err != noErr) {
return kAudioHardwareUnsupportedOperationError;
}

char device_name[256];
const char* digidesign_name = "Digidesign";
@@ -420,11 +441,13 @@ OSStatus JackCoreAudioDriver::GetDefaultDevice(AudioDeviceID* id)
AudioDeviceID inDefault;
AudioDeviceID outDefault;

if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) {
return res;
}

if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) {
return res;
}

jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault);

@@ -447,8 +470,9 @@ OSStatus JackCoreAudioDriver::GetDefaultInputDevice(AudioDeviceID* id)
UInt32 theSize = sizeof(UInt32);
AudioDeviceID inDefault;

if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) {
return res;
}

if (inDefault == 0) {
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);
AudioDeviceID outDefault;

if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr)
if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) {
return res;
}

if (outDefault == 0) {
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];
err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList);
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;
}
}
}
return err;
@@ -526,7 +552,7 @@ OSStatus JackCoreAudioDriver::DestroyAggregateDevice()
pluginAOPA.mElement = kAudioObjectPropertyElementMaster;
UInt32 outDataSize;

if (fPluginID > 0) {
if (fPluginID > 0) {

osErr = AudioObjectGetPropertyDataSize(fPluginID, &pluginAOPA, 0, NULL, &outDataSize);
if (osErr != noErr) {
@@ -771,8 +797,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
vector<CFStringRef> captureDeviceUID;
for (UInt32 i = 0; i < captureDeviceID.size(); i++) {
CFStringRef ref = GetDeviceName(captureDeviceID[i]);
if (ref == NULL)
if (ref == NULL) {
return -1;
}
captureDeviceUID.push_back(ref);
// input sub-devices in this example, so append the sub-device's UID to the CFArray
CFArrayAppendValue(subDevicesArray, ref);
@@ -781,8 +808,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
vector<CFStringRef> playbackDeviceUID;
for (UInt32 i = 0; i < playbackDeviceID.size(); i++) {
CFStringRef ref = GetDeviceName(playbackDeviceID[i]);
if (ref == NULL)
if (ref == NULL) {
return -1;
}
playbackDeviceUID.push_back(ref);
// output sub-devices in this example, so append the sub-device's UID to the CFArray
CFArrayAppendValue(subDevicesArray, ref);
@@ -908,8 +936,9 @@ OSStatus JackCoreAudioDriver::CreateAggregateDeviceAux(vector<AudioDeviceID> cap
CFRelease(aggDeviceDict);
CFRelease(subDevicesArray);

if (subDevicesArrayClock)
if (subDevicesArrayClock) {
CFRelease(subDevicesArrayClock);
}

// release the device UID
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;
}
}

// 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;
}
}
}

@@ -1081,14 +1112,16 @@ int JackCoreAudioDriver::SetupChannels(bool capturing, bool playing, int& inchan

if (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;
}
}

if (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;
}
}

if (inchannels == -1) {
@@ -1261,6 +1294,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
int outchannels,
int in_nChannels,
int out_nChannels,
const vector<int>& chan_in_list,
const vector<int>& chan_out_list,
jack_nframes_t buffer_size,
jack_nframes_t sample_rate)
{
@@ -1270,7 +1305,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing,
AudioDeviceID currAudioDeviceID;
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) {
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];
for (int i = 0; i < in_nChannels; i++) {
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);
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1");
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for input");
printError(err1);
goto error;
}
}

if (playing && outchannels > 0 && outchannels < out_nChannels) {
// Setup output channel map
if (playing && outchannels > 0 && outchannels <= out_nChannels) {
SInt32 chanArr[out_nChannels];
for (int i = 0; i < out_nChannels; i++) {
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);
if (err1 != noErr) {
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0");
jack_error("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap for output");
printError(err1);
goto error;
}
@@ -1588,6 +1659,8 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
bool playing,
int inchannels,
int outchannels,
const char* chan_in_list,
const char* chan_out_list,
bool monitor,
const char* capture_driver_uid,
const char* playback_driver_uid,
@@ -1618,6 +1691,21 @@ int JackCoreAudioDriver::Open(jack_nframes_t buffer_size,
Gestalt(gestaltSystemVersionMajor, &major);
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
if (major == 10 && minor >= 6) {
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;
}

// 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;
}

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;
}

if (SetupBufferSize(buffer_size) < 0)
if (SetupBufferSize(buffer_size) < 0) {
goto error;
}

if (SetupSampleRate(sample_rate) < 0)
if (SetupSampleRate(sample_rate) < 0) {
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;
}

if (capturing && inchannels > 0)
if (SetupBuffers(inchannels) < 0)
if (capturing && inchannels > 0) {
if (SetupBuffers(inchannels) < 0) {
goto error;
}
}

if (AddListeners() < 0)
if (AddListeners() < 0) {
goto error;
}

// Core driver may have changed the in/out values
fCaptureChannels = inchannels;
@@ -1692,11 +1796,13 @@ void JackCoreAudioDriver::UpdateLatencies()
UInt32 value1 = 0;
UInt32 value2 = 0;
err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error");
}
err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error");
}

range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency;
fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range);
@@ -1707,11 +1813,13 @@ void JackCoreAudioDriver::UpdateLatencies()
UInt32 value1 = 0;
UInt32 value2 = 0;
err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error");
}
err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error");
}

// Add more latency if "async" mode is used...
range.min = range.max
@@ -1742,12 +1850,14 @@ int JackCoreAudioDriver::Attach()
for (int i = 0; i < fCaptureChannels; i++) {

err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error");
}
if (err == noErr && size > 0) {
err = AudioDeviceGetProperty(fDeviceID, i + 1, true, kAudioDevicePropertyChannelName, &size, channel_name);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error");
}
snprintf(alias, sizeof(alias) - 1, "%s:%s:out_%s%u", fAliasName, fCaptureDriverName, channel_name, i + 1);
} else {
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++) {

err = AudioDeviceGetPropertyInfo(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, &isWritable);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetPropertyInfo kAudioDevicePropertyChannelName error");
}
if (err == noErr && size > 0) {
err = AudioDeviceGetProperty(fDeviceID, i + 1, false, kAudioDevicePropertyChannelName, &size, channel_name);
if (err != noErr)
if (err != noErr) {
jack_log("AudioDeviceGetProperty kAudioDevicePropertyChannelName error");
}
snprintf(alias, sizeof(alias) - 1, "%s:%s:in_%s%u", fAliasName, fPlaybackDriverName, channel_name, i + 1);
} else {
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)
{
if (SetupBufferSize(buffer_size) < 0)
if (SetupBufferSize(buffer_size) < 0) {
return -1;
}

JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails

@@ -1950,8 +2063,12 @@ extern "C"

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, "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;
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;
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);

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)
{
jack_nframes_t srate = 44100;
jack_nframes_t frames_per_interrupt = 128;
jack_nframes_t frames_per_interrupt = 256;
bool capture = false;
bool playback = false;
int chan_in = -1; // Default: if not explicitely set, then max possible will be used...
int chan_out = -1; // Default: if not explicitely set, then max possible will be used...
const char* chan_in_list = "";
const char* chan_out_list = "";
bool monitor = false;
const char* capture_driver_uid = "";
const char* playback_driver_uid = "";
@@ -2030,15 +2149,23 @@ extern "C"
break;

case 'c':
chan_in = chan_out = (int)param->value.ui;
chan_in = chan_out = param->value.i;
break;

case 'i':
chan_in = (int)param->value.ui;
chan_in = param->value.i;
break;

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;

case 'C':
@@ -2103,9 +2230,27 @@ extern "C"
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);
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;
} else {
delete driver;


+ 6
- 2
macosx/coreaudio/JackCoreAudioDriver.h View File

@@ -141,6 +141,8 @@ class JackCoreAudioDriver : public JackAudioDriver
int outchannels,
int in_nChannels,
int out_nChannels,
const vector<int>& chan_in_list,
const vector<int>& chan_out_list,
jack_nframes_t nframes,
jack_nframes_t samplerate);
void CloseAUHAL();
@@ -162,8 +164,10 @@ class JackCoreAudioDriver : public JackAudioDriver
jack_nframes_t samplerate,
bool capturing,
bool playing,
int chan_in,
int chan_out,
int inchannels,
int outchannels,
const char* chan_in_list,
const char* chan_out_list,
bool monitor,
const char* capture_driver_name,
const char* playback_driver_name,


+ 69
- 69
macosx/iphone/freeverb.mm View File

@@ -25,7 +25,7 @@
#include <pwd.h>
#include <sys/types.h>
#include <assert.h>
#include <pthread.h>
#include <pthread.h>
#include <sys/wait.h>
#include <libgen.h>
#include <jack/net.h>
@@ -52,7 +52,7 @@ using namespace std;
#define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
#endif
#else
#define AVOIDDENORMALS
#define AVOIDDENORMALS
#endif

//#define BENCHMARKMODE
@@ -61,7 +61,7 @@ struct Meta : map<const char*, const char*>
{
void declare (const char* key, const char* value) { (*this)[key]=value; }
};

#define max(x,y) (((x)>(y)) ? (x) : (y))
#define min(x,y) (((x)<(y)) ? (x) : (y))
@@ -91,37 +91,37 @@ class UI
{
bool fStopped;
public:
UI() : fStopped(false) {}
virtual ~UI() {}
// -- active widgets
virtual void addButton(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 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 addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
// -- passive widgets
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 addHorizontalBargraph(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
virtual void openFrameBox(const char* label) = 0;
virtual void openTabBox(const char* label) = 0;
virtual void openHorizontalBox(const char* label) = 0;
virtual void openVerticalBox(const char* label) = 0;
virtual void closeBox() = 0;
virtual void show() = 0;
virtual void run() = 0;
void stop() { fStopped = true; }
bool stopped() { return fStopped; }

@@ -132,24 +132,24 @@ struct param {
float* fZone; float fMin; float fMax;
param(float* z, float a, float b) : fZone(z), fMin(a), fMax(b) {}
};
class CMDUI : public UI
{
int fArgc;
char** fArgv;
stack<string> fPrefix;
map<string, param> fKeyParam;
void addOption(const char* label, float* zone, float min, float max)
{
string fullname = fPrefix.top() + label;
fKeyParam.insert(make_pair(fullname, param(zone, min, max)));
}
void openAnyBox(const char* label)
{
string prefix;
if (label && label[0]) {
prefix = fPrefix.top() + "-" + label;
} else {
@@ -157,21 +157,21 @@ class CMDUI : public UI
}
fPrefix.push(prefix);
}
public:
CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("--"); }
virtual ~CMDUI() {}
virtual void addButton(const char* label, float* zone) {};
virtual void addToggleButton(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)
{
addOption(label,zone,min,max);
}
virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
{
addOption(label,zone,min,max);
@@ -181,9 +181,9 @@ public:
{
addOption(label,zone,min,max);
}
// -- passive widgets
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 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 openHorizontalBox(const char* label) { openAnyBox(label); }
virtual void openVerticalBox(const char* label) { openAnyBox(label); }
virtual void closeBox() { fPrefix.pop(); }
virtual void show() {}
virtual void run()
virtual void run()
{
char c;
printf("Type 'q' to quit\n");
@@ -205,8 +205,8 @@ public:
sleep(1);
}
}
void print()
void print()
{
map<string, param>::iterator i;
cout << fArgc << "\n";
@@ -215,13 +215,13 @@ public:
cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] ";
}
}
void process_command()
{
map<string, param>::iterator p;
for (int i = 1; i < fArgc; i++) {
if (fArgv[i][0] == '-') {
p = fKeyParam.find(fArgv[i]);
p = fKeyParam.find(fArgv[i]);
if (p == fKeyParam.end()) {
cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
print();
@@ -233,13 +233,13 @@ public:
}
}
}
void process_init()
{
map<string, param>::iterator p;
for (int i = 1; i < fArgc; i++) {
if (fArgv[i][0] == '-') {
p = fKeyParam.find(fArgv[i]);
p = fKeyParam.find(fArgv[i]);
if (p == fKeyParam.end()) {
cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n";
exit(1);
@@ -256,14 +256,14 @@ public:
//----------------------------------------------------------------
// Signal processor definition
//----------------------------------------------------------------
class dsp {
protected:
int fSamplingFreq;
public:
dsp() {}
virtual ~dsp() {}
virtual int getNumInputs() = 0;
virtual int getNumOutputs() = 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 conclude() {}
};

//----------------------------------------------------------------------------
// FAUST generated code
//----------------------------------------------------------------------------

class mydsp : public dsp {
private:
@@ -349,7 +349,7 @@ class mydsp : public dsp {
float fVec23[256];
float fRec24[2];
public:
static void metadata(Meta* m) {
static void metadata(Meta* m) {
m->declare("name", "freeverb");
m->declare("version", "1.0");
m->declare("author", "Grame");
@@ -580,8 +580,8 @@ class mydsp : public dsp {
};


mydsp DSP;


@@ -601,7 +601,7 @@ int gNumInChans;
int gNumOutChans;

//----------------------------------------------------------------------------
// Jack Callbacks
// Jack Callbacks
//----------------------------------------------------------------------------

static void net_shutdown(void *)
@@ -633,7 +633,7 @@ void printstats()
low = hi = tot = (stops[KSKIP] - starts[KSKIP]);

if (mesure < KMESURE) {
for (int i = KSKIP+1; i<mesure; i++) {
unsigned long long int m = stops[i] - starts[i];
if (m<low) low = m;
@@ -643,7 +643,7 @@ void printstats()
cout << low << ' ' << tot/(mesure-KSKIP) << ' ' << hi << endl;

} else {
for (int i = KSKIP+1; i<KMESURE; i++) {
unsigned long long int m = stops[i] - starts[i];
if (m<low) low = m;
@@ -652,7 +652,7 @@ void printstats()
}
cout << low << ' ' << tot/(KMESURE-KSKIP) << ' ' << hi << endl;

}
}
}

#else
@@ -663,20 +663,20 @@ void printstats()
#endif

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,
void** midi_input_buffer,
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)
{
AVOIDDENORMALS;
STARTMESURE
DSP.compute(buffer_size, audio_input_buffer, audio_output_buffer);
STOPMESURE
STOPMESURE
return 0;
}

@@ -687,68 +687,68 @@ static int net_process(jack_nframes_t buffer_size,

*******************************************************************************
*******************************************************************************/
//-------------------------------------------------------------------------
// MAIN
//-------------------------------------------------------------------------


#define TEST_MASTER "194.5.49.5"
int main(int argc, char *argv[]) {
UI* interface = new CMDUI(argc, argv);
jack_net_slave_t* net;
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//Jack::JackAudioQueueAdapter audio(2, 2, 1024, 44100, NULL);
gNumInChans = DSP.getNumInputs();
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;
printf("Network\n");
//if (audio.Open() < 0) {
// fprintf(stderr, "Cannot open audio\n");
// return 1;
//}
//audio.Start();
// Hang around forever...
//while(1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false);
if ((net = jack_net_slave_open(TEST_MASTER, DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
fprintf(stderr, "jack remote server not running ?\n");
return 1;
}
jack_set_net_slave_process_callback(net, net_process, NULL);
// We want to restart (that is "wait for available master" again)
//jack_set_net_shutdown_callback(net, net_shutdown, 0);
DSP.init(result.sample_rate);
DSP.buildUserInterface(interface);
if (jack_net_slave_activate(net) != 0) {
fprintf(stderr, "cannot activate net");
return 1;
}
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
// Wait for application end
jack_net_slave_deactivate(net);
jack_net_slave_close(net);
//if (audio.Close() < 0) {
// fprintf(stderr, "Cannot close audio\n");
//}
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 = 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;

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)
{
int i;
int i;
// Copy from iPod input to network buffers
for (i = 0; i < result.audio_input; i++) {
memcpy(audio_input_buffer[i], inputs[i], buffer_size * sizeof(float));
}
/*
// Copy from network out buffers to network in buffers (audio thru)
for (i = 0; i < result.audio_input; i++) {
memcpy(audio_input_buffer[i], audio_output_buffer[i], buffer_size * sizeof(float));
}
*/
// Mix iPod input and network in buffers to network out buffers
//MixAudio(audio_input_buffer, inputs, audio_output_buffer, result.audio_input, buffer_size);
// Send network buffers
if (jack_net_master_send(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) {
printf("jack_net_master_send error..\n");
}
// Recv network buffers
if (jack_net_master_recv(net, result.audio_output, audio_output_buffer, 0, NULL) < 0) {
printf("jack_net_master_recv error..\n");
}
// Copy from network buffers to iPod output
for (i = 0; i < result.audio_output; i++) {
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[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int i;
if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) {
printf("jack_net_master_open error..\n");
return -1;
}
TiPhoneCoreAudioRenderer audio_device(result.audio_input, result.audio_output);
// Allocate buffers
if (result.audio_input > 0) {
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)));
}
}
if (result.audio_output > 0) {
audio_output_buffer = (float**)calloc(result.audio_output, sizeof(float*));
for (i = 0; i < result.audio_output; i++) {
audio_output_buffer[i] = (float*)(calloc(buffer_size, sizeof(float)));
}
}
if (audio_device.Open(buffer_size, sample_rate) < 0) {
return -1;
}
audio_device.SetAudioCallback(MasterAudioCallback, NULL);
if (audio_device.Start() < 0) {
return -1;
}
/*
// 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);
while (1) {
// Copy input to output
for (i = 0; i < result.audio_input; i++) {
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) {
printf("jack_net_master_send error..\n");
}
if (jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL) < 0) {
printf("jack_net_master_recv error..\n");
}
usleep(wait_usec);
};
*/
int retVal = UIApplicationMain(argc, argv, nil, nil);
audio_device.Stop();
audio_device.Close();
// Wait for application end
jack_net_master_close(net);
for (i = 0; i < result.audio_input; i++) {
free(audio_input_buffer[i]);
}
free(audio_input_buffer);
for (i = 0; i < result.audio_output; i++) {
free(audio_output_buffer[i]);
}
free(audio_output_buffer);
[pool release];
return retVal;
}

+ 26
- 25
macosx/iphone/main_slave.mm View File

@@ -21,18 +21,18 @@ int buffer_size;
int sample_rate;

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,
void** midi_input_buffer,
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)
{
jack_adapter_pull_and_push(adapter, audio_output_buffer, audio_input_buffer, buffer_size);
// Process input, produce output
if (audio_input == audio_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

int main(int argc, char *argv[]) {
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;

//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) {
printf("jack_net_slave_open error..\n");
printf("jack_net_slave_open error...\n");
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) {
return -1;
}
TiPhoneCoreAudioRenderer audio_device(NUM_INPUT, NUM_OUTPUT);
jack_set_net_slave_process_callback(net, net_process, NULL);
jack_set_net_slave_shutdown_callback(net, net_shutdown, NULL);
if (jack_net_slave_activate(net) != 0) {
printf("Cannot activate slave client\n");
return -1;
}
if (audio_device.Open(result.buffer_size, result.sample_rate) < 0) {
return -1;
}
audio_device.SetAudioCallback(SlaveAudioCallback, NULL);
if (audio_device.Start() < 0) {
return -1;
}
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
audio_device.Stop();
audio_device.Close();
// Wait for application end
jack_net_slave_deactivate(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_disconnect\fR [ \fI-s\fR | \fI--server servername\fR ] [\fI-h\fR | \fI--help\fR ] port1 port2
.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
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()
{
if (fSemaphore) {
jack_log("JackPosixSemaphore::Disconnect name = %s", fName);
jack_log("JackPosixSemaphore::Disconnect name = %s", fName);
if (sem_close(fSemaphore) != 0) {
jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno));
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));
return 0;
} else {
jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
return -1;
}
} else {
@@ -232,6 +233,7 @@ int JackClientSocket::Write(void* data, int len)
jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
return 0;
} else {
jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
return -1;
}
} 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
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) {
int status1 = *status;
if (status1 & JackVersionError)
if (status1 & JackVersionError) {
jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
else
} else {
jack_error("Client name = %s conflits with another running client", name);
}
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;
ServerSyncCall(&req, &res, result);
*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);

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* 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;
if (header.Read(socket) < 0) {
jack_log("HandleRequest: cannot read header");
ClientKill(fd); // TO CHECK SOLARIS
ClientKill(fd);
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);
if (res.Write(socket) < 0)
jack_error("JackRequest::ClientCheck write error name = %s", req.fName);
// Atomic ClientCheck followed by ClientOpen on same socket
if (req.fOpen)
HandleRequest(fd);
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?
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) {
@@ -67,10 +67,14 @@ int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* nam
}

// 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) {
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) {
@@ -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;
ServerSyncCall(&req, &res, result);
*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);

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* 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)
res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
res.Write(fPipe);
// Atomic ClientCheck followed by ClientOpen on same pipe
if (req.fOpen)
HandleRequest();
break;
}

@@ -477,11 +480,11 @@ int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* ser
void JackWinNamedPipeServerChannel::Close()
{
/* 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();


+ 1
- 0
windows/libjackserver.cbp View File

@@ -241,6 +241,7 @@
<Unit filename="..\common\JackActivationCount.cpp" />
<Unit filename="..\common\JackArgParser.cpp" />
<Unit filename="..\common\JackAudioDriver.cpp" />
<Unit filename="..\common\JackTimedDriver.cpp" />
<Unit filename="..\common\JackAudioPort.cpp" />
<Unit filename="..\common\JackClient.cpp" />
<Unit filename="..\common\JackConnectionManager.cpp" />


Loading…
Cancel
Save