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) {
 Wrapper for a restartable threaded driver (e.g. JackNetDriver).
Locked Engine, access to methods is serialized using a mutex.
Inter process synchronization using POSIX semaphore.
SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)
The base interface for drivers clients.
SERVER_EXPORT void jack_log(const char *fmt,...)