summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Letz <letz@grame.fr>2011-07-30 10:51:18 +0200
committerStephane Letz <letz@grame.fr>2011-07-30 10:51:18 +0200
commit80d316ece46717f3634c5466e499b2d11fceb209 (patch)
tree8b7b0913274e3cd06202f186b9624b9e9e2092d4
parent4e979b964966b6596eb725916f9ff16932e85880 (diff)
parent7918f1c12abdd8d9328b829a87f9ae3a414344b5 (diff)
downloadjack2-80d316ece46717f3634c5466e499b2d11fceb209.tar.gz
Merge branch 'master' into js-dbus
-rw-r--r--ChangeLog20
-rw-r--r--common/JackAPI.cpp17
-rw-r--r--common/JackAudioAdapter.cpp11
-rw-r--r--common/JackAudioDriver.cpp27
-rw-r--r--common/JackAudioDriver.h3
-rw-r--r--common/JackChannel.h2
-rw-r--r--common/JackClient.cpp2
-rw-r--r--common/JackControlAPI.cpp78
-rw-r--r--common/JackControlAPI.h78
-rw-r--r--common/JackDebugClient.h2
-rw-r--r--common/JackDriver.cpp9
-rw-r--r--common/JackDriver.h36
-rw-r--r--common/JackDriverLoader.cpp53
-rw-r--r--common/JackDummyDriver.cpp78
-rw-r--r--common/JackDummyDriver.h35
-rw-r--r--common/JackEngine.cpp17
-rw-r--r--common/JackExternalClient.cpp8
-rw-r--r--common/JackExternalClient.h4
-rw-r--r--common/JackGlobals.h6
-rw-r--r--common/JackInternalClient.cpp13
-rw-r--r--common/JackInternalClientChannel.h2
-rw-r--r--common/JackLibAPI.cpp1
-rw-r--r--common/JackLibClient.cpp13
-rw-r--r--common/JackLibClient.h2
-rw-r--r--common/JackLibGlobals.h2
-rw-r--r--common/JackMidiAPI.cpp21
-rw-r--r--common/JackMidiDriver.cpp5
-rw-r--r--common/JackMidiDriver.h2
-rw-r--r--common/JackNetAPI.cpp195
-rw-r--r--common/JackNetAdapter.cpp28
-rw-r--r--common/JackNetDriver.cpp172
-rw-r--r--common/JackNetDriver.h19
-rw-r--r--common/JackNetInterface.cpp681
-rw-r--r--common/JackNetInterface.h134
-rw-r--r--common/JackNetManager.cpp522
-rw-r--r--common/JackNetManager.h30
-rw-r--r--common/JackNetOneDriver.cpp45
-rw-r--r--common/JackNetOneDriver.h24
-rw-r--r--common/JackNetTool.cpp612
-rw-r--r--common/JackNetTool.h586
-rw-r--r--common/JackPort.cpp1
-rw-r--r--common/JackRequest.h11
-rw-r--r--common/JackServer.cpp1
-rw-r--r--common/JackServerAPI.cpp21
-rw-r--r--common/JackShmMem.h21
-rw-r--r--common/JackThreadedDriver.cpp38
-rw-r--r--common/JackThreadedDriver.h15
-rw-r--r--common/JackTimedDriver.cpp86
-rw-r--r--common/JackTimedDriver.h66
-rw-r--r--common/JackTools.h14
-rw-r--r--common/JackWaitThreadedDriver.cpp37
-rw-r--r--common/JackWaitThreadedDriver.h6
-rw-r--r--common/driver_interface.h6
-rw-r--r--common/jack/jack.h1
-rw-r--r--common/jack/net.h53
-rw-r--r--common/wscript1
-rw-r--r--example-clients/alias.c4
-rw-r--r--example-clients/bufsize.c2
-rw-r--r--example-clients/capture_client.c18
-rw-r--r--example-clients/connect.c2
-rw-r--r--example-clients/freewheel.c4
-rw-r--r--example-clients/impulse_grabber.c14
-rw-r--r--example-clients/ipunload.c6
-rw-r--r--example-clients/lsp.c3
-rw-r--r--example-clients/metro.c32
-rw-r--r--example-clients/midiseq.c8
-rw-r--r--example-clients/midisine.c12
-rw-r--r--example-clients/monitor_client.c2
-rw-r--r--example-clients/netmaster.c2
-rw-r--r--example-clients/netslave.c46
-rw-r--r--example-clients/showtime.c6
-rw-r--r--example-clients/zombie.c2
-rw-r--r--linux/JackLinuxTime.c2
-rw-r--r--macosx/Jackdmp.xcodeproj/project.pbxproj70
-rw-r--r--macosx/coreaudio/JackCoreAudioAdapter.cpp38
-rw-r--r--macosx/coreaudio/JackCoreAudioDriver.cpp257
-rw-r--r--macosx/coreaudio/JackCoreAudioDriver.h8
-rw-r--r--macosx/iphone/freeverb.mm138
-rw-r--r--macosx/iphone/main_master.mm58
-rw-r--r--macosx/iphone/main_slave.mm51
-rw-r--r--man/jack_connect.02
-rw-r--r--posix/JackPosixSemaphore.cpp2
-rw-r--r--posix/JackSocket.cpp2
-rw-r--r--posix/JackSocketClientChannel.cpp11
-rw-r--r--posix/JackSocketClientChannel.h2
-rw-r--r--posix/JackSocketServerChannel.cpp5
-rw-r--r--windows/JackWinNamedPipeClientChannel.cpp22
-rw-r--r--windows/JackWinNamedPipeClientChannel.h2
-rw-r--r--windows/JackWinNamedPipeServerChannel.cpp11
-rw-r--r--windows/libjackserver.cbp1
90 files changed, 2358 insertions, 2460 deletions
diff --git a/ChangeLog b/ChangeLog
index 77a5edd3..8d004d02 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp
index b05704c4..2680396a 100644
--- a/common/JackAPI.cpp
+++ b/common/JackAPI.cpp
@@ -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__
diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp
index bf4e5f8c..f1a74fc8 100644
--- a/common/JackAudioAdapter.cpp
+++ b/common/JackAudioAdapter.cpp
@@ -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
diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp
index 8d65ebad..9d0cda32 100644
--- a/common/JackAudioDriver.cpp
+++ b/common/JackAudioDriver.cpp
@@ -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)
{
diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h
index bb9c1b9f..42ccb22d 100644
--- a/common/JackAudioDriver.h
+++ b/common/JackAudioDriver.h
@@ -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();
diff --git a/common/JackChannel.h b/common/JackChannel.h
index 69d25e00..5979ba8e 100644
--- a/common/JackChannel.h
+++ b/common/JackChannel.h
@@ -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)
{}
diff --git a/common/JackClient.cpp b/common/JackClient.cpp
index 121e7f91..639adfe8 100644
--- a/common/JackClient.cpp
+++ b/common/JackClient.cpp
@@ -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) {
diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp
index 2329ce80..6c359cde 100644
--- a/common/JackControlAPI.cpp
+++ b/common/JackControlAPI.cpp
@@ -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);
diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h
index b3462880..8011f9ba 100644
--- a/common/JackControlAPI.h
+++ b/common/JackControlAPI.h
@@ -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);
diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h
index 465d9465..f781b075 100644
--- a/common/JackDebugClient.h
+++ b/common/JackDebugClient.h
@@ -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:
diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp
index e424ce28..b81cdb48 100644
--- a/common/JackDriver.cpp
+++ b/common/JackDriver.cpp
@@ -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;
diff --git a/common/JackDriver.h b/common/JackDriver.h
index 45d695af..3bda602d 100644
--- a/common/JackDriver.h
+++ b/common/JackDriver.h
@@ -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();
diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp
index ec6053f6..5c5b3283 100644
--- a/common/JackDriverLoader.cpp
+++ b/common/JackDriverLoader.cpp
@@ -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,
diff --git a/common/JackDummyDriver.cpp b/common/JackDummyDriver.cpp
index 72d1b4d0..184499b8 100644
--- a/common/JackDummyDriver.cpp
+++ b/common/JackDummyDriver.cpp
@@ -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;
diff --git a/common/JackDummyDriver.h b/common/JackDummyDriver.h
index cfd6b474..284b026b 100644
--- a/common/JackDummyDriver.h
+++ b/common/JackDummyDriver.h
@@ -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
diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp
index ff991fde..e4342f81 100644
--- a/common/JackEngine.cpp
+++ b/common/JackEngine.cpp
@@ -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]);
}
diff --git a/common/JackExternalClient.cpp b/common/JackExternalClient.cpp
index 54342f97..5fd1b60f 100644
--- a/common/JackExternalClient.cpp
+++ b/common/JackExternalClient.cpp
@@ -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;
diff --git a/common/JackExternalClient.h b/common/JackExternalClient.h
index c7c7fc42..19318a33 100644
--- a/common/JackExternalClient.h
+++ b/common/JackExternalClient.h
@@ -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:
diff --git a/common/JackGlobals.h b/common/JackGlobals.h
index 75c9b030..36d73c38 100644
--- a/common/JackGlobals.h
+++ b/common/JackGlobals.h
@@ -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
diff --git a/common/JackInternalClient.cpp b/common/JackInternalClient.cpp
index 9645f9d3..12d0c671 100644
--- a/common/JackInternalClient.cpp
+++ b/common/JackInternalClient.cpp
@@ -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;
}
diff --git a/common/JackInternalClientChannel.h b/common/JackInternalClientChannel.h
index 650b0ccc..69588a99 100644
--- a/common/JackInternalClientChannel.h
+++ b/common/JackInternalClientChannel.h
@@ -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);
}
diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp
index 403ce5d2..e0d83e76 100644
--- a/common/JackLibAPI.cpp
+++ b/common/JackLibAPI.cpp
@@ -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, ...);
diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp
index 2b54aa16..4ba58c9c 100644
--- a/common/JackLibClient.cpp
+++ b/common/JackLibClient.cpp
@@ -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;
}
diff --git a/common/JackLibClient.h b/common/JackLibClient.h
index ef07581c..000c9aa6 100644
--- a/common/JackLibClient.h
+++ b/common/JackLibClient.h
@@ -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:
diff --git a/common/JackLibGlobals.h b/common/JackLibGlobals.h
index a2f87ed1..be36cb47 100644
--- a/common/JackLibGlobals.h
+++ b/common/JackLibGlobals.h
@@ -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
diff --git a/common/JackMidiAPI.cpp b/common/JackMidiAPI.cpp
index 4e574394..c462cece 100644
--- a/common/JackMidiAPI.cpp
+++ b/common/JackMidiAPI.cpp
@@ -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;
}
diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp
index 86001ae2..47866647 100644
--- a/common/JackMidiDriver.cpp
+++ b/common/JackMidiDriver.cpp
@@ -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();
diff --git a/common/JackMidiDriver.h b/common/JackMidiDriver.h
index b7584bbe..3e35ec08 100644
--- a/common/JackMidiDriver.h
+++ b/common/JackMidiDriver.h
@@ -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();
diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp
index 9be49aa0..4a7c40ee 100644
--- a/common/JackNetAPI.cpp
+++ b/common/JackNetAPI.cpp
@@ -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)
diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp
index 7642fd58..9be1bcf3 100644
--- a/common/JackNetAdapter.cpp
+++ b/common/JackNetAdapter.cpp
@@ -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;
}
}
diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp
index 2855fb17..da8327d2 100644
--- a/common/JackNetDriver.cpp
+++ b/common/JackNetDriver.cpp
@@ -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 {
diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h
index f73337c7..98f512ab 100644
--- a/common/JackNetDriver.h
+++ b/common/JackNetDriver.h
@@ -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();
diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp
index d8562a05..32e2ed2f 100644
--- a/common/JackNetInterface.cpp
+++ b/common/JackNetInterface.cpp
@@ -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
@@ -24,8 +23,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
using namespace std;
-#define PACKET_AVAILABLE_SIZE (fParams.fMtu - sizeof(packet_header_t))
-#define HEADER_SIZE (sizeof(packet_header_t))
/*
TODO : since midi buffers now uses up to BUFFER_SIZE_MAX frames,
@@ -94,62 +91,142 @@ namespace Jack
int JackNetInterface::SetNetBufferSize()
{
- //audio
+ // audio
float audio_size = (fNetAudioCaptureBuffer)
- ? fNetAudioCaptureBuffer->GetCycleSize()
- : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
+ ? fNetAudioCaptureBuffer->GetCycleSize()
+ : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleSize() : 0;
jack_log("audio_size %f", audio_size);
- //midi
+ // midi
float midi_size = (fNetMidiCaptureBuffer)
- ? fNetMidiCaptureBuffer->GetCycleSize()
- : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
+ ? fNetMidiCaptureBuffer->GetCycleSize()
+ : (fNetMidiPlaybackBuffer) ? fNetMidiPlaybackBuffer->GetCycleSize() : 0;
jack_log("midi_size %f", midi_size);
- //bufsize = sync + audio + midi
- int bufsize = MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int) midi_size);
+ // bufsize = sync + audio + midi
+ int bufsize = NETWORK_MAX_LATENCY * (fParams.fMtu + (int)audio_size + (int)midi_size);
jack_log("SetNetBufferSize bufsize = %d", bufsize);
- //tx buffer
- if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR)
+ // tx buffer
+ if (fSocket.SetOption(SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) {
return SOCKET_ERROR;
+ }
- //rx buffer
- if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR)
+ // rx buffer
+ if (fSocket.SetOption(SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) == SOCKET_ERROR) {
return SOCKET_ERROR;
+ }
return 0;
}
bool JackNetInterface::SetParams()
{
- //TX header init
+ // TX header init
strcpy(fTxHeader.fPacketType, "header");
fTxHeader.fID = fParams.fID;
fTxHeader.fCycle = 0;
fTxHeader.fSubCycle = 0;
fTxHeader.fIsLastPckt = 0;
- //RX header init
+ // RX header init
strcpy(fRxHeader.fPacketType, "header");
fRxHeader.fID = fParams.fID;
fRxHeader.fCycle = 0;
fRxHeader.fSubCycle = 0;
fRxHeader.fIsLastPckt = 0;
- //network buffers
+ // network buffers
fTxBuffer = new char[fParams.fMtu];
fRxBuffer = new char[fParams.fMtu];
assert(fTxBuffer);
assert(fRxBuffer);
- //net audio/midi buffers'addresses
+ // net audio/midi buffers'addresses
fTxData = fTxBuffer + HEADER_SIZE;
fRxData = fRxBuffer + HEADER_SIZE;
return true;
}
+ int JackNetInterface::MidiSend(NetMidiBuffer* buffer, int midi_channnels, int audio_channels)
+ {
+ if (midi_channnels > 0) {
+ // set global header fields and get the number of midi packets
+ fTxHeader.fDataType = 'm';
+ uint data_size = buffer->RenderFromJackPorts();
+ fTxHeader.fNumPacket = buffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE(&fParams));
+
+ for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
+ fTxHeader.fSubCycle = subproc;
+ fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && audio_channels == 0) ? 1 : 0;
+ fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, data_size);
+ memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
+ if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) {
+ return SOCKET_ERROR;
+ }
+ }
+ }
+ return 0;
+ }
+
+ int JackNetInterface::AudioSend(NetAudioBuffer* buffer, int audio_channels)
+ {
+ // audio
+ if (audio_channels > 0) {
+ fTxHeader.fDataType = 'a';
+ fTxHeader.fActivePorts = buffer->RenderFromJackPorts();
+ fTxHeader.fNumPacket = buffer->GetNumPackets(fTxHeader.fActivePorts);
+
+ for (uint subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
+ fTxHeader.fSubCycle = subproc;
+ fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
+ fTxHeader.fPacketSize = HEADER_SIZE + buffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
+ memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
+ // PacketHeaderDisplay(&fTxHeader);
+ if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR) {
+ return SOCKET_ERROR;
+ }
+ }
+ }
+ return 0;
+ }
+
+ int JackNetInterface::MidiRecv(packet_header_t* rx_head, NetMidiBuffer* buffer, uint& recvd_midi_pckt)
+ {
+ int rx_bytes = Recv(rx_head->fPacketSize, 0);
+ fRxHeader.fCycle = rx_head->fCycle;
+ fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
+ buffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
+ // Last midi packet is received, so finish rendering...
+ if (++recvd_midi_pckt == rx_head->fNumPacket) {
+ buffer->RenderToJackPorts();
+ }
+ return rx_bytes;
+ }
+
+ int JackNetInterface::AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer)
+ {
+ int rx_bytes = Recv(rx_head->fPacketSize, 0);
+ fRxHeader.fCycle = rx_head->fCycle;
+ fRxHeader.fSubCycle = rx_head->fSubCycle;
+ fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
+ fRxHeader.fActivePorts = rx_head->fActivePorts;
+ rx_bytes = buffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, fRxHeader.fActivePorts);
+ // Last audio packet is received, so finish rendering...
+ if (fRxHeader.fIsLastPckt) {
+ buffer->RenderToJackPorts();
+ }
+ return rx_bytes;
+ }
+
+ int JackNetInterface::FinishRecv(NetAudioBuffer* buffer)
+ {
+ // TODO : finish midi and audio rendering ?
+ buffer->RenderToJackPorts();
+ return NET_PACKET_ERROR;
+ }
+
// JackNetMasterInterface ************************************************************************************
bool JackNetMasterInterface::Init()
@@ -160,23 +237,23 @@ namespace Jack
uint attempt = 0;
int rx_bytes = 0;
- //socket
+ // socket
if (fSocket.NewSocket() == SOCKET_ERROR) {
jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
return false;
}
- //timeout on receive (for init)
+ // timeout on receive (for init)
if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0)
jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
- //connect
+ // connect
if (fSocket.Connect() == SOCKET_ERROR) {
jack_error("Can't connect : %s", StrError(NET_ERROR_CODE));
return false;
}
- //send 'SLAVE_SETUP' until 'START_MASTER' received
+ // send 'SLAVE_SETUP' until 'START_MASTER' received
jack_info("Sending parameters to %s...", fParams.fSlaveNetName);
do
{
@@ -185,12 +262,12 @@ namespace Jack
SetPacketType(&fParams, SLAVE_SETUP);
SessionParamsHToN(&fParams, &net_params);
- if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR)
+ if (fSocket.Send(&net_params, sizeof(session_params_t), 0) == SOCKET_ERROR) {
jack_error("Error in send : %s", StrError(NET_ERROR_CODE));
+ }
memset(&net_params, 0, sizeof(session_params_t));
- if (((rx_bytes = fSocket.Recv(&net_params, sizeof(session_params_t), 0)) == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA))
- {
+ if (((rx_bytes = fSocket.Recv(&net_params, sizeof(session_params_t), 0)) == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
jack_error("Problem with network");
return false;
}
@@ -206,28 +283,6 @@ namespace Jack
return true;
}
- /*
- int JackNetMasterInterface::SetRxTimeout()
- {
- jack_log("JackNetMasterInterface::SetRxTimeout");
-
- float time = 0;
-
- //slow or normal mode, short timeout on recv (2 audio subcycles)
- if ((fParams.fNetworkMode == 's') || (fParams.fNetworkMode == 'n')) {
- time = 2000000.f * ((fNetAudioCaptureBuffer)
- ? fNetAudioCaptureBuffer->GetCycleDuration()
- : (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->GetCycleDuration() : 0);
- }
- //fast mode, wait for 75% of the entire cycle duration
- else if (fParams.fNetworkMode == 'f') {
- time = 750000.f * (static_cast<float>(fParams.fPeriodSize) / static_cast<float>(fParams.fSampleRate));
- }
-
- return fSocket.SetTimeOut(static_cast<int>(time));
- }
- */
-
int JackNetMasterInterface::SetRxTimeout()
{
jack_log("JackNetMasterInterface::SetRxTimeout");
@@ -238,23 +293,28 @@ namespace Jack
bool JackNetMasterInterface::SetParams()
{
jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
- fParams.fSendAudioChannels, fParams.fReturnAudioChannels, fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
+ fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
+ fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
JackNetInterface::SetParams();
fTxHeader.fDataStream = 's';
fRxHeader.fDataStream = 'r';
- //midi net buffers
- if (fParams.fSendMidiChannels > 0)
+ fMaxCycleOffset = fParams.fNetworkLatency;
+
+ // midi net buffers
+ if (fParams.fSendMidiChannels > 0) {
fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fTxData);
+ }
- if (fParams.fReturnMidiChannels > 0)
+ if (fParams.fReturnMidiChannels > 0) {
fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fRxData);
+ }
try {
- //audio net buffers
+ // audio net buffers
if (fParams.fSendAudioChannels > 0) {
switch (fParams.fSampleEncoder) {
@@ -304,13 +364,15 @@ namespace Jack
return false;
}
- //set the new timeout for the socket
+ // set the new timeout for the socket
+ /*
if (SetRxTimeout() == SOCKET_ERROR) {
jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE));
goto error;
}
+ */
- //set the new rx buffer size
+ // set the new rx buffer size
if (SetNetBufferSize() == SOCKET_ERROR) {
jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
goto error;
@@ -327,10 +389,10 @@ namespace Jack
{
jack_log("JackNetMasterInterface::Exit, ID %u", fParams.fID);
- //stop process
+ // stop process
fRunning = false;
- //send a 'multicast euthanasia request' - new socket is required on macosx
+ // send a 'multicast euthanasia request' - new socket is required on macosx
jack_info("Exiting '%s'", fParams.fName);
SetPacketType(&fParams, KILL_MASTER);
JackNetSocket mcast_socket(fMulticastIP, fSocket.GetPort());
@@ -339,19 +401,31 @@ namespace Jack
memset(&net_params, 0, sizeof(session_params_t));
SessionParamsHToN(&fParams, &net_params);
- if (mcast_socket.NewSocket() == SOCKET_ERROR)
+ if (mcast_socket.NewSocket() == SOCKET_ERROR) {
jack_error("Can't create socket : %s", StrError(NET_ERROR_CODE));
- if (mcast_socket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR)
+ }
+ if (mcast_socket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR) {
jack_error("Can't send suicide request : %s", StrError(NET_ERROR_CODE));
+ }
mcast_socket.Close();
}
- void JackNetMasterInterface::FatalError()
+ void JackNetMasterInterface::FatalRecvError()
{
- //fatal connection issue, exit
- jack_error("'%s' : %s, exiting", fParams.fName, StrError(NET_ERROR_CODE));
- //ask to the manager to properly remove the master
+ // fatal connection issue, exit
+ jack_error("Recv connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName);
+ // ask to the manager to properly remove the master
+ Exit();
+ // UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
+ ThreadExit();
+ }
+
+ void JackNetMasterInterface::FatalSendError()
+ {
+ // fatal connection issue, exit
+ jack_error("Send connection lost error = %s, '%s' exiting", StrError(NET_ERROR_CODE), fParams.fName);
+ // ask to the manager to properly remove the master
Exit();
// UGLY temporary way to be sure the thread does not call code possibly causing a deadlock in JackEngine.
ThreadExit();
@@ -365,17 +439,17 @@ namespace Jack
/*
net_error_t error = fSocket.GetError();
- //no data isn't really a network error, so just return 0 available read bytes
+ // no data isn't really a network error, so just return 0 available read bytes
if (error == NET_NO_DATA) {
return 0;
} else if (error == NET_CONN_ERROR) {
- FatalError();
+ FatalRecvError();
} else {
jack_error("Error in master receive : %s", StrError(NET_ERROR_CODE));
}
*/
- FatalError();
+ FatalRecvError();
}
packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
@@ -393,23 +467,19 @@ namespace Jack
/*
net_error_t error = fSocket.GetError();
if (error == NET_CONN_ERROR) {
- FatalError();
+ FatalSendError();
} else {
jack_error("Error in master send : %s", StrError(NET_ERROR_CODE));
}
*/
- FatalError();
+ FatalSendError();
}
return tx_bytes;
}
bool JackNetMasterInterface::IsSynched()
{
- if (fParams.fNetworkMode == 's') {
- return (fCycleOffset < (CYCLE_OFFSET_SLOW + 1));
- } else {
- return true;
- }
+ return (fCurrentCycleOffset <= fMaxCycleOffset);
}
int JackNetMasterInterface::SyncSend()
@@ -420,60 +490,25 @@ namespace Jack
fTxHeader.fIsLastPckt = (fParams.fSendMidiChannels == 0 && fParams.fSendAudioChannels == 0) ? 1 : 0;
fTxHeader.fPacketSize = fParams.fMtu;
- // Write active ports list
- if (fNetAudioPlaybackBuffer)
- fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData, fTxHeader.fActivePorts);
-
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
- //PacketHeaderDisplay(&fTxHeader);
+ // PacketHeaderDisplay(&fTxHeader);
return Send(fTxHeader.fPacketSize, 0);
}
int JackNetMasterInterface::DataSend()
{
- uint subproc;
- uint data_size;
-
- //midi
- if (fParams.fSendMidiChannels > 0) {
- //set global header fields and get the number of midi packets
- fTxHeader.fDataType = 'm';
- data_size = fNetMidiCaptureBuffer->RenderFromJackPorts();
- fTxHeader.fNumPacket = fNetMidiCaptureBuffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE);
-
- for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
- fTxHeader.fSubCycle = subproc;
- fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && (fParams.fSendAudioChannels == 0)) ? 1 : 0;
- fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiCaptureBuffer->RenderToNetwork(subproc, data_size);
- memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
- if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
- return SOCKET_ERROR;
- }
- }
-
- //audio
- if (fParams.fSendAudioChannels > 0) {
- fTxHeader.fDataType = 'a';
- fNetAudioCaptureBuffer->RenderFromJackPorts();
- fTxHeader.fNumPacket = fNetAudioCaptureBuffer->GetNumPackets();
-
- for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
- fTxHeader.fSubCycle = subproc;
- fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
- fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioCaptureBuffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
- memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
- //PacketHeaderDisplay(&fTxHeader);
- if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
- return SOCKET_ERROR;
- }
+ if (MidiSend(fNetMidiCaptureBuffer, fParams.fSendMidiChannels, fParams.fSendAudioChannels) == SOCKET_ERROR) {
+ return SOCKET_ERROR;
}
-
- return 0;
+ return AudioSend(fNetAudioCaptureBuffer, fParams.fSendAudioChannels);
}
int JackNetMasterInterface::SyncRecv()
{
+ int rx_bytes = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
+
+ /*
int rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
if ((rx_bytes == 0) || (rx_bytes == SOCKET_ERROR)) {
@@ -481,68 +516,29 @@ namespace Jack
return SOCKET_ERROR;
}
- fCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
-
- // Read active ports list
- if (fNetAudioCaptureBuffer)
- fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
-
- switch (fParams.fNetworkMode)
- {
- case 's' :
- //slow mode : allow to use full bandwidth and heavy process on the slave
- // - extra latency is set to two cycles, one cycle for send/receive operations + one cycle for heavy process on the slave
- // - if the network is two fast, just wait the next cycle, this mode allows a shorter cycle duration for the master
- // - this mode will skip the two first cycles, thus it lets time for data to be processed and queued on the socket rx buffer
- //the slow mode is the safest mode because it wait twice the bandwidth relative time (send/return + process)
-
- if (fCycleOffset < CYCLE_OFFSET_SLOW) {
- return 0;
- } else {
- rx_bytes = Recv(rx_head->fPacketSize, 0);
- }
-
- /*
- rx_bytes = Recv(rx_head->fPacketSize, 0);
-
- if (fCycleOffset != fLastfCycleOffset)
- jack_info("Warning : '%s' runs in slow network mode, but data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
- fLastfCycleOffset = fCycleOffset;
- */
-
- break;
-
- case 'n' :
- //normal use of the network :
- // - extra latency is set to one cycle, what is the time needed to receive streams using full network bandwidth
- // - if the network is too fast, just wait the next cycle, the benefit here is the master's cycle is shorter
- // - indeed, data is supposed to be on the network rx buffer, so we don't have to wait for it
- if (fCycleOffset < CYCLE_OFFSET_NORMAL) {
- return 0;
- } else {
- rx_bytes = Recv(rx_head->fPacketSize, 0);
- }
+ fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
+ */
- if (fCycleOffset > CYCLE_OFFSET_NORMAL) {
- jack_info("'%s' can't run in normal network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
- }
- break;
+ // receive sync (launch the cycle)
+ do {
+ rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
+ // connection issue, send will detect it, so don't skip the cycle (return 0)
+ if (rx_bytes == SOCKET_ERROR) {
+ return SOCKET_ERROR;
+ }
+ }
+ while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
- case 'f' :
- //fast mode suppose the network bandwith is larger than required for the transmission (only a few channels for example)
- // - packets can be quickly received, quickly is here relative to the cycle duration
- // - here, receive data, we can't keep it queued on the rx buffer,
- // - but if there is a cycle offset, tell the user, that means we're not in fast mode anymore, network is too slow
- rx_bytes = Recv(rx_head->fPacketSize, 0);
+ fCurrentCycleOffset = fTxHeader.fCycle - rx_head->fCycle;
- if (fCycleOffset > CYCLE_OFFSET_FAST) {
- jack_info("'%s' can't run in fast network mode, data received too late (%d cycle(s) offset)", fParams.fName, fCycleOffset);
- }
- break;
+ if (fCurrentCycleOffset < fMaxCycleOffset) {
+ jack_info("Synching with latency = %d", fCurrentCycleOffset);
+ return 0;
+ } else {
+ rx_bytes = Recv(rx_head->fPacketSize, 0);
+ fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
+ return rx_bytes;
}
-
- fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
- return rx_bytes;
}
int JackNetMasterInterface::DataRecv()
@@ -551,47 +547,30 @@ namespace Jack
uint recvd_midi_pckt = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
- while (!fRxHeader.fIsLastPckt)
- {
- //how much data is queued on the rx buffer ?
+ while (!fRxHeader.fIsLastPckt) {
+ // how much data is queued on the rx buffer ?
rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
- //error here, problem with recv, just skip the cycle (return -1)
- if (rx_bytes == SOCKET_ERROR)
+ // error here, problem with recv, just skip the cycle (return -1)
+ if (rx_bytes == SOCKET_ERROR) {
return rx_bytes;
+ }
+
+ if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID)) {
+ // read data
+ switch (rx_head->fDataType) {
- if (rx_bytes && (rx_head->fDataStream == 'r') && (rx_head->fID == fParams.fID))
- {
- //read data
- switch (rx_head->fDataType)
- {
- case 'm': //midi
- rx_bytes = Recv(rx_head->fPacketSize, 0);
- fRxHeader.fCycle = rx_head->fCycle;
- fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
- fNetMidiPlaybackBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
- // Last midi packet is received, so finish rendering...
- if (++recvd_midi_pckt == rx_head->fNumPacket)
- fNetMidiPlaybackBuffer->RenderToJackPorts();
+ case 'm': // midi
+ rx_bytes = MidiRecv(rx_head, fNetMidiPlaybackBuffer, recvd_midi_pckt);
break;
- case 'a': //audio
- rx_bytes = Recv(rx_head->fPacketSize, 0);
- fRxHeader.fCycle = rx_head->fCycle;
- fRxHeader.fSubCycle = rx_head->fSubCycle;
- fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
- fRxHeader.fActivePorts = rx_head->fActivePorts;
- rx_bytes = fNetAudioPlaybackBuffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE, fRxHeader.fActivePorts);
- // Last audio packet is received, so finish rendering...
- if (fRxHeader.fIsLastPckt)
- fNetAudioPlaybackBuffer->RenderToJackPorts();
+ case 'a': // audio
+ rx_bytes = AudioRecv(rx_head, fNetAudioPlaybackBuffer);
break;
- case 's': //sync
+ case 's': // sync
jack_info("NetMaster : overloaded, skipping receive from '%s'", fParams.fName);
- // TODO : finish midi and audio rendering ?
- fNetAudioPlaybackBuffer->RenderToJackPorts();
- return NET_PACKET_ERROR;
+ return FinishRecv(fNetAudioPlaybackBuffer);
}
}
}
@@ -601,35 +580,46 @@ namespace Jack
void JackNetMasterInterface::EncodeSyncPacket()
{
- //this method contains every step of sync packet informations coding
- //first of all, reset sync packet
- memset(fTxData, 0, PACKET_AVAILABLE_SIZE);
+ // This method contains every step of sync packet informations coding
+ // first of all, clear sync packet
+ memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams));
- //then, first step : transport
+ // then, first step : transport
if (fParams.fTransportSync) {
- // desactivated...
- //EncodeTransportData();
- TransportDataHToN(&fSendTransportData, &fSendTransportData);
- //copy to TxBuffer
+ EncodeTransportData();
+ TransportDataHToN(&fSendTransportData, &fSendTransportData);
+ // copy to TxBuffer
memcpy(fTxData, &fSendTransportData, sizeof(net_transport_data_t));
}
- //then others (freewheel etc.)
- //...
+ // then others (freewheel etc.)
+ // ...
+
+ // Transport not used for now...
+
+ // Write active ports list
+ fTxHeader.fActivePorts = (fNetAudioPlaybackBuffer) ? fNetAudioPlaybackBuffer->ActivePortsToNetwork(fTxData) : 0;
}
void JackNetMasterInterface::DecodeSyncPacket()
{
- //this method contains every step of sync packet informations decoding process
- //first : transport
+ // This method contains every step of sync packet informations decoding process
+ // first : transport
if (fParams.fTransportSync) {
- //copy received transport data to transport data structure
+ // copy received transport data to transport data structure
memcpy(&fReturnTransportData, fRxData, sizeof(net_transport_data_t));
TransportDataNToH(&fReturnTransportData, &fReturnTransportData);
- // desactivated...
- //DecodeTransportData();
+ DecodeTransportData();
+ }
+ // then others
+ // ...
+
+ // Transport not used for now...
+ packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
+
+ // Read active ports list
+ if (fNetAudioCaptureBuffer) {
+ fNetAudioCaptureBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
}
- //then others
- //...
}
// JackNetSlaveInterface ************************************************************************************************
@@ -640,27 +630,29 @@ namespace Jack
{
jack_log("JackNetSlaveInterface::Init()");
- //set the parameters to send
+ // set the parameters to send
strcpy(fParams.fPacketType, "params");
fParams.fProtocolVersion = SLAVE_PROTOCOL;
SetPacketType(&fParams, SLAVE_AVAILABLE);
- //init loop : get a master and start, do it until connection is ok
+ // init loop : get a master and start, do it until connection is ok
net_status_t status;
do {
- //first, get a master, do it until a valid connection is running
+ // first, get a master, do it until a valid connection is running
do {
status = SendAvailableToMaster();
- if (status == NET_SOCKET_ERROR)
+ if (status == NET_SOCKET_ERROR) {
return false;
+ }
}
while (status != NET_CONNECTED);
- //then tell the master we are ready
+ // then tell the master we are ready
jack_info("Initializing connection with %s...", fParams.fMasterNetName);
status = SendStartToMaster();
- if (status == NET_ERROR)
+ if (status == NET_ERROR) {
return false;
+ }
}
while (status != NET_ROLLING);
@@ -668,22 +660,23 @@ namespace Jack
}
// Separate the connection protocol into two separated step
- bool JackNetSlaveInterface::InitConnection(int time_out)
+ bool JackNetSlaveInterface::InitConnection(int time_out_sec)
{
jack_log("JackNetSlaveInterface::InitConnection()");
- unsigned int try_count = (time_out > 0) ? ((1000000 * time_out) / SLAVE_INIT_TIMEOUT) : LONG_MAX;
+ uint try_count = (time_out_sec > 0) ? ((1000000 * time_out_sec) / SLAVE_INIT_TIMEOUT) : LONG_MAX;
- //set the parameters to send
+ // set the parameters to send
strcpy(fParams.fPacketType, "params");
fParams.fProtocolVersion = SLAVE_PROTOCOL;
SetPacketType(&fParams, SLAVE_AVAILABLE);
net_status_t status;
do {
- //get a master
+ // get a master
status = SendAvailableToMaster(try_count);
- if (status == NET_SOCKET_ERROR)
+ if (status == NET_SOCKET_ERROR) {
return false;
+ }
}
while (status != NET_CONNECTED && --try_count > 0);
@@ -696,7 +689,7 @@ namespace Jack
net_status_t status;
do {
- //then tell the master we are ready
+ // then tell the master we are ready
jack_info("Initializing connection with %s...", fParams.fMasterNetName);
status = SendStartToMaster();
if (status == NET_ERROR)
@@ -710,41 +703,41 @@ namespace Jack
net_status_t JackNetSlaveInterface::SendAvailableToMaster(long try_count)
{
jack_log("JackNetSlaveInterface::SendAvailableToMaster()");
- //utility
+ // utility
session_params_t host_params;
int rx_bytes = 0;
- //socket
+ // socket
if (fSocket.NewSocket() == SOCKET_ERROR) {
jack_error("Fatal error : network unreachable - %s", StrError(NET_ERROR_CODE));
return NET_SOCKET_ERROR;
}
- //bind the socket
+ // bind the socket
if (fSocket.Bind() == SOCKET_ERROR) {
jack_error("Can't bind the socket : %s", StrError(NET_ERROR_CODE));
return NET_SOCKET_ERROR;
}
- //timeout on receive
+ // timeout on receive
if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR)
jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
- //disable local loop
+ // disable local loop
if (fSocket.SetLocalLoop() == SOCKET_ERROR)
jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE));
- //send 'AVAILABLE' until 'SLAVE_SETUP' received
+ // send 'AVAILABLE' until 'SLAVE_SETUP' received
jack_info("Waiting for a master...");
do {
- //send 'available'
+ // send 'available'
session_params_t net_params;
memset(&net_params, 0, sizeof(session_params_t));
SessionParamsHToN(&fParams, &net_params);
if (fSocket.SendTo(&net_params, sizeof(session_params_t), 0, fMulticastIP) == SOCKET_ERROR)
jack_error("Error in data send : %s", StrError(NET_ERROR_CODE));
- //filter incoming packets : don't exit while no error is detected
+ // filter incoming packets : don't exit while no error is detected
memset(&net_params, 0, sizeof(session_params_t));
rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
SessionParamsNToH(&net_params, &host_params);
@@ -761,10 +754,10 @@ namespace Jack
return NET_CONNECT_ERROR;
}
- //everything is OK, copy parameters
+ // everything is OK, copy parameters
fParams = host_params;
- //connect the socket
+ // connect the socket
if (fSocket.Connect() == SOCKET_ERROR) {
jack_error("Error in connect : %s", StrError(NET_ERROR_CODE));
return NET_CONNECT_ERROR;
@@ -776,7 +769,7 @@ namespace Jack
{
jack_log("JackNetSlaveInterface::SendStartToMaster");
- //tell the master to start
+ // tell the master to start
session_params_t net_params;
memset(&net_params, 0, sizeof(session_params_t));
SetPacketType(&fParams, START_MASTER);
@@ -791,23 +784,26 @@ namespace Jack
bool JackNetSlaveInterface::SetParams()
{
jack_log("JackNetSlaveInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d",
- fParams.fSendAudioChannels, fParams.fReturnAudioChannels, fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
+ fParams.fSendAudioChannels, fParams.fReturnAudioChannels,
+ fParams.fSendMidiChannels, fParams.fReturnMidiChannels);
JackNetInterface::SetParams();
fTxHeader.fDataStream = 'r';
fRxHeader.fDataStream = 's';
- //midi net buffers
- if (fParams.fSendMidiChannels > 0)
+ // midi net buffers
+ if (fParams.fSendMidiChannels > 0) {
fNetMidiCaptureBuffer = new NetMidiBuffer(&fParams, fParams.fSendMidiChannels, fRxData);
+ }
- if (fParams.fReturnMidiChannels > 0)
+ if (fParams.fReturnMidiChannels > 0) {
fNetMidiPlaybackBuffer = new NetMidiBuffer(&fParams, fParams.fReturnMidiChannels, fTxData);
+ }
try {
- //audio net buffers
+ // audio net buffers
if (fParams.fSendAudioChannels > 0) {
switch (fParams.fSampleEncoder) {
@@ -857,7 +853,7 @@ namespace Jack
return false;
}
- //set the new buffer sizes
+ // set the new buffer sizes
if (SetNetBufferSize() == SOCKET_ERROR) {
jack_error("Can't set net buffer sizes : %s", StrError(NET_ERROR_CODE));
goto error;
@@ -870,24 +866,36 @@ namespace Jack
return false;
}
+ void JackNetSlaveInterface::FatalRecvError()
+ {
+ jack_error("Recv connection lost error = %s", StrError(NET_ERROR_CODE));
+ throw JackNetException();
+ }
+
+ void JackNetSlaveInterface::FatalSendError()
+ {
+ jack_error("Send connection lost error = %s", StrError(NET_ERROR_CODE));
+ throw JackNetException();
+ }
+
int JackNetSlaveInterface::Recv(size_t size, int flags)
{
int rx_bytes = fSocket.Recv(fRxBuffer, size, flags);
- //handle errors
+ // handle errors
if (rx_bytes == SOCKET_ERROR) {
/*
net_error_t error = fSocket.GetError();
- //no data isn't really an error in realtime processing, so just return 0
+ // no data isn't really an error in realtime processing, so just return 0
if (error == NET_NO_DATA) {
jack_error("No data, is the master still running ?");
- //if a network error occurs, this exception will restart the driver
+ // if a network error occurs, this exception will restart the driver
} else if (error == NET_CONN_ERROR) {
- FatalError();
+ FatalRecvError();
} else {
jack_error("Fatal error in slave receive : %s", StrError(NET_ERROR_CODE));
}
*/
- FatalError();
+ FatalRecvError();
}
packet_header_t* header = reinterpret_cast<packet_header_t*>(fRxBuffer);
@@ -895,30 +903,24 @@ namespace Jack
return rx_bytes;
}
- void JackNetSlaveInterface::FatalError()
- {
- jack_error("Send connection lost");
- throw JackNetException();
- }
-
int JackNetSlaveInterface::Send(size_t size, int flags)
{
packet_header_t* header = reinterpret_cast<packet_header_t*>(fTxBuffer);
PacketHeaderHToN(header, header);
int tx_bytes = fSocket.Send(fTxBuffer, size, flags);
- //handle errors
+ // handle errors
if (tx_bytes == SOCKET_ERROR) {
/*
net_error_t error = fSocket.GetError();
- //if a network error occurs, this exception will restart the driver
+ // if a network error occurs, this exception will restart the driver
if (error == NET_CONN_ERROR) {
- FatalError();
+ FatalSendError();
} else {
jack_error("Fatal error in slave send : %s", StrError(NET_ERROR_CODE));
}
*/
- FatalError();
+ FatalSendError();
}
return tx_bytes;
}
@@ -928,19 +930,16 @@ namespace Jack
int rx_bytes = 0;
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
- //receive sync (launch the cycle)
+ // receive sync (launch the cycle)
do {
rx_bytes = Recv(fParams.fMtu, 0);
- //connection issue, send will detect it, so don't skip the cycle (return 0)
- if (rx_bytes == SOCKET_ERROR)
+ // connection issue, send will detect it, so don't skip the cycle (return 0)
+ if (rx_bytes == SOCKET_ERROR) {
return rx_bytes;
+ }
}
while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's'));
- // Read active ports list
- if (fNetAudioPlaybackBuffer)
- fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
-
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
return rx_bytes;
}
@@ -952,43 +951,29 @@ namespace Jack
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
while (!fRxHeader.fIsLastPckt) {
- //how much data is queued on the rx buffer ?
+ // how much data is queued on the rx buffer ?
rx_bytes = Recv(fParams.fMtu, MSG_PEEK);
- //error here, problem with recv, just skip the cycle (return -1)
- if (rx_bytes == SOCKET_ERROR)
+ // error here, problem with recv, just skip the cycle (return -1)
+ if (rx_bytes == SOCKET_ERROR) {
return rx_bytes;
+ }
if (rx_bytes && (rx_head->fDataStream == 's') && (rx_head->fID == fParams.fID)) {
- switch (rx_head->fDataType)
- {
- case 'm': //midi
- rx_bytes = Recv(rx_head->fPacketSize, 0);
- fRxHeader.fCycle = rx_head->fCycle;
- fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
- fNetMidiCaptureBuffer->RenderFromNetwork(rx_head->fSubCycle, rx_bytes - HEADER_SIZE);
- // Last midi packet is received, so finish rendering...
- if (++recvd_midi_pckt == rx_head->fNumPacket)
- fNetMidiCaptureBuffer->RenderToJackPorts();
+ // read data
+ switch (rx_head->fDataType) {
+
+ case 'm': // midi
+ rx_bytes = MidiRecv(rx_head, fNetMidiCaptureBuffer, recvd_midi_pckt);
break;
- case 'a': //audio
- rx_bytes = Recv(rx_head->fPacketSize, 0);
- fRxHeader.fCycle = rx_head->fCycle;
- fRxHeader.fSubCycle = rx_head->fSubCycle;
- fRxHeader.fIsLastPckt = rx_head->fIsLastPckt;
- fRxHeader.fActivePorts = rx_head->fActivePorts;
- rx_bytes = fNetAudioCaptureBuffer->RenderFromNetwork(rx_head->fCycle, rx_head->fSubCycle, rx_bytes - HEADER_SIZE, fRxHeader.fActivePorts);
- // Last audio packet is received, so finish rendering...
- if (fRxHeader.fIsLastPckt)
- fNetAudioCaptureBuffer->RenderToJackPorts();
+ case 'a': // audio
+ rx_bytes = AudioRecv(rx_head, fNetAudioCaptureBuffer);
break;
- case 's': //sync
+ case 's': // sync
jack_info("NetSlave : overloaded, skipping receive");
- // TODO : finish midi and audio rendering ?
- fNetAudioCaptureBuffer->RenderToJackPorts();
- return NET_PACKET_ERROR;
+ return FinishRecv(fNetAudioCaptureBuffer);
}
}
}
@@ -999,7 +984,7 @@ namespace Jack
int JackNetSlaveInterface::SyncSend()
{
- //tx header
+ // tx header
if (fParams.fSlaveSyncMode) {
fTxHeader.fCycle = fRxHeader.fCycle;
} else {
@@ -1010,86 +995,62 @@ namespace Jack
fTxHeader.fIsLastPckt = (fParams.fReturnMidiChannels == 0 && fParams.fReturnAudioChannels == 0) ? 1 : 0;
fTxHeader.fPacketSize = fParams.fMtu;
- // Write active ports list
- if (fNetAudioCaptureBuffer)
- fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData, fTxHeader.fActivePorts);
-
memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
+ // PacketHeaderDisplay(&fTxHeader);
return Send(fTxHeader.fPacketSize, 0);
}
int JackNetSlaveInterface::DataSend()
{
- uint subproc, data_size;
-
- //midi
- if (fParams.fReturnMidiChannels > 0) {
- //set global header fields and get the number of midi packets
- fTxHeader.fDataType = 'm';
- data_size = fNetMidiPlaybackBuffer->RenderFromJackPorts();
- fTxHeader.fNumPacket = fNetMidiPlaybackBuffer->GetNumPackets(data_size, PACKET_AVAILABLE_SIZE);
-
- for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
- fTxHeader.fSubCycle = subproc;
- fTxHeader.fIsLastPckt = ((subproc == (fTxHeader.fNumPacket - 1)) && !fParams.fReturnAudioChannels) ? 1 : 0;
- fTxHeader.fPacketSize = HEADER_SIZE + fNetMidiPlaybackBuffer->RenderToNetwork(subproc, data_size);
- memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
- if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
- return SOCKET_ERROR;
- }
- }
-
- //audio
- if (fParams.fReturnAudioChannels > 0) {
-
- fTxHeader.fDataType = 'a';
- fNetAudioPlaybackBuffer->RenderFromJackPorts();
- fTxHeader.fNumPacket = fNetAudioPlaybackBuffer->GetNumPackets();
-
- for (subproc = 0; subproc < fTxHeader.fNumPacket; subproc++) {
- fTxHeader.fSubCycle = subproc;
- fTxHeader.fIsLastPckt = (subproc == (fTxHeader.fNumPacket - 1)) ? 1 : 0;
- fTxHeader.fPacketSize = HEADER_SIZE + fNetAudioPlaybackBuffer->RenderToNetwork(subproc, fTxHeader.fActivePorts);
- memcpy(fTxBuffer, &fTxHeader, HEADER_SIZE);
- //PacketHeaderDisplay(&fTxHeader);
- if (Send(fTxHeader.fPacketSize, 0) == SOCKET_ERROR)
- return SOCKET_ERROR;
- }
+ if (MidiSend(fNetMidiPlaybackBuffer, fParams.fReturnMidiChannels, fParams.fReturnAudioChannels) == SOCKET_ERROR) {
+ return SOCKET_ERROR;
}
- return 0;
+ return AudioSend(fNetAudioPlaybackBuffer, fParams.fReturnAudioChannels);
}
- //network sync------------------------------------------------------------------------
+ // network sync------------------------------------------------------------------------
void JackNetSlaveInterface::EncodeSyncPacket()
{
- //this method contains every step of sync packet informations coding
- //first of all, reset sync packet
- memset(fTxData, 0, PACKET_AVAILABLE_SIZE);
- //then first step : transport
+ // This method contains every step of sync packet informations coding
+ // first of all, clear sync packet
+ memset(fTxData, 0, PACKET_AVAILABLE_SIZE(&fParams));
+
+ // then first step : transport
if (fParams.fTransportSync) {
- // desactivated...
- //EncodeTransportData();
- TransportDataHToN(&fReturnTransportData, &fReturnTransportData);
- //copy to TxBuffer
+ EncodeTransportData();
+ TransportDataHToN(&fReturnTransportData, &fReturnTransportData);
+ // copy to TxBuffer
memcpy(fTxData, &fReturnTransportData, sizeof(net_transport_data_t));
}
- //then others
- //...
+ // then others
+ // ...
+
+ // Transport is not used for now...
+
+ // Write active ports list
+ fTxHeader.fActivePorts = (fNetAudioCaptureBuffer) ? fNetAudioCaptureBuffer->ActivePortsToNetwork(fTxData) : 0;
}
void JackNetSlaveInterface::DecodeSyncPacket()
{
- //this method contains every step of sync packet informations decoding process
- //first : transport
+ // This method contains every step of sync packet informations decoding process
+ // first : transport
if (fParams.fTransportSync) {
- //copy received transport data to transport data structure
+ // copy received transport data to transport data structure
memcpy(&fSendTransportData, fRxData, sizeof(net_transport_data_t));
- TransportDataNToH(&fSendTransportData, &fSendTransportData);
- // desactivated...
- //DecodeTransportData();
+ TransportDataNToH(&fSendTransportData, &fSendTransportData);
+ DecodeTransportData();
+ }
+ // then others
+ // ...
+
+ // Transport not used for now...
+ packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer);
+
+ // Read active ports list
+ if (fNetAudioPlaybackBuffer) {
+ fNetAudioPlaybackBuffer->ActivePortsFromNetwork(fRxData, rx_head->fActivePorts);
}
- //then others
- //...
}
}
diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h
index 082292a2..45a42cb9 100644
--- a/common/JackNetInterface.h
+++ b/common/JackNetInterface.h
@@ -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
diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp
index a0c14de3..4a813b9b 100644
--- a/common/JackNetManager.cpp
+++ b/common/JackNetManager.cpp
@@ -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
diff --git a/common/JackNetManager.h b/common/JackNetManager.h
index 48b6c25c..bc1e790a 100644
--- a/common/JackNetManager.h
+++ b/common/JackNetManager.h
@@ -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();
};
}
diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp
index a7bec4c6..7dd4e69d 100644
--- a/common/JackNetOneDriver.cpp
+++ b/common/JackNetOneDriver.cpp
@@ -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,
diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h
index f0dfc165..ae5fd078 100644
--- a/common/JackNetOneDriver.h
+++ b/common/JackNetOneDriver.h
@@ -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;
}
diff --git a/common/JackNetTool.cpp b/common/JackNetTool.cpp
index 791af963..f5997e3b 100644
--- a/common/JackNetTool.cpp
+++ b/common/JackNetTool.cpp
@@ -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;
diff --git a/common/JackNetTool.h b/common/JackNetTool.h
index 375aa376..315ab66b 100644
--- a/common/JackNetTool.h
+++ b/common/JackNetTool.h
@@ -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
diff --git a/common/JackPort.cpp b/common/JackPort.cpp
index 8e3be740..9bc53d83 100644
--- a/common/JackPort.cpp
+++ b/common/JackPort.cpp
@@ -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;
diff --git a/common/JackRequest.h b/common/JackRequest.h
index f5e86543..07ec219c 100644
--- a/common/JackRequest.h
+++ b/common/JackRequest.h
@@ -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));
}
};
diff --git a/common/JackServer.cpp b/common/JackServer.cpp
index 22027c9c..0c270165 100644
--- a/common/JackServer.cpp
+++ b/common/JackServer.cpp
@@ -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"
diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp
index e5a0b057..3f637445 100644
--- a/common/JackServerAPI.cpp
+++ b/common/JackServerAPI.cpp
@@ -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)
diff --git a/common/JackShmMem.h b/common/JackShmMem.h
index 619e81f6..13d1c43a 100644
--- a/common/JackShmMem.h
+++ b/common/JackShmMem.h
@@ -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();
}
diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp
index 29fab30f..9500dadb 100644
--- a/common/JackThreadedDriver.cpp
+++ b/common/JackThreadedDriver.cpp
@@ -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
diff --git a/common/JackThreadedDriver.h b/common/JackThreadedDriver.h
index 83d09faf..12d77471 100644
--- a/common/JackThreadedDriver.h
+++ b/common/JackThreadedDriver.h
@@ -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
diff --git a/common/JackTimedDriver.cpp b/common/JackTimedDriver.cpp
new file mode 100644
index 00000000..68b98b6f
--- /dev/null
+++ b/common/JackTimedDriver.cpp
@@ -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
diff --git a/common/JackTimedDriver.h b/common/JackTimedDriver.h
new file mode 100644
index 00000000..987bfab4
--- /dev/null
+++ b/common/JackTimedDriver.h
@@ -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
diff --git a/common/JackTools.h b/common/JackTools.h
index 50451e04..4b312563 100644
--- a/common/JackTools.h
+++ b/common/JackTools.h
@@ -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;
+ }
+ }
};
/*!
diff --git a/common/JackWaitThreadedDriver.cpp b/common/JackWaitThreadedDriver.cpp
index 76637440..dd52a9d9 100644
--- a/common/JackWaitThreadedDriver.cpp
+++ b/common/JackWaitThreadedDriver.cpp
@@ -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
diff --git a/common/JackWaitThreadedDriver.h b/common/JackWaitThreadedDriver.h
index 83a8e351..f98a4e4a 100644
--- a/common/JackWaitThreadedDriver.h
+++ b/common/JackWaitThreadedDriver.h
@@ -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()
{}
diff --git a/common/driver_interface.h b/common/driver_interface.h
index fad24137..4645c2f0 100644
--- a/common/driver_interface.h
+++ b/common/driver_interface.h
@@ -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(). */
diff --git a/common/jack/jack.h b/common/jack/jack.h
index 3177a795..03d601b0 100644
--- a/common/jack/jack.h
+++ b/common/jack/jack.h
@@ -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
diff --git a/common/jack/net.h b/common/jack/net.h
index 001868be..4c9a389b 100644
--- a/common/jack/net.h
+++ b/common/jack/net.h
@@ -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
diff --git a/common/wscript b/common/wscript
index 96e48b08..9a63c15a 100644
--- a/common/wscript
+++ b/common/wscript
@@ -114,6 +114,7 @@ def build(bld):
serverlib.source = [] + common_libsources
serverlib.source += [
'JackAudioDriver.cpp',
+ 'JackTimedDriver.cpp',
'JackMidiDriver.cpp',
'JackDriver.cpp',
'JackEngine.cpp',
diff --git a/example-clients/alias.c b/example-clients/alias.c
index 87a19b88..cb2b3f99 100644
--- a/example-clients/alias.c
+++ b/example-clients/alias.c
@@ -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;
-
+
}
diff --git a/example-clients/bufsize.c b/example-clients/bufsize.c
index c6407c20..771fd5a8 100644
--- a/example-clients/bufsize.c
+++ b/example-clients/bufsize.c
@@ -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
diff --git a/example-clients/capture_client.c b/example-clients/capture_client.c
index 72a2467f..08585051 100644
--- a/example-clients/capture_client.c
+++ b/example-clients/capture_client.c
@@ -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);
diff --git a/example-clients/connect.c b/example-clients/connect.c
index 3c6de6b9..5ed112b0 100644
--- a/example-clients/connect.c
+++ b/example-clients/connect.c
@@ -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;
}
diff --git a/example-clients/freewheel.c b/example-clients/freewheel.c
index c0892833..a59a8cec 100644
--- a/example-clients/freewheel.c
+++ b/example-clients/freewheel.c
@@ -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);
diff --git a/example-clients/impulse_grabber.c b/example-clients/impulse_grabber.c
index 0a1fd706..80006c0b 100644
--- a/example-clients/impulse_grabber.c
+++ b/example-clients/impulse_grabber.c
@@ -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);
diff --git a/example-clients/ipunload.c b/example-clients/ipunload.c
index baedfc1e..2ce3d0c8 100644
--- a/example-clients/ipunload.c
+++ b/example-clients/ipunload.c
@@ -85,9 +85,9 @@ main (int argc, char *argv[])
} else {
fprintf (stdout, "%s unloaded.\n", client_name);
}
-
+
jack_client_close(client);
return 0;
}
-
-
+
+
diff --git a/example-clients/lsp.c b/example-clients/lsp.c
index ee18f5ba..81700cdc 100644
--- a/example-clients/lsp.c
+++ b/example-clients/lsp.c
@@ -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);
}
+
diff --git a/example-clients/metro.c b/example-clients/metro.c
index d2daaa7f..feaa144a 100644
--- a/example-clients/metro.c
+++ b/example-clients/metro.c
@@ -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);
diff --git a/example-clients/midiseq.c b/example-clients/midiseq.c
index 10a37b2a..60b3e483 100644
--- a/example-clients/midiseq.c
+++ b/example-clients/midiseq.c
@@ -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);
}
diff --git a/example-clients/midisine.c b/example-clients/midisine.c
index 89ff7f75..ce830019 100644
--- a/example-clients/midisine.c
+++ b/example-clients/midisine.c
@@ -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);
diff --git a/example-clients/monitor_client.c b/example-clients/monitor_client.c
index 0a89b17c..36f61d6f 100644
--- a/example-clients/monitor_client.c
+++ b/example-clients/monitor_client.c
@@ -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;
}
diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c
index be7eb0e6..c9dd42ae 100644
--- a/example-clients/netmaster.c
+++ b/example-clients/netmaster.c
@@ -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;
}
diff --git a/example-clients/netslave.c b/example-clients/netslave.c
index 446d1561..2c136de9 100644
--- a/example-clients/netslave.c
+++ b/example-clients/netslave.c
@@ -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);
}
diff --git a/example-clients/showtime.c b/example-clients/showtime.c
index af413e89..fbbb94b7 100644
--- a/example-clients/showtime.c
+++ b/example-clients/showtime.c
@@ -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 ();
diff --git a/example-clients/zombie.c b/example-clients/zombie.c
index fb3cd24e..c982cfa8 100644
--- a/example-clients/zombie.c
+++ b/example-clients/zombie.c
@@ -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;
}
diff --git a/linux/JackLinuxTime.c b/linux/JackLinuxTime.c
index c80eb17d..18e616eb 100644
--- a/linux/JackLinuxTime.c
+++ b/linux/JackLinuxTime.c
@@ -143,7 +143,7 @@ static jack_time_t jack_get_mhz (void)
exit(1);
}
- for ( ; ; )
+ for (;;)
{
jack_time_t mhz;
int ret;
diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj
index 5b93588c..b9693086 100644
--- a/macosx/Jackdmp.xcodeproj/project.pbxproj
+++ b/macosx/Jackdmp.xcodeproj/project.pbxproj
@@ -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",
diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp
index fef7d4d8..319e1ddf 100644
--- a/macosx/coreaudio/JackCoreAudioAdapter.cpp
+++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp
@@ -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)
diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp
index f3ff2fb2..bad5801f 100644
--- a/macosx/coreaudio/JackCoreAudioDriver.cpp
+++ b/macosx/coreaudio/JackCoreAudioDriver.cpp
@@ -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;
diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h
index 8f50d597..71b27a6e 100644
--- a/macosx/coreaudio/JackCoreAudioDriver.h
+++ b/macosx/coreaudio/JackCoreAudioDriver.h
@@ -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,
diff --git a/macosx/iphone/freeverb.mm b/macosx/iphone/freeverb.mm
index 3daabc9a..1d1517d7 100644
--- a/macosx/iphone/freeverb.mm
+++ b/macosx/iphone/freeverb.mm
@@ -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;
}
diff --git a/macosx/iphone/main_master.mm b/macosx/iphone/main_master.mm
index 7ec618b3..ae71f227 100644
--- a/macosx/iphone/main_master.mm
+++ b/macosx/iphone/main_master.mm
@@ -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;
}
diff --git a/macosx/iphone/main_slave.mm b/macosx/iphone/main_slave.mm
index b4ef278b..b9875c32 100644
--- a/macosx/iphone/main_slave.mm
+++ b/macosx/iphone/main_slave.mm
@@ -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);
diff --git a/man/jack_connect.0 b/man/jack_connect.0
index 602ac39b..5ee8f8b5 100644
--- a/man/jack_connect.0
+++ b/man/jack_connect.0
@@ -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
diff --git a/posix/JackPosixSemaphore.cpp b/posix/JackPosixSemaphore.cpp
index 0be9fdb5..91e9d601 100644
--- a/posix/JackPosixSemaphore.cpp
+++ b/posix/JackPosixSemaphore.cpp
@@ -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;
diff --git a/posix/JackSocket.cpp b/posix/JackSocket.cpp
index 6d7d6879..2157a455 100644
--- a/posix/JackSocket.cpp
+++ b/posix/JackSocket.cpp
@@ -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 {
diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp
index 23d62e98..f40ae39a 100644
--- a/posix/JackSocketClientChannel.cpp
+++ b/posix/JackSocketClientChannel.cpp
@@ -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;
diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h
index 8e2b0e30..50da7de7 100644
--- a/posix/JackSocketClientChannel.h
+++ b/posix/JackSocketClientChannel.h
@@ -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)
{}
diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp
index caaac23c..73a16b16 100644
--- a/posix/JackSocketServerChannel.cpp
+++ b/posix/JackSocketServerChannel.cpp
@@ -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;
}
diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp
index e866e80d..9bf5d0b9 100644
--- a/windows/JackWinNamedPipeClientChannel.cpp
+++ b/windows/JackWinNamedPipeClientChannel.cpp
@@ -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;
diff --git a/windows/JackWinNamedPipeClientChannel.h b/windows/JackWinNamedPipeClientChannel.h
index 479e3271..7b84eba8 100644
--- a/windows/JackWinNamedPipeClientChannel.h
+++ b/windows/JackWinNamedPipeClientChannel.h
@@ -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)
{}
diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp
index a60c826a..b557a33c 100644
--- a/windows/JackWinNamedPipeServerChannel.cpp
+++ b/windows/JackWinNamedPipeServerChannel.cpp
@@ -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();
diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp
index d2f9b490..17f64965 100644
--- a/windows/libjackserver.cbp
+++ b/windows/libjackserver.cbp
@@ -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" />