19 #include "JackCompilerDeps.h"
20 #include "driver_interface.h"
21 #include "JackNetDriver.h"
22 #include "JackEngineControl.h"
23 #include "JackLockedEngine.h"
24 #include "JackWaitThreadedDriver.h"
30 JackNetDriver::JackNetDriver(
const char* name,
const char* alias, JackLockedEngine* engine, JackSynchro* table,
31 const char* ip,
int udp_port,
int mtu,
int midi_input_ports,
int midi_output_ports,
32 char* net_name, uint transport_sync,
int network_latency,
33 int celt_encoding,
int opus_encoding,
bool auto_save)
34 : JackWaiterDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port)
36 jack_log(
"JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port);
39 if (strcmp(net_name,
"") == 0) {
40 GetHostName(net_name, JACK_CLIENT_NAME_SIZE);
45 fWantedMIDICaptureChannels = midi_input_ports;
46 fWantedMIDIPlaybackChannels = midi_output_ports;
48 if (celt_encoding > 0) {
49 fParams.fSampleEncoder = JackCeltEncoder;
50 fParams.fKBps = celt_encoding;
51 }
else if (opus_encoding > 0) {
52 fParams.fSampleEncoder = JackOpusEncoder;
53 fParams.fKBps = opus_encoding;
55 fParams.fSampleEncoder = JackFloatEncoder;
58 strcpy(fParams.fName, net_name);
59 fSocket.GetName(fParams.fSlaveNetName);
60 fParams.fTransportSync = transport_sync;
61 fParams.fNetworkLatency = network_latency;
62 fSendTransportData.fState = -1;
63 fReturnTransportData.fState = -1;
64 fLastTransportState = -1;
65 fLastTimebaseMaster = -1;
66 fMidiCapturePortList = NULL;
67 fMidiPlaybackPortList = NULL;
68 fWantedAudioCaptureChannels = -1;
69 fWantedAudioPlaybackChannels = -1;
70 fAutoSave = auto_save;
77 JackNetDriver::~JackNetDriver()
79 delete[] fMidiCapturePortList;
80 delete[] fMidiPlaybackPortList;
88 int JackNetDriver::Open(jack_nframes_t buffer_size,
89 jack_nframes_t samplerate,
95 const char* capture_driver_name,
96 const char* playback_driver_name,
97 jack_nframes_t capture_latency,
98 jack_nframes_t playback_latency)
101 fWantedAudioCaptureChannels = inchannels;
102 fWantedAudioPlaybackChannels = outchannels;
103 return JackWaiterDriver::Open(buffer_size, samplerate,
105 inchannels, outchannels,
107 capture_driver_name, playback_driver_name,
108 capture_latency, playback_latency);
111 int JackNetDriver::Close()
119 return JackWaiterDriver::Close();
123 int JackNetDriver::Attach()
128 int JackNetDriver::Detach()
139 bool JackNetDriver::Initialize()
141 jack_log(
"JackNetDriver::Initialize");
148 if (fSocket.IsSocket()) {
154 fParams.fSendAudioChannels = fWantedAudioCaptureChannels;
155 fParams.fReturnAudioChannels = fWantedAudioPlaybackChannels;
157 fParams.fSendMidiChannels = fWantedMIDICaptureChannels;
158 fParams.fReturnMidiChannels = fWantedMIDIPlaybackChannels;
160 fParams.fSlaveSyncMode = fEngineControl->fSyncMode;
163 jack_info(
"NetDriver started in %s mode %s Master's transport sync.",
164 (fParams.fSlaveSyncMode) ?
"sync" :
"async", (fParams.fTransportSync) ?
"with" :
"without");
167 if (!JackNetSlaveInterface::Init()) {
179 fCaptureChannels = fParams.fSendAudioChannels;
180 fPlaybackChannels = fParams.fReturnAudioChannels;
185 delete[] fMidiCapturePortList;
186 delete[] fMidiPlaybackPortList;
188 if (fParams.fSendMidiChannels > 0) {
189 fMidiCapturePortList =
new jack_port_id_t [fParams.fSendMidiChannels];
190 assert(fMidiCapturePortList);
191 for (
int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
192 fMidiCapturePortList[midi_port_index] = 0;
196 if (fParams.fReturnMidiChannels > 0) {
197 fMidiPlaybackPortList =
new jack_port_id_t [fParams.fReturnMidiChannels];
198 assert(fMidiPlaybackPortList);
199 for (
int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
200 fMidiPlaybackPortList[midi_port_index] = 0;
205 if (AllocPorts() != 0) {
211 SessionParamsDisplay(&fParams);
217 plot_name = string(fParams.fName);
218 plot_name += string(
"_slave");
219 plot_name += (fEngineControl->fSyncMode) ?
string(
"_sync") : string(
"_async");
220 plot_name += string(
"_latency");
221 fNetTimeMon =
new JackGnuPlotMonitor<float>(128, 5, plot_name);
222 string net_time_mon_fields[] =
224 string(
"sync decoded"),
225 string(
"end of read"),
226 string(
"start of write"),
228 string(
"end of write")
230 string net_time_mon_options[] =
232 string(
"set xlabel \"audio cycles\""),
233 string(
"set ylabel \"% of audio cycle\"")
235 fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 5);
238 JackTimedDriver::SetBufferSize(fParams.fPeriodSize);
239 JackTimedDriver::SetSampleRate(fParams.fSampleRate);
241 JackDriver::NotifyBufferSize(fParams.fPeriodSize);
242 JackDriver::NotifySampleRate(fParams.fSampleRate);
245 fEngineControl->fTransport.SetNetworkSync(fParams.fTransportSync);
253 void JackNetDriver::FreeAll()
259 delete fNetAudioCaptureBuffer;
260 delete fNetAudioPlaybackBuffer;
261 delete fNetMidiCaptureBuffer;
262 delete fNetMidiPlaybackBuffer;
263 delete[] fMidiCapturePortList;
264 delete[] fMidiPlaybackPortList;
268 fNetAudioCaptureBuffer = NULL;
269 fNetAudioPlaybackBuffer = NULL;
270 fNetMidiCaptureBuffer = NULL;
271 fNetMidiPlaybackBuffer = NULL;
272 fMidiCapturePortList = NULL;
273 fMidiPlaybackPortList = NULL;
281 void JackNetDriver::UpdateLatencies()
287 for (
int i = 0; i < fCaptureChannels; i++) {
288 input_range.
max = input_range.
min = float(fParams.fNetworkLatency * fEngineControl->fBufferSize) / 2.f;
289 fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range);
292 for (
int i = 0; i < fPlaybackChannels; i++) {
293 output_range.
max = output_range.
min = float(fParams.fNetworkLatency * fEngineControl->fBufferSize) / 2.f;
294 if (!fEngineControl->fSyncMode) {
295 output_range.
max = output_range.
min += fEngineControl->fBufferSize;
297 fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range);
298 if (fWithMonitorPorts) {
299 monitor_range.
min = monitor_range.
max = 0;
300 fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range);
306 int JackNetDriver::AllocPorts()
308 jack_log(
"JackNetDriver::AllocPorts fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
320 jack_port_id_t port_index;
321 char name[REAL_JACK_PORT_NAME_SIZE+1];
322 char alias[REAL_JACK_PORT_NAME_SIZE+1];
323 int audio_port_index;
327 for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) {
328 snprintf(alias,
sizeof(alias),
"%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1);
329 snprintf(name,
sizeof(name),
"%s:capture_%d", fClientControl.fName, audio_port_index + 1);
330 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
331 CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
332 jack_error(
"driver: cannot register port for %s", name);
336 port = fGraphManager->GetPort(port_index);
337 port->SetAlias(alias);
338 fCapturePortList[audio_port_index] = port_index;
339 jack_log(
"JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency());
342 for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
343 snprintf(alias,
sizeof(alias),
"%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1);
344 snprintf(name,
sizeof(name),
"%s:playback_%d",fClientControl.fName, audio_port_index + 1);
345 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
346 PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
347 jack_error(
"driver: cannot register port for %s", name);
351 port = fGraphManager->GetPort(port_index);
352 port->SetAlias(alias);
353 fPlaybackPortList[audio_port_index] = port_index;
354 jack_log(
"JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency());
358 for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
359 snprintf(alias,
sizeof(alias),
"%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1);
360 snprintf(name,
sizeof (name),
"%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1);
361 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
362 CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
363 jack_error(
"driver: cannot register port for %s", name);
367 port = fGraphManager->GetPort(port_index);
368 fMidiCapturePortList[midi_port_index] = port_index;
369 jack_log(
"JackNetDriver::AllocPorts() fMidiCapturePortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency());
372 for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
373 snprintf(alias,
sizeof(alias),
"%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1);
374 snprintf(name,
sizeof(name),
"%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1);
375 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
376 PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
377 jack_error(
"driver: cannot register port for %s", name);
381 port = fGraphManager->GetPort(port_index);
382 fMidiPlaybackPortList[midi_port_index] = port_index;
383 jack_log(
"JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency());
390 int JackNetDriver::FreePorts()
392 jack_log(
"JackNetDriver::FreePorts");
394 for (
int audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) {
395 if (fCapturePortList[audio_port_index] > 0) {
396 fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[audio_port_index]);
397 fCapturePortList[audio_port_index] = 0;
401 for (
int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
402 if (fPlaybackPortList[audio_port_index] > 0) {
403 fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[audio_port_index]);
404 fPlaybackPortList[audio_port_index] = 0;
408 for (
int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
409 if (fMidiCapturePortList && fMidiCapturePortList[midi_port_index] > 0) {
410 fGraphManager->ReleasePort(fClientControl.fRefNum, fMidiCapturePortList[midi_port_index]);
411 fMidiCapturePortList[midi_port_index] = 0;
415 for (
int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
416 if (fMidiPlaybackPortList && fMidiPlaybackPortList[midi_port_index] > 0) {
417 fEngine->PortUnRegister(fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index]);
418 fMidiPlaybackPortList[midi_port_index] = 0;
424 void JackNetDriver::SaveConnections(
int alias)
426 JackDriver::SaveConnections(alias);
427 const char** connections;
429 if (fMidiCapturePortList) {
430 for (
int i = 0; i < fParams.fSendMidiChannels; ++i) {
431 if (fMidiCapturePortList[i] && (connections = fGraphManager->GetConnections(fMidiCapturePortList[i])) != 0) {
432 for (
int j = 0; connections[j]; j++) {
433 JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
434 fConnections.push_back(make_pair(port_id->GetType(), make_pair(fGraphManager->GetPort(fMidiCapturePortList[i])->GetName(), connections[j])));
435 jack_info(
"Save connection: %s %s", fGraphManager->GetPort(fMidiCapturePortList[i])->GetName(), connections[j]);
442 if (fMidiPlaybackPortList) {
443 for (
int i = 0; i < fParams.fReturnMidiChannels; ++i) {
444 if (fMidiPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fMidiPlaybackPortList[i])) != 0) {
445 for (
int j = 0; connections[j]; j++) {
446 JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
447 fConnections.push_back(make_pair(port_id->GetType(), make_pair(connections[j], fGraphManager->GetPort(fMidiPlaybackPortList[i])->GetName())));
448 jack_info(
"Save connection: %s %s", connections[j], fGraphManager->GetPort(fMidiPlaybackPortList[i])->GetName());
456 JackMidiBuffer* JackNetDriver::GetMidiInputBuffer(
int port_index)
458 return static_cast<JackMidiBuffer*>(fGraphManager->GetBuffer(fMidiCapturePortList[port_index], fEngineControl->fBufferSize));
461 JackMidiBuffer* JackNetDriver::GetMidiOutputBuffer(
int port_index)
463 return static_cast<JackMidiBuffer*>(fGraphManager->GetBuffer(fMidiPlaybackPortList[port_index], fEngineControl->fBufferSize));
467 void JackNetDriver::DecodeTransportData()
475 if (fSendTransportData.fTimebaseMaster == TIMEBASEMASTER) {
476 fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional);
478 fEngineControl->fTransport.ResetTimebase(refnum);
480 jack_info(
"The NetMaster is now the new timebase master.");
484 if (fSendTransportData.fNewState &&(fSendTransportData.fState != fEngineControl->fTransport.GetState())) {
486 switch (fSendTransportData.fState)
488 case JackTransportStopped :
489 fEngineControl->fTransport.SetCommand(TransportCommandStop);
493 case JackTransportStarting :
494 fEngineControl->fTransport.RequestNewPos(&fSendTransportData.fPosition);
495 fEngineControl->fTransport.SetCommand(TransportCommandStart);
496 jack_info(
"Master starts transport frame = %d", fSendTransportData.fPosition.frame);
499 case JackTransportRolling :
501 fEngineControl->fTransport.SetState(JackTransportRolling);
508 void JackNetDriver::EncodeTransportData()
513 fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional);
514 if (refnum != fLastTimebaseMaster) {
517 fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER;
518 jack_info(
"Sending a timebase master release request.");
521 fReturnTransportData.fTimebaseMaster = (conditional) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER;
522 jack_info(
"Sending a %s timebase master request.", (conditional) ?
"conditional" :
"non-conditional");
524 fLastTimebaseMaster = refnum;
526 fReturnTransportData.fTimebaseMaster = NO_CHANGE;
530 fReturnTransportData.fState = fEngineControl->fTransport.Query(&fReturnTransportData.fPosition);
533 fReturnTransportData.fNewState = ((fReturnTransportData.fState == JackTransportNetStarting) &&
534 (fReturnTransportData.fState != fLastTransportState) &&
535 (fReturnTransportData.fState != fSendTransportData.fState));
536 if (fReturnTransportData.fNewState) {
537 jack_info(
"Sending '%s'.", GetTransportState(fReturnTransportData.fState));
539 fLastTransportState = fReturnTransportData.fState;
544 int JackNetDriver::Read()
547 for (
int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
548 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, GetMidiInputBuffer(midi_port_index));
551 for (
int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
552 #ifdef OPTIMIZED_PROTOCOL
553 if (fGraphManager->GetConnectionsNum(fCapturePortList[audio_port_index]) > 0) {
554 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index));
556 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL);
559 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index));
567 switch (SyncRecv()) {
572 case SYNC_PACKET_ERROR:
579 DecodeSyncPacket(unused_frames);
585 fRcvSyncUst = GetMicroSeconds();
589 fNetTimeMon->Add(
float(GetMicroSeconds() - fRcvSyncUst) /
float(fEngineControl->fPeriodUsecs) * 100.f);
592 switch (DataRecv()) {
597 case DATA_PACKET_ERROR:
598 jack_time_t cur_time = GetMicroSeconds();
599 NotifyXRun(cur_time,
float(cur_time - fBeginDateUst));
604 JackDriver::CycleTakeBeginTime();
607 fNetTimeMon->Add(
float(GetMicroSeconds() - fRcvSyncUst) /
float(fEngineControl->fPeriodUsecs) * 100.f);
613 int JackNetDriver::Write()
616 for (
int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
617 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, GetMidiOutputBuffer(midi_port_index));
620 for (
int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
621 #ifdef OPTIMIZED_PROTOCOL
623 if (fNetAudioPlaybackBuffer->GetConnected(audio_port_index)
624 && (fGraphManager->GetConnectionsNum(fPlaybackPortList[audio_port_index]) > 0)) {
625 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index));
627 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL);
630 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index));
635 fNetTimeMon->AddLast(
float(GetMicroSeconds() - fRcvSyncUst) /
float(fEngineControl->fPeriodUsecs) * 100.f);
641 if (SyncSend() == SOCKET_ERROR) {
646 fNetTimeMon->Add(((
float)(GetMicroSeconds() - fRcvSyncUst) / (
float)fEngineControl->fPeriodUsecs) * 100.f);
650 if (DataSend() == SOCKET_ERROR) {
655 fNetTimeMon->AddLast(((
float)(GetMicroSeconds() - fRcvSyncUst) / (
float)fEngineControl->fPeriodUsecs) * 100.f);
674 desc = jack_driver_descriptor_construct(
"net", JackDriverMaster,
"netjack slave backend component", &filler);
676 strcpy(value.str, DEFAULT_MULTICAST_IP);
677 jack_driver_descriptor_add_parameter(desc, &filler,
"multicast-ip",
'a', JackDriverParamString, &value, NULL,
"Multicast address, or explicit IP of the master", NULL);
679 value.i = DEFAULT_PORT;
680 jack_driver_descriptor_add_parameter(desc, &filler,
"udp-net-port",
'p', JackDriverParamInt, &value, NULL,
"UDP port", NULL);
682 value.i = DEFAULT_MTU;
683 jack_driver_descriptor_add_parameter(desc, &filler,
"mtu",
'M', JackDriverParamInt, &value, NULL,
"MTU to the master", NULL);
686 jack_driver_descriptor_add_parameter(desc, &filler,
"input-ports",
'C', JackDriverParamInt, &value, NULL,
"Number of audio input ports",
"Number of audio input ports. If -1, audio physical input from the master");
687 jack_driver_descriptor_add_parameter(desc, &filler,
"output-ports",
'P', JackDriverParamInt, &value, NULL,
"Number of audio output ports",
"Number of audio output ports. If -1, audio physical output from the master");
690 jack_driver_descriptor_add_parameter(desc, &filler,
"midi-in-ports",
'i', JackDriverParamInt, &value, NULL,
"Number of midi input ports",
"Number of MIDI input ports. If -1, MIDI physical input from the master");
691 jack_driver_descriptor_add_parameter(desc, &filler,
"midi-out-ports",
'o', JackDriverParamInt, &value, NULL,
"Number of midi output ports",
"Number of MIDI output ports. If -1, MIDI physical output from the master");
695 jack_driver_descriptor_add_parameter(desc, &filler,
"celt",
'c', JackDriverParamInt, &value, NULL,
"Set CELT encoding and number of kBits per channel", NULL);
699 jack_driver_descriptor_add_parameter(desc, &filler,
"opus",
'O', JackDriverParamInt, &value, NULL,
"Set Opus encoding and number of kBits per channel", NULL);
701 strcpy(value.str,
"'hostname'");
702 jack_driver_descriptor_add_parameter(desc, &filler,
"client-name",
'n', JackDriverParamString, &value, NULL,
"Name of the jack client", NULL);
705 jack_driver_descriptor_add_parameter(desc, &filler,
"auto-save",
's', JackDriverParamBool, &value, NULL,
"Save/restore connection state when restarting", NULL);
715 jack_driver_descriptor_add_parameter(desc, &filler,
"latency",
'l', JackDriverParamUInt, &value, NULL,
"Network latency", NULL);
722 char multicast_ip[32];
723 char net_name[JACK_CLIENT_NAME_SIZE+1] = {0};
725 int mtu = DEFAULT_MTU;
727 uint transport_sync = 0;
728 jack_nframes_t period_size = 1024;
729 jack_nframes_t sample_rate = 48000;
730 int audio_capture_ports = -1;
731 int audio_playback_ports = -1;
732 int midi_input_ports = -1;
733 int midi_output_ports = -1;
734 int celt_encoding = -1;
735 int opus_encoding = -1;
736 bool monitor =
false;
737 int network_latency = 5;
740 bool auto_save =
false;
743 const char* default_udp_port = getenv(
"JACK_NETJACK_PORT");
744 udp_port = (default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT;
747 const char* default_multicast_ip = getenv(
"JACK_NETJACK_MULTICAST");
748 strcpy(multicast_ip, (default_multicast_ip) ? default_multicast_ip : DEFAULT_MULTICAST_IP);
750 for (node = params; node; node = jack_slist_next(node)) {
752 switch (param->character)
755 assert(strlen(param->value.str) < 32);
756 strcpy(multicast_ip, param->value.str);
759 udp_port = param->value.ui;
762 mtu = param->value.i;
765 audio_capture_ports = param->value.i;
768 audio_playback_ports = param->value.i;
771 midi_input_ports = param->value.i;
774 midi_output_ports = param->value.i;
778 celt_encoding = param->value.i;
783 opus_encoding = param->value.i;
787 strncpy(net_name, param->value.str, JACK_CLIENT_NAME_SIZE);
799 network_latency = param->value.ui;
800 if (network_latency > NETWORK_MAX_LATENCY) {
801 printf(
"Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
812 midi_input_ports, midi_output_ports,
813 net_name, transport_sync,
814 network_latency, celt_encoding, opus_encoding, auto_save));
815 if (driver->Open(period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, monitor,
"from_master_",
"to_master_", 0, 0) == 0) {