@@ -58,9 +58,7 @@ On the slave, just launch a new jack server using : | |||
As in a standard backend in Jack2, you can use '-S' (synchronous mode). The asynchronous mode (without '-S') allows to send the computed data during the next cycle. In synchronous mode, data are sent back at the end of the cycle, that means after the process. You can specify some options, like '-n name' (will give a name to the slave, default is the network hostname), '-C input_ports' (the number of master-->slave channels), '-P output_ports' (the number of slave-->master channels), default is 2 ; or '-i midi_in_ports' and '-o midi_out_ports', default is 0. If you set multicast address or port on the master, you can add '-a xxx.xxx.xxx.xxx' and '-p udp_port'. | |||
You can also use others network mode, with '-m' option (fast, normal or slow). Fast mode allow a zero latency transmission. This mode means the master waits for its returned data from the slave in the current cycle. This mode is appropriated for 'small' transmissions (only a few channels with a light process on the slave). Normal mode brings one cycle latency. It allow a normal use of the network. | |||
Slow mode (default) allows a full usage of the whole system. Slow mode brings a two cycles additional latency. This mode allows to send a lot of data on the network, but it also takes into account some process time on the slave, thus the data aren't expected on the master before two cycles, so it's not necessary to wait for them. | |||
Latency (-n) is the number of buffers added in network transmission. Zero is for cases when the audio buffers can be sent to the other size, transformed by the process and returned in the same cycle. By default latency is 5 buffers. | |||
For additional informations, you can go to the NetJack2 Wiki at : http://trac.jackaudio.org/wiki/WalkThrough/User/NetJack2. | |||
@@ -1257,19 +1257,21 @@ LIB_EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* | |||
JackClient* client = (JackClient*)ext_client; | |||
if (client == NULL) { | |||
jack_error("jack_get_ports called with a NULL client"); | |||
return 0; | |||
jack_error("jack_port_by_name called with a NULL client"); | |||
return NULL; | |||
} | |||
if (portname == NULL) { | |||
jack_error("jack_port_by_name called with a NULL port name"); | |||
return NULL; | |||
} else { | |||
JackGraphManager* manager = GetGraphManager(); | |||
if (!manager) | |||
return NULL; | |||
} | |||
JackGraphManager* manager = GetGraphManager(); | |||
if (manager) { | |||
int res = manager->GetPort(portname); // returns a port index at least > 1 | |||
return (res == NO_PORT) ? NULL : (jack_port_t*)((uintptr_t)res); | |||
} else { | |||
return NULL; | |||
} | |||
} | |||
@@ -1399,7 +1401,7 @@ LIB_EXPORT float jack_cpu_load(jack_client_t* ext_client) | |||
return 0.0f; | |||
} else { | |||
JackEngineControl* control = GetEngineControl(); | |||
return (control ? control->fCPULoad : 0.0f); | |||
return (control ? control->fCPULoad : 0.0f); | |||
} | |||
} | |||
@@ -135,12 +135,16 @@ namespace Jack | |||
goto fail; | |||
} | |||
if (jack_set_latency_callback(fClient, LatencyCallback, this) < 0) { | |||
goto fail; | |||
} | |||
/* | |||
if (jack_set_port_connect_callback(fClient, SetConnectCallback, this) < 0) { | |||
goto fail; | |||
} | |||
*/ | |||
if (AllocPorts() != 0) { | |||
jack_error("Can't allocate JACK ports"); | |||
goto fail; | |||
@@ -193,7 +197,7 @@ namespace Jack | |||
if ((fAudioPlaybackPorts[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL) | |||
return -1; | |||
//port latency | |||
range.min = range.max = fParams.fNetworkLatency * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; | |||
range.min = range.max = fParams.fNetworkLatency * port_latency + ((fParams.fSlaveSyncMode) ? 0 : port_latency); | |||
jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range); | |||
} | |||
@@ -212,7 +216,7 @@ namespace Jack | |||
if ((fMidiPlaybackPorts[i] = jack_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL) | |||
return -1; | |||
//port latency | |||
range.min = range.max = fParams.fNetworkLatency * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency; | |||
range.min = range.max = fParams.fNetworkLatency * port_latency + ((fParams.fSlaveSyncMode) ? 0 : port_latency); | |||
jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range); | |||
} | |||
return 0; | |||
@@ -220,14 +224,14 @@ namespace Jack | |||
void JackNetMaster::ConnectPorts() | |||
{ | |||
const char **ports; | |||
const char** ports; | |||
ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); | |||
if (ports != NULL) { | |||
for (int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) { | |||
jack_connect(fClient, ports[i], jack_port_name(fAudioCapturePorts[i])); | |||
} | |||
free(ports); | |||
jack_free(ports); | |||
} | |||
ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); | |||
@@ -235,7 +239,7 @@ namespace Jack | |||
for (int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) { | |||
jack_connect(fClient, jack_port_name(fAudioPlaybackPorts[i]), ports[i]); | |||
} | |||
free(ports); | |||
jack_free(ports); | |||
} | |||
} | |||
@@ -383,6 +387,28 @@ namespace Jack | |||
} | |||
return 0; | |||
} | |||
void JackNetMaster::LatencyCallback(jack_latency_callback_mode_t mode, void* arg) | |||
{ | |||
JackNetMaster* obj = static_cast<JackNetMaster*>(arg); | |||
jack_nframes_t port_latency = jack_get_buffer_size(obj->fClient); | |||
jack_latency_range_t range; | |||
int i; | |||
//audio | |||
for (i = 0; i < obj->fParams.fReturnAudioChannels; i++) { | |||
//port latency | |||
range.min = range.max = obj->fParams.fNetworkLatency * port_latency + ((obj->fParams.fSlaveSyncMode) ? 0 : port_latency); | |||
jack_port_set_latency_range(obj->fAudioPlaybackPorts[i], JackPlaybackLatency, &range); | |||
} | |||
//midi | |||
for (i = 0; i < obj->fParams.fReturnMidiChannels; i++) { | |||
//port latency | |||
range.min = range.max = obj->fParams.fNetworkLatency * port_latency + ((obj->fParams.fSlaveSyncMode) ? 0 : port_latency); | |||
jack_port_set_latency_range(obj->fMidiPlaybackPorts[i], JackPlaybackLatency, &range); | |||
} | |||
} | |||
//process----------------------------------------------------------------------------- | |||
int JackNetMaster::SetProcess(jack_nframes_t nframes, void* arg) | |||
@@ -595,7 +621,7 @@ namespace Jack | |||
int JackNetMasterManager::CountIO(int flags) | |||
{ | |||
const char **ports; | |||
const char** ports; | |||
int count = 0; | |||
jack_port_t* port; | |||
@@ -606,7 +632,7 @@ namespace Jack | |||
&& (strcmp(jack_port_type(port), JACK_DEFAULT_AUDIO_TYPE) == 0)) { | |||
count++; | |||
} | |||
free(ports); | |||
jack_free(ports); | |||
} | |||
return count; | |||
} | |||
@@ -44,6 +44,7 @@ namespace Jack | |||
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 void SetConnectCallback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg); | |||
static void LatencyCallback(jack_latency_callback_mode_t mode, void* arg); | |||
//jack client | |||
jack_client_t* fClient; | |||