00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "JackCompilerDeps.h"
00020 #include "driver_interface.h"
00021 #include "JackNetDriver.h"
00022 #include "JackEngineControl.h"
00023 #include "JackLockedEngine.h"
00024 #include "JackWaitThreadedDriver.h"
00025
00026 using namespace std;
00027
00028 namespace Jack
00029 {
00030 JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
00031 const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports,
00032 char* net_name, uint transport_sync, int network_latency,
00033 int celt_encoding, int opus_encoding, bool auto_save)
00034 : JackWaiterDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port)
00035 {
00036 jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port);
00037
00038
00039 if (strcmp(net_name, "") == 0) {
00040 GetHostName(net_name, JACK_CLIENT_NAME_SIZE);
00041 }
00042
00043 fParams.fMtu = mtu;
00044
00045 fWantedMIDICaptureChannels = midi_input_ports;
00046 fWantedMIDIPlaybackChannels = midi_output_ports;
00047
00048 if (celt_encoding > 0) {
00049 fParams.fSampleEncoder = JackCeltEncoder;
00050 fParams.fKBps = celt_encoding;
00051 } else if (opus_encoding > 0) {
00052 fParams.fSampleEncoder = JackOpusEncoder;
00053 fParams.fKBps = opus_encoding;
00054 } else {
00055 fParams.fSampleEncoder = JackFloatEncoder;
00056
00057 }
00058 strcpy(fParams.fName, net_name);
00059 fSocket.GetName(fParams.fSlaveNetName);
00060 fParams.fTransportSync = transport_sync;
00061 fParams.fNetworkLatency = network_latency;
00062 fSendTransportData.fState = -1;
00063 fReturnTransportData.fState = -1;
00064 fLastTransportState = -1;
00065 fLastTimebaseMaster = -1;
00066 fMidiCapturePortList = NULL;
00067 fMidiPlaybackPortList = NULL;
00068 fWantedAudioCaptureChannels = -1;
00069 fWantedAudioPlaybackChannels = -1;
00070 fAutoSave = auto_save;
00071 #ifdef JACK_MONITOR
00072 fNetTimeMon = NULL;
00073 fRcvSyncUst = 0;
00074 #endif
00075 }
00076
00077 JackNetDriver::~JackNetDriver()
00078 {
00079 delete[] fMidiCapturePortList;
00080 delete[] fMidiPlaybackPortList;
00081 #ifdef JACK_MONITOR
00082 delete fNetTimeMon;
00083 #endif
00084 }
00085
00086
00087
00088 int JackNetDriver::Open(jack_nframes_t buffer_size,
00089 jack_nframes_t samplerate,
00090 bool capturing,
00091 bool playing,
00092 int inchannels,
00093 int outchannels,
00094 bool monitor,
00095 const char* capture_driver_name,
00096 const char* playback_driver_name,
00097 jack_nframes_t capture_latency,
00098 jack_nframes_t playback_latency)
00099 {
00100
00101 fWantedAudioCaptureChannels = inchannels;
00102 fWantedAudioPlaybackChannels = outchannels;
00103 return JackWaiterDriver::Open(buffer_size, samplerate,
00104 capturing, playing,
00105 inchannels, outchannels,
00106 monitor,
00107 capture_driver_name, playback_driver_name,
00108 capture_latency, playback_latency);
00109 }
00110
00111 int JackNetDriver::Close()
00112 {
00113 #ifdef JACK_MONITOR
00114 if (fNetTimeMon) {
00115 fNetTimeMon->Save();
00116 }
00117 #endif
00118 FreeAll();
00119 return JackWaiterDriver::Close();
00120 }
00121
00122
00123 int JackNetDriver::Attach()
00124 {
00125 return 0;
00126 }
00127
00128 int JackNetDriver::Detach()
00129 {
00130 return 0;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 bool JackNetDriver::Initialize()
00140 {
00141 jack_log("JackNetDriver::Initialize");
00142 if (fAutoSave) {
00143 SaveConnections(0);
00144 }
00145 FreePorts();
00146
00147
00148 if (fSocket.IsSocket()) {
00149 jack_info("Restarting driver...");
00150 FreeAll();
00151 }
00152
00153
00154 fParams.fSendAudioChannels = fWantedAudioCaptureChannels;
00155 fParams.fReturnAudioChannels = fWantedAudioPlaybackChannels;
00156
00157 fParams.fSendMidiChannels = fWantedMIDICaptureChannels;
00158 fParams.fReturnMidiChannels = fWantedMIDIPlaybackChannels;
00159
00160 fParams.fSlaveSyncMode = fEngineControl->fSyncMode;
00161
00162
00163 jack_info("NetDriver started in %s mode %s Master's transport sync.",
00164 (fParams.fSlaveSyncMode) ? "sync" : "async", (fParams.fTransportSync) ? "with" : "without");
00165
00166
00167 if (!JackNetSlaveInterface::Init()) {
00168 jack_error("Starting network fails...");
00169 return false;
00170 }
00171
00172
00173 if (!SetParams()) {
00174 jack_error("SetParams error...");
00175 return false;
00176 }
00177
00178
00179 fCaptureChannels = fParams.fSendAudioChannels;
00180 fPlaybackChannels = fParams.fReturnAudioChannels;
00181
00182
00183
00184
00185 delete[] fMidiCapturePortList;
00186 delete[] fMidiPlaybackPortList;
00187
00188 if (fParams.fSendMidiChannels > 0) {
00189 fMidiCapturePortList = new jack_port_id_t [fParams.fSendMidiChannels];
00190 assert(fMidiCapturePortList);
00191 for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
00192 fMidiCapturePortList[midi_port_index] = 0;
00193 }
00194 }
00195
00196 if (fParams.fReturnMidiChannels > 0) {
00197 fMidiPlaybackPortList = new jack_port_id_t [fParams.fReturnMidiChannels];
00198 assert(fMidiPlaybackPortList);
00199 for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
00200 fMidiPlaybackPortList[midi_port_index] = 0;
00201 }
00202 }
00203
00204
00205 if (AllocPorts() != 0) {
00206 jack_error("Can't allocate ports.");
00207 return false;
00208 }
00209
00210
00211 SessionParamsDisplay(&fParams);
00212
00213
00214 #ifdef JACK_MONITOR
00215 string plot_name;
00216
00217 plot_name = string(fParams.fName);
00218 plot_name += string("_slave");
00219 plot_name += (fEngineControl->fSyncMode) ? string("_sync") : string("_async");
00220 plot_name += string("_latency");
00221 fNetTimeMon = new JackGnuPlotMonitor<float>(128, 5, plot_name);
00222 string net_time_mon_fields[] =
00223 {
00224 string("sync decoded"),
00225 string("end of read"),
00226 string("start of write"),
00227 string("sync send"),
00228 string("end of write")
00229 };
00230 string net_time_mon_options[] =
00231 {
00232 string("set xlabel \"audio cycles\""),
00233 string("set ylabel \"% of audio cycle\"")
00234 };
00235 fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 5);
00236 #endif
00237
00238 JackTimedDriver::SetBufferSize(fParams.fPeriodSize);
00239 JackTimedDriver::SetSampleRate(fParams.fSampleRate);
00240
00241 JackDriver::NotifyBufferSize(fParams.fPeriodSize);
00242 JackDriver::NotifySampleRate(fParams.fSampleRate);
00243
00244
00245 fEngineControl->fTransport.SetNetworkSync(fParams.fTransportSync);
00246
00247 if (fAutoSave) {
00248 LoadConnections(0);
00249 }
00250 return true;
00251 }
00252
00253 void JackNetDriver::FreeAll()
00254 {
00255 FreePorts();
00256
00257 delete[] fTxBuffer;
00258 delete[] fRxBuffer;
00259 delete fNetAudioCaptureBuffer;
00260 delete fNetAudioPlaybackBuffer;
00261 delete fNetMidiCaptureBuffer;
00262 delete fNetMidiPlaybackBuffer;
00263 delete[] fMidiCapturePortList;
00264 delete[] fMidiPlaybackPortList;
00265
00266 fTxBuffer = NULL;
00267 fRxBuffer = NULL;
00268 fNetAudioCaptureBuffer = NULL;
00269 fNetAudioPlaybackBuffer = NULL;
00270 fNetMidiCaptureBuffer = NULL;
00271 fNetMidiPlaybackBuffer = NULL;
00272 fMidiCapturePortList = NULL;
00273 fMidiPlaybackPortList = NULL;
00274
00275 #ifdef JACK_MONITOR
00276 delete fNetTimeMon;
00277 fNetTimeMon = NULL;
00278 #endif
00279 }
00280
00281 void JackNetDriver::UpdateLatencies()
00282 {
00283 jack_latency_range_t input_range;
00284 jack_latency_range_t output_range;
00285 jack_latency_range_t monitor_range;
00286
00287 for (int i = 0; i < fCaptureChannels; i++) {
00288 input_range.max = input_range.min = float(fParams.fNetworkLatency * fEngineControl->fBufferSize) / 2.f;
00289 fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range);
00290 }
00291
00292 for (int i = 0; i < fPlaybackChannels; i++) {
00293 output_range.max = output_range.min = float(fParams.fNetworkLatency * fEngineControl->fBufferSize) / 2.f;
00294 if (!fEngineControl->fSyncMode) {
00295 output_range.max = output_range.min += fEngineControl->fBufferSize;
00296 }
00297 fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range);
00298 if (fWithMonitorPorts) {
00299 monitor_range.min = monitor_range.max = 0;
00300 fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range);
00301 }
00302 }
00303 }
00304
00305
00306 int JackNetDriver::AllocPorts()
00307 {
00308 jack_log("JackNetDriver::AllocPorts fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 JackPort* port;
00320 jack_port_id_t port_index;
00321 char name[REAL_JACK_PORT_NAME_SIZE];
00322 char alias[REAL_JACK_PORT_NAME_SIZE];
00323 int audio_port_index;
00324 int midi_port_index;
00325
00326
00327 for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) {
00328 snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1);
00329 snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, audio_port_index + 1);
00330 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
00331 CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
00332 jack_error("driver: cannot register port for %s", name);
00333 return -1;
00334 }
00335
00336 port = fGraphManager->GetPort(port_index);
00337 port->SetAlias(alias);
00338 fCapturePortList[audio_port_index] = port_index;
00339 jack_log("JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency());
00340 }
00341
00342 for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
00343 snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1);
00344 snprintf(name, sizeof(name), "%s:playback_%d",fClientControl.fName, audio_port_index + 1);
00345 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE,
00346 PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
00347 jack_error("driver: cannot register port for %s", name);
00348 return -1;
00349 }
00350
00351 port = fGraphManager->GetPort(port_index);
00352 port->SetAlias(alias);
00353 fPlaybackPortList[audio_port_index] = port_index;
00354 jack_log("JackNetDriver::AllocPorts() fPlaybackPortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency());
00355 }
00356
00357
00358 for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
00359 snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1);
00360 snprintf(name, sizeof (name), "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1);
00361 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
00362 CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
00363 jack_error("driver: cannot register port for %s", name);
00364 return -1;
00365 }
00366
00367 port = fGraphManager->GetPort(port_index);
00368 fMidiCapturePortList[midi_port_index] = port_index;
00369 jack_log("JackNetDriver::AllocPorts() fMidiCapturePortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency());
00370 }
00371
00372 for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
00373 snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1);
00374 snprintf(name, sizeof(name), "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1);
00375 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE,
00376 PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
00377 jack_error("driver: cannot register port for %s", name);
00378 return -1;
00379 }
00380
00381 port = fGraphManager->GetPort(port_index);
00382 fMidiPlaybackPortList[midi_port_index] = port_index;
00383 jack_log("JackNetDriver::AllocPorts() fMidiPlaybackPortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency());
00384 }
00385
00386 UpdateLatencies();
00387 return 0;
00388 }
00389
00390 int JackNetDriver::FreePorts()
00391 {
00392 jack_log("JackNetDriver::FreePorts");
00393
00394 for (int audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) {
00395 if (fCapturePortList[audio_port_index] > 0) {
00396 fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[audio_port_index]);
00397 fCapturePortList[audio_port_index] = 0;
00398 }
00399 }
00400
00401 for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
00402 if (fPlaybackPortList[audio_port_index] > 0) {
00403 fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[audio_port_index]);
00404 fPlaybackPortList[audio_port_index] = 0;
00405 }
00406 }
00407
00408 for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
00409 if (fMidiCapturePortList && fMidiCapturePortList[midi_port_index] > 0) {
00410 fGraphManager->ReleasePort(fClientControl.fRefNum, fMidiCapturePortList[midi_port_index]);
00411 fMidiCapturePortList[midi_port_index] = 0;
00412 }
00413 }
00414
00415 for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
00416 if (fMidiPlaybackPortList && fMidiPlaybackPortList[midi_port_index] > 0) {
00417 fEngine->PortUnRegister(fClientControl.fRefNum, fMidiPlaybackPortList[midi_port_index]);
00418 fMidiPlaybackPortList[midi_port_index] = 0;
00419 }
00420 }
00421 return 0;
00422 }
00423
00424 void JackNetDriver::SaveConnections(int alias)
00425 {
00426 JackDriver::SaveConnections(alias);
00427 const char** connections;
00428
00429 if (fMidiCapturePortList) {
00430 for (int i = 0; i < fParams.fSendMidiChannels; ++i) {
00431 if (fMidiCapturePortList[i] && (connections = fGraphManager->GetConnections(fMidiCapturePortList[i])) != 0) {
00432 for (int j = 0; connections[j]; j++) {
00433 JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
00434 fConnections.push_back(make_pair(port_id->GetType(), make_pair(fGraphManager->GetPort(fMidiCapturePortList[i])->GetName(), connections[j])));
00435 jack_info("Save connection: %s %s", fGraphManager->GetPort(fMidiCapturePortList[i])->GetName(), connections[j]);
00436 }
00437 free(connections);
00438 }
00439 }
00440 }
00441
00442 if (fMidiPlaybackPortList) {
00443 for (int i = 0; i < fParams.fReturnMidiChannels; ++i) {
00444 if (fMidiPlaybackPortList[i] && (connections = fGraphManager->GetConnections(fMidiPlaybackPortList[i])) != 0) {
00445 for (int j = 0; connections[j]; j++) {
00446 JackPort* port_id = fGraphManager->GetPort(fGraphManager->GetPort(connections[j]));
00447 fConnections.push_back(make_pair(port_id->GetType(), make_pair(connections[j], fGraphManager->GetPort(fMidiPlaybackPortList[i])->GetName())));
00448 jack_info("Save connection: %s %s", connections[j], fGraphManager->GetPort(fMidiPlaybackPortList[i])->GetName());
00449 }
00450 free(connections);
00451 }
00452 }
00453 }
00454 }
00455
00456 JackMidiBuffer* JackNetDriver::GetMidiInputBuffer(int port_index)
00457 {
00458 return static_cast<JackMidiBuffer*>(fGraphManager->GetBuffer(fMidiCapturePortList[port_index], fEngineControl->fBufferSize));
00459 }
00460
00461 JackMidiBuffer* JackNetDriver::GetMidiOutputBuffer(int port_index)
00462 {
00463 return static_cast<JackMidiBuffer*>(fGraphManager->GetBuffer(fMidiPlaybackPortList[port_index], fEngineControl->fBufferSize));
00464 }
00465
00466
00467 void JackNetDriver::DecodeTransportData()
00468 {
00469
00470
00471
00472
00473 int refnum;
00474 bool conditional;
00475 if (fSendTransportData.fTimebaseMaster == TIMEBASEMASTER) {
00476 fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional);
00477 if (refnum != -1) {
00478 fEngineControl->fTransport.ResetTimebase(refnum);
00479 }
00480 jack_info("The NetMaster is now the new timebase master.");
00481 }
00482
00483
00484 if (fSendTransportData.fNewState &&(fSendTransportData.fState != fEngineControl->fTransport.GetState())) {
00485
00486 switch (fSendTransportData.fState)
00487 {
00488 case JackTransportStopped :
00489 fEngineControl->fTransport.SetCommand(TransportCommandStop);
00490 jack_info("Master stops transport.");
00491 break;
00492
00493 case JackTransportStarting :
00494 fEngineControl->fTransport.RequestNewPos(&fSendTransportData.fPosition);
00495 fEngineControl->fTransport.SetCommand(TransportCommandStart);
00496 jack_info("Master starts transport frame = %d", fSendTransportData.fPosition.frame);
00497 break;
00498
00499 case JackTransportRolling :
00500
00501 fEngineControl->fTransport.SetState(JackTransportRolling);
00502 jack_info("Master is rolling.");
00503 break;
00504 }
00505 }
00506 }
00507
00508 void JackNetDriver::EncodeTransportData()
00509 {
00510
00511 int refnum;
00512 bool conditional;
00513 fEngineControl->fTransport.GetTimebaseMaster(refnum, conditional);
00514 if (refnum != fLastTimebaseMaster) {
00515
00516 if (refnum == -1) {
00517 fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER;
00518 jack_info("Sending a timebase master release request.");
00519 } else {
00520
00521 fReturnTransportData.fTimebaseMaster = (conditional) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER;
00522 jack_info("Sending a %s timebase master request.", (conditional) ? "conditional" : "non-conditional");
00523 }
00524 fLastTimebaseMaster = refnum;
00525 } else {
00526 fReturnTransportData.fTimebaseMaster = NO_CHANGE;
00527 }
00528
00529
00530 fReturnTransportData.fState = fEngineControl->fTransport.Query(&fReturnTransportData.fPosition);
00531
00532
00533 fReturnTransportData.fNewState = ((fReturnTransportData.fState == JackTransportNetStarting) &&
00534 (fReturnTransportData.fState != fLastTransportState) &&
00535 (fReturnTransportData.fState != fSendTransportData.fState));
00536 if (fReturnTransportData.fNewState) {
00537 jack_info("Sending '%s'.", GetTransportState(fReturnTransportData.fState));
00538 }
00539 fLastTransportState = fReturnTransportData.fState;
00540 }
00541
00542
00543
00544 int JackNetDriver::Read()
00545 {
00546
00547 for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
00548 fNetMidiCaptureBuffer->SetBuffer(midi_port_index, GetMidiInputBuffer(midi_port_index));
00549 }
00550
00551 for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
00552 #ifdef OPTIMIZED_PROTOCOL
00553 if (fGraphManager->GetConnectionsNum(fCapturePortList[audio_port_index]) > 0) {
00554 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index));
00555 } else {
00556 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL);
00557 }
00558 #else
00559 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index));
00560 #endif
00561 }
00562
00563 #ifdef JACK_MONITOR
00564 fNetTimeMon->New();
00565 #endif
00566
00567 switch (SyncRecv()) {
00568
00569 case SOCKET_ERROR:
00570 return SOCKET_ERROR;
00571
00572 case SYNC_PACKET_ERROR:
00573
00574 break;
00575
00576 default:
00577
00578 int unused_frames;
00579 DecodeSyncPacket(unused_frames);
00580 break;
00581 }
00582
00583 #ifdef JACK_MONITOR
00584
00585 fRcvSyncUst = GetMicroSeconds();
00586 #endif
00587
00588 #ifdef JACK_MONITOR
00589 fNetTimeMon->Add(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f);
00590 #endif
00591
00592 switch (DataRecv()) {
00593
00594 case SOCKET_ERROR:
00595 return SOCKET_ERROR;
00596
00597 case DATA_PACKET_ERROR:
00598 jack_time_t cur_time = GetMicroSeconds();
00599 NotifyXRun(cur_time, float(cur_time - fBeginDateUst));
00600 break;
00601 }
00602
00603
00604 JackDriver::CycleTakeBeginTime();
00605
00606 #ifdef JACK_MONITOR
00607 fNetTimeMon->Add(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f);
00608 #endif
00609
00610 return 0;
00611 }
00612
00613 int JackNetDriver::Write()
00614 {
00615
00616 for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
00617 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, GetMidiOutputBuffer(midi_port_index));
00618 }
00619
00620 for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) {
00621 #ifdef OPTIMIZED_PROTOCOL
00622
00623 if (fNetAudioPlaybackBuffer->GetConnected(audio_port_index)
00624 && (fGraphManager->GetConnectionsNum(fPlaybackPortList[audio_port_index]) > 0)) {
00625 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index));
00626 } else {
00627 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL);
00628 }
00629 #else
00630 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index));
00631 #endif
00632 }
00633
00634 #ifdef JACK_MONITOR
00635 fNetTimeMon->AddLast(float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f);
00636 #endif
00637
00638 EncodeSyncPacket();
00639
00640
00641 if (SyncSend() == SOCKET_ERROR) {
00642 return SOCKET_ERROR;
00643 }
00644
00645 #ifdef JACK_MONITOR
00646 fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
00647 #endif
00648
00649
00650 if (DataSend() == SOCKET_ERROR) {
00651 return SOCKET_ERROR;
00652 }
00653
00654 #ifdef JACK_MONITOR
00655 fNetTimeMon->AddLast(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f);
00656 #endif
00657
00658 return 0;
00659 }
00660
00661
00662
00663 #ifdef __cplusplus
00664 extern "C"
00665 {
00666 #endif
00667
00668 SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor()
00669 {
00670 jack_driver_desc_t * desc;
00671 jack_driver_desc_filler_t filler;
00672 jack_driver_param_value_t value;
00673
00674 desc = jack_driver_descriptor_construct("net", JackDriverMaster, "netjack slave backend component", &filler);
00675
00676 strcpy(value.str, DEFAULT_MULTICAST_IP);
00677 jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast address, or explicit IP of the master", NULL);
00678
00679 value.i = DEFAULT_PORT;
00680 jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);
00681
00682 value.i = DEFAULT_MTU;
00683 jack_driver_descriptor_add_parameter(desc, &filler, "mtu", 'M', JackDriverParamInt, &value, NULL, "MTU to the master", NULL);
00684
00685 value.i = -1;
00686 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");
00687 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");
00688
00689 value.i = -1;
00690 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");
00691 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");
00692
00693 #if HAVE_CELT
00694 value.i = -1;
00695 jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamInt, &value, NULL, "Set CELT encoding and number of kBits per channel", NULL);
00696 #endif
00697 #if HAVE_OPUS
00698 value.i = -1;
00699 jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'O', JackDriverParamInt, &value, NULL, "Set Opus encoding and number of kBits per channel", NULL);
00700 #endif
00701 strcpy(value.str, "'hostname'");
00702 jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL);
00703
00704 value.i = false;
00705 jack_driver_descriptor_add_parameter(desc, &filler, "auto-save", 's', JackDriverParamBool, &value, NULL, "Save/restore connection state when restarting", NULL);
00706
00707
00708
00709
00710
00711
00712
00713
00714 value.ui = 5U;
00715 jack_driver_descriptor_add_parameter(desc, &filler, "latency", 'l', JackDriverParamUInt, &value, NULL, "Network latency", NULL);
00716
00717 return desc;
00718 }
00719
00720 SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
00721 {
00722 char multicast_ip[32];
00723 char net_name[JACK_CLIENT_NAME_SIZE + 1] = {0};
00724 int udp_port;
00725 int mtu = DEFAULT_MTU;
00726
00727 uint transport_sync = 0;
00728 jack_nframes_t period_size = 1024;
00729 jack_nframes_t sample_rate = 48000;
00730 int audio_capture_ports = -1;
00731 int audio_playback_ports = -1;
00732 int midi_input_ports = -1;
00733 int midi_output_ports = -1;
00734 int celt_encoding = -1;
00735 int opus_encoding = -1;
00736 bool monitor = false;
00737 int network_latency = 5;
00738 const JSList* node;
00739 const jack_driver_param_t* param;
00740 bool auto_save = false;
00741
00742
00743 const char* default_udp_port = getenv("JACK_NETJACK_PORT");
00744 udp_port = (default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT;
00745
00746
00747 const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST");
00748 strcpy(multicast_ip, (default_multicast_ip) ? default_multicast_ip : DEFAULT_MULTICAST_IP);
00749
00750 for (node = params; node; node = jack_slist_next(node)) {
00751 param = (const jack_driver_param_t*) node->data;
00752 switch (param->character)
00753 {
00754 case 'a' :
00755 assert(strlen(param->value.str) < 32);
00756 strcpy(multicast_ip, param->value.str);
00757 break;
00758 case 'p':
00759 udp_port = param->value.ui;
00760 break;
00761 case 'M':
00762 mtu = param->value.i;
00763 break;
00764 case 'C':
00765 audio_capture_ports = param->value.i;
00766 break;
00767 case 'P':
00768 audio_playback_ports = param->value.i;
00769 break;
00770 case 'i':
00771 midi_input_ports = param->value.i;
00772 break;
00773 case 'o':
00774 midi_output_ports = param->value.i;
00775 break;
00776 #if HAVE_CELT
00777 case 'c':
00778 celt_encoding = param->value.i;
00779 break;
00780 #endif
00781 #if HAVE_OPUS
00782 case 'O':
00783 opus_encoding = param->value.i;
00784 break;
00785 #endif
00786 case 'n' :
00787 strncpy(net_name, param->value.str, JACK_CLIENT_NAME_SIZE);
00788 break;
00789 case 's':
00790 auto_save = true;
00791 break;
00792
00793
00794
00795
00796
00797
00798 case 'l' :
00799 network_latency = param->value.ui;
00800 if (network_latency > NETWORK_MAX_LATENCY) {
00801 printf("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY);
00802 return NULL;
00803 }
00804 break;
00805 }
00806 }
00807
00808 try {
00809
00810 Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver(
00811 new Jack::JackNetDriver("system", "net_pcm", engine, table, multicast_ip, udp_port, mtu,
00812 midi_input_ports, midi_output_ports,
00813 net_name, transport_sync,
00814 network_latency, celt_encoding, opus_encoding, auto_save));
00815 if (driver->Open(period_size, sample_rate, 1, 1, audio_capture_ports, audio_playback_ports, monitor, "from_master_", "to_master_", 0, 0) == 0) {
00816 return driver;
00817 } else {
00818 delete driver;
00819 return NULL;
00820 }
00821
00822 } catch (...) {
00823 return NULL;
00824 }
00825 }
00826
00827 #ifdef __cplusplus
00828 }
00829 #endif
00830 }