00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "JackNetManager.h"
00020 #include "JackArgParser.h"
00021 #include "JackServerGlobals.h"
00022 #include "JackLockedEngine.h"
00023
00024 using namespace std;
00025
00026 namespace Jack
00027 {
00028
00029
00030 JackNetMaster::JackNetMaster(JackNetSocket& socket, session_params_t& params, const char* multicast_ip)
00031 : JackNetMasterInterface(params, socket, multicast_ip)
00032 {
00033 jack_log("JackNetMaster::JackNetMaster");
00034
00035
00036 fClientName = const_cast<char*>(fParams.fName);
00037 fJackClient = NULL;
00038 fSendTransportData.fState = -1;
00039 fReturnTransportData.fState = -1;
00040 fLastTransportState = -1;
00041 int port_index;
00042
00043
00044 fAudioCapturePorts = new jack_port_t* [fParams.fSendAudioChannels];
00045 for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) {
00046 fAudioCapturePorts[port_index] = NULL;
00047 }
00048
00049 fAudioPlaybackPorts = new jack_port_t* [fParams.fReturnAudioChannels];
00050 for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) {
00051 fAudioPlaybackPorts[port_index] = NULL;
00052 }
00053
00054
00055 fMidiCapturePorts = new jack_port_t* [fParams.fSendMidiChannels];
00056 for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) {
00057 fMidiCapturePorts[port_index] = NULL;
00058 }
00059
00060 fMidiPlaybackPorts = new jack_port_t* [fParams.fReturnMidiChannels];
00061 for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) {
00062 fMidiPlaybackPorts[port_index] = NULL;
00063 }
00064
00065
00066 #ifdef JACK_MONITOR
00067 fPeriodUsecs = (int)(1000000.f * ((float) fParams.fPeriodSize / (float) fParams.fSampleRate));
00068 string plot_name;
00069 plot_name = string(fParams.fName);
00070 plot_name += string("_master");
00071 plot_name += string((fParams.fSlaveSyncMode) ? "_sync" : "_async");
00072 plot_name += string("_latency");
00073 fNetTimeMon = new JackGnuPlotMonitor<float>(128, 4, plot_name);
00074 string net_time_mon_fields[] =
00075 {
00076 string("sync send"),
00077 string("end of send"),
00078 string("sync recv"),
00079 string("end of cycle")
00080 };
00081 string net_time_mon_options[] =
00082 {
00083 string("set xlabel \"audio cycles\""),
00084 string("set ylabel \"% of audio cycle\"")
00085 };
00086 fNetTimeMon->SetPlotFile(net_time_mon_options, 2, net_time_mon_fields, 4);
00087 #endif
00088 }
00089
00090 JackNetMaster::~JackNetMaster()
00091 {
00092 jack_log("JackNetMaster::~JackNetMaster ID = %u", fParams.fID);
00093
00094 if (fJackClient) {
00095 jack_deactivate(fJackClient);
00096 FreePorts();
00097 jack_client_close(fJackClient);
00098 }
00099 delete[] fAudioCapturePorts;
00100 delete[] fAudioPlaybackPorts;
00101 delete[] fMidiCapturePorts;
00102 delete[] fMidiPlaybackPorts;
00103 #ifdef JACK_MONITOR
00104 fNetTimeMon->Save();
00105 delete fNetTimeMon;
00106 #endif
00107 }
00108
00109 bool JackNetMaster::Init(bool auto_connect)
00110 {
00111
00112 if (!JackNetMasterInterface::Init()) {
00113 jack_error("JackNetMasterInterface::Init() error...");
00114 return false;
00115 }
00116
00117
00118 if (!SetParams()) {
00119 jack_error("SetParams error...");
00120 return false;
00121 }
00122
00123
00124 jack_status_t status;
00125 if ((fJackClient = jack_client_open(fClientName, JackNullOption, &status, NULL)) == NULL) {
00126 jack_error("Can't open a new JACK client");
00127 return false;
00128 }
00129
00130 if (jack_set_process_callback(fJackClient, SetProcess, this) < 0) {
00131 goto fail;
00132 }
00133
00134 if (jack_set_buffer_size_callback(fJackClient, SetBufferSize, this) < 0) {
00135 goto fail;
00136 }
00137
00138 if (AllocPorts() != 0) {
00139 jack_error("Can't allocate JACK ports");
00140 goto fail;
00141 }
00142
00143
00144 fRunning = true;
00145
00146
00147 if (jack_activate(fJackClient) != 0) {
00148 jack_error("Can't activate JACK client");
00149 goto fail;
00150 }
00151
00152 if (auto_connect) {
00153 ConnectPorts();
00154 }
00155 jack_info("New NetMaster started");
00156 return true;
00157
00158 fail:
00159 FreePorts();
00160 jack_client_close(fJackClient);
00161 fJackClient = NULL;
00162 return false;
00163 }
00164
00165
00166 int JackNetMaster::AllocPorts()
00167 {
00168 int i;
00169 char name[24];
00170 jack_nframes_t port_latency = jack_get_buffer_size(fJackClient);
00171 jack_latency_range_t range;
00172
00173 jack_log("JackNetMaster::AllocPorts");
00174
00175
00176 for (i = 0; i < fParams.fSendAudioChannels; i++) {
00177 snprintf(name, sizeof(name), "to_slave_%d", i+1);
00178 if ((fAudioCapturePorts[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0)) == NULL)
00179 return -1;
00180
00181 range.min = range.max = 0;
00182 jack_port_set_latency_range(fAudioCapturePorts[i], JackCaptureLatency, &range);
00183 }
00184
00185 for (i = 0; i < fParams.fReturnAudioChannels; i++) {
00186 snprintf(name, sizeof(name), "from_slave_%d", i+1);
00187 if ((fAudioPlaybackPorts[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL)
00188 return -1;
00189
00190 range.min = range.max = fParams.fNetworkLatency * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency;
00191 jack_port_set_latency_range(fAudioPlaybackPorts[i], JackPlaybackLatency, &range);
00192 }
00193
00194
00195 for (i = 0; i < fParams.fSendMidiChannels; i++) {
00196 snprintf(name, sizeof(name), "midi_to_slave_%d", i+1);
00197 if ((fMidiCapturePorts[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0)) == NULL)
00198 return -1;
00199
00200 range.min = range.max = 0;
00201 jack_port_set_latency_range(fMidiCapturePorts[i], JackCaptureLatency, &range);
00202 }
00203
00204 for (i = 0; i < fParams.fReturnMidiChannels; i++) {
00205 snprintf(name, sizeof(name), "midi_from_slave_%d", i+1);
00206 if ((fMidiPlaybackPorts[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0)) == NULL)
00207 return -1;
00208
00209 range.min = range.max = fParams.fNetworkLatency * port_latency + (fParams.fSlaveSyncMode) ? 0 : port_latency;
00210 jack_port_set_latency_range(fMidiPlaybackPorts[i], JackPlaybackLatency, &range);
00211 }
00212 return 0;
00213 }
00214
00215 void JackNetMaster::ConnectPorts()
00216 {
00217 const char **ports;
00218
00219 ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput);
00220 if (ports != NULL) {
00221 for (int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) {
00222 jack_connect(fJackClient, ports[i], jack_port_name(fAudioCapturePorts[i]));
00223 }
00224 free(ports);
00225 }
00226
00227 ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
00228 if (ports != NULL) {
00229 for (int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) {
00230 jack_connect(fJackClient, jack_port_name(fAudioPlaybackPorts[i]), ports[i]);
00231 }
00232 free(ports);
00233 }
00234 }
00235
00236 void JackNetMaster::FreePorts()
00237 {
00238 jack_log("JackNetMaster::FreePorts ID = %u", fParams.fID);
00239
00240 int port_index;
00241 for (port_index = 0; port_index < fParams.fSendAudioChannels; port_index++) {
00242 if (fAudioCapturePorts[port_index]) {
00243 jack_port_unregister(fJackClient, fAudioCapturePorts[port_index]);
00244 }
00245 }
00246 for (port_index = 0; port_index < fParams.fReturnAudioChannels; port_index++) {
00247 if (fAudioPlaybackPorts[port_index]) {
00248 jack_port_unregister(fJackClient, fAudioPlaybackPorts[port_index]);
00249 }
00250 }
00251 for (port_index = 0; port_index < fParams.fSendMidiChannels; port_index++) {
00252 if (fMidiCapturePorts[port_index]) {
00253 jack_port_unregister(fJackClient, fMidiCapturePorts[port_index]);
00254 }
00255 }
00256 for (port_index = 0; port_index < fParams.fReturnMidiChannels; port_index++) {
00257 if (fMidiPlaybackPorts[port_index]) {
00258 jack_port_unregister(fJackClient, fMidiPlaybackPorts[port_index]);
00259 }
00260 }
00261 }
00262
00263
00264 void JackNetMaster::EncodeTransportData()
00265 {
00266
00267
00268 fSendTransportData.fTimebaseMaster = NO_CHANGE;
00269
00270
00271 fSendTransportData.fState = static_cast<uint>(jack_transport_query(fJackClient, &fSendTransportData.fPosition));
00272
00273
00274 fSendTransportData.fNewState = ((fSendTransportData.fState != fLastTransportState) && (fSendTransportData.fState != fReturnTransportData.fState));
00275 if (fSendTransportData.fNewState) {
00276 jack_info("Sending '%s' to '%s' frame = %ld", GetTransportState(fSendTransportData.fState), fParams.fName, fSendTransportData.fPosition.frame);
00277 }
00278 fLastTransportState = fSendTransportData.fState;
00279 }
00280
00281 void JackNetMaster::DecodeTransportData()
00282 {
00283
00284 if (fReturnTransportData.fTimebaseMaster != NO_CHANGE) {
00285
00286 int timebase = 0;
00287 switch (fReturnTransportData.fTimebaseMaster)
00288 {
00289 case RELEASE_TIMEBASEMASTER :
00290 timebase = jack_release_timebase(fJackClient);
00291 if (timebase < 0) {
00292 jack_error("Can't release timebase master");
00293 } else {
00294 jack_info("'%s' isn't the timebase master anymore", fParams.fName);
00295 }
00296 break;
00297
00298 case TIMEBASEMASTER :
00299 timebase = jack_set_timebase_callback(fJackClient, 0, SetTimebaseCallback, this);
00300 if (timebase < 0) {
00301 jack_error("Can't set a new timebase master");
00302 } else {
00303 jack_info("'%s' is the new timebase master", fParams.fName);
00304 }
00305 break;
00306
00307 case CONDITIONAL_TIMEBASEMASTER :
00308 timebase = jack_set_timebase_callback(fJackClient, 1, SetTimebaseCallback, this);
00309 if (timebase != EBUSY) {
00310 if (timebase < 0)
00311 jack_error("Can't set a new timebase master");
00312 else
00313 jack_info("'%s' is the new timebase master", fParams.fName);
00314 }
00315 break;
00316 }
00317 }
00318
00319
00320 if (fReturnTransportData.fNewState && (fReturnTransportData.fState != jack_transport_query(fJackClient, NULL))) {
00321
00322 switch (fReturnTransportData.fState)
00323 {
00324 case JackTransportStopped :
00325 jack_transport_stop(fJackClient);
00326 jack_info("'%s' stops transport", fParams.fName);
00327 break;
00328
00329 case JackTransportStarting :
00330 if (jack_transport_reposition(fJackClient, &fReturnTransportData.fPosition) == EINVAL)
00331 jack_error("Can't set new position");
00332 jack_transport_start(fJackClient);
00333 jack_info("'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame);
00334 break;
00335
00336 case JackTransportNetStarting :
00337 jack_info("'%s' is ready to roll...", fParams.fName);
00338 break;
00339
00340 case JackTransportRolling :
00341 jack_info("'%s' is rolling", fParams.fName);
00342 break;
00343 }
00344 }
00345 }
00346
00347 void JackNetMaster::SetTimebaseCallback(jack_transport_state_t state, jack_nframes_t nframes, jack_position_t* pos, int new_pos, void* arg)
00348 {
00349 static_cast<JackNetMaster*>(arg)->TimebaseCallback(pos);
00350 }
00351
00352 void JackNetMaster::TimebaseCallback(jack_position_t* pos)
00353 {
00354 pos->bar = fReturnTransportData.fPosition.bar;
00355 pos->beat = fReturnTransportData.fPosition.beat;
00356 pos->tick = fReturnTransportData.fPosition.tick;
00357 pos->bar_start_tick = fReturnTransportData.fPosition.bar_start_tick;
00358 pos->beats_per_bar = fReturnTransportData.fPosition.beats_per_bar;
00359 pos->beat_type = fReturnTransportData.fPosition.beat_type;
00360 pos->ticks_per_beat = fReturnTransportData.fPosition.ticks_per_beat;
00361 pos->beats_per_minute = fReturnTransportData.fPosition.beats_per_minute;
00362 }
00363
00364
00365
00366 bool JackNetMaster::IsSlaveReadyToRoll()
00367 {
00368 return (fReturnTransportData.fState == JackTransportNetStarting);
00369 }
00370
00371 int JackNetMaster::SetBufferSize(jack_nframes_t nframes, void* arg)
00372 {
00373 JackNetMaster* obj = static_cast<JackNetMaster*>(arg);
00374 if (nframes != obj->fParams.fPeriodSize) {
00375 jack_error("Cannot handle buffer size change, so JackNetMaster proxy will be removed...");
00376 obj->Exit();
00377 }
00378 return 0;
00379 }
00380
00381
00382 int JackNetMaster::SetProcess(jack_nframes_t nframes, void* arg)
00383 {
00384 try {
00385 return static_cast<JackNetMaster*>(arg)->Process();
00386 } catch (JackNetException& e) {
00387 return 0;
00388 }
00389 }
00390
00391 int JackNetMaster::Process()
00392 {
00393 int res;
00394
00395 if (!fRunning) {
00396 return 0;
00397 }
00398
00399 #ifdef JACK_MONITOR
00400 jack_time_t begin_time = GetMicroSeconds();
00401 fNetTimeMon->New();
00402 #endif
00403
00404
00405 for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) {
00406 fNetMidiCaptureBuffer->SetBuffer(midi_port_index,
00407 static_cast<JackMidiBuffer*>(jack_port_get_buffer(fMidiCapturePorts[midi_port_index],
00408 fParams.fPeriodSize)));
00409 }
00410 for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) {
00411
00412 #ifdef OPTIMIZED_PROTOCOL
00413 if (fNetAudioCaptureBuffer->GetConnected(audio_port_index)) {
00414
00415 fNetAudioCaptureBuffer->SetBuffer(audio_port_index,
00416 ((jack_port_connected(fAudioCapturePorts[audio_port_index]) > 0)
00417 ? static_cast<sample_t*>(jack_port_get_buffer(fAudioCapturePorts[audio_port_index], fParams.fPeriodSize))
00418 : NULL));
00419 } else {
00420 fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL);
00421 }
00422 #else
00423 fNetAudioCaptureBuffer->SetBuffer(audio_port_index,
00424 static_cast<sample_t*>(jack_port_get_buffer(fAudioCapturePorts[audio_port_index],
00425 fParams.fPeriodSize)));
00426 #endif
00427
00428 }
00429
00430 for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) {
00431 fNetMidiPlaybackBuffer->SetBuffer(midi_port_index,
00432 static_cast<JackMidiBuffer*>(jack_port_get_buffer(fMidiPlaybackPorts[midi_port_index],
00433 fParams.fPeriodSize)));
00434 }
00435 for (int audio_port_index = 0; audio_port_index < fParams.fReturnAudioChannels; audio_port_index++) {
00436
00437 #ifdef OPTIMIZED_PROTOCOL
00438 sample_t* out = (jack_port_connected(fAudioPlaybackPorts[audio_port_index]) > 0)
00439 ? static_cast<sample_t*>(jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index], fParams.fPeriodSize))
00440 : NULL;
00441 if (out) {
00442 memset(out, 0, sizeof(float) * fParams.fPeriodSize);
00443 }
00444 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out);
00445 #else
00446 sample_t* out = static_cast<sample_t*>(jack_port_get_buffer(fAudioPlaybackPorts[audio_port_index], fParams.fPeriodSize));
00447 if (out) {
00448 memset(out, 0, sizeof(float) * fParams.fPeriodSize);
00449 }
00450 fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, out)));
00451 #endif
00452 }
00453
00454 if (IsSynched()) {
00455
00456
00457 EncodeSyncPacket();
00458
00459 if (SyncSend() == SOCKET_ERROR) {
00460 return SOCKET_ERROR;
00461 }
00462
00463 #ifdef JACK_MONITOR
00464 fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
00465 #endif
00466
00467
00468 if (DataSend() == SOCKET_ERROR) {
00469 return SOCKET_ERROR;
00470 }
00471
00472 #ifdef JACK_MONITOR
00473 fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
00474 #endif
00475
00476 } else {
00477 jack_error("Connection is not synched, skip cycle...");
00478 }
00479
00480
00481 res = SyncRecv();
00482 if ((res == 0) || (res == SOCKET_ERROR)) {
00483 return res;
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 #ifdef JACK_MONITOR
00507 fNetTimeMon->Add((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
00508 #endif
00509
00510
00511 DecodeSyncPacket();
00512
00513
00514 res = DataRecv();
00515 if ((res == 0) || (res == SOCKET_ERROR)) {
00516 return res;
00517 } else if (res == NET_PACKET_ERROR) {
00518
00519 JackServerGlobals::fInstance->GetEngine()->NotifyXRun(GetMicroSeconds(), 0);
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 #ifdef JACK_MONITOR
00543 fNetTimeMon->AddLast((((float)(GetMicroSeconds() - begin_time)) / (float) fPeriodUsecs) * 100.f);
00544 #endif
00545 return 0;
00546 }
00547
00548
00549
00550 JackNetMasterManager::JackNetMasterManager(jack_client_t* client, const JSList* params) : fSocket()
00551 {
00552 jack_log("JackNetMasterManager::JackNetMasterManager");
00553
00554 fManagerClient = client;
00555 fManagerName = jack_get_client_name(fManagerClient);
00556 fGlobalID = 0;
00557 fRunning = true;
00558 fAutoConnect = false;
00559
00560 const JSList* node;
00561 const jack_driver_param_t* param;
00562
00563
00564 const char* default_udp_port = getenv("JACK_NETJACK_PORT");
00565 fSocket.SetPort((default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT);
00566
00567 const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST");
00568 if (default_multicast_ip) {
00569 strcpy(fMulticastIP, default_multicast_ip);
00570 } else {
00571 strcpy(fMulticastIP, DEFAULT_MULTICAST_IP);
00572 }
00573
00574 for (node = params; node; node = jack_slist_next(node)) {
00575
00576 param = (const jack_driver_param_t*) node->data;
00577 switch (param->character)
00578 {
00579 case 'a' :
00580 if (strlen(param->value.str) < 32) {
00581 strcpy(fMulticastIP, param->value.str);
00582 } else {
00583 jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP);
00584 }
00585 break;
00586
00587 case 'p':
00588 fSocket.SetPort(param->value.ui);
00589 break;
00590
00591 case 'c':
00592 fAutoConnect = param->value.i;
00593 break;
00594 }
00595 }
00596
00597
00598 jack_set_sync_callback(fManagerClient, SetSyncCallback, this);
00599
00600
00601 if (jack_activate(fManagerClient) != 0) {
00602 jack_error("Can't activate the NetManager client, transport disabled");
00603 }
00604
00605
00606 if (jack_client_create_thread(fManagerClient, &fManagerThread, 0, 0, NetManagerThread, this)) {
00607 jack_error("Can't create the NetManager control thread");
00608 }
00609 }
00610
00611 JackNetMasterManager::~JackNetMasterManager()
00612 {
00613 jack_log("JackNetMasterManager::~JackNetMasterManager");
00614 jack_info("Exiting NetManager...");
00615 fRunning = false;
00616 jack_client_kill_thread(fManagerClient, fManagerThread);
00617 master_list_t::iterator it;
00618 for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
00619 delete(*it);
00620 }
00621 fSocket.Close();
00622 SocketAPIEnd();
00623 }
00624
00625 int JackNetMasterManager::CountIO(int flags)
00626 {
00627 const char **ports;
00628 int count = 0;
00629 jack_port_t* port;
00630
00631 ports = jack_get_ports(fManagerClient, NULL, NULL, flags);
00632 if (ports != NULL) {
00633 while (ports[count]
00634 && (port = jack_port_by_name(fManagerClient, ports[count]))
00635 && (strcmp(jack_port_type(port), JACK_DEFAULT_AUDIO_TYPE) == 0)) {
00636 count++;
00637 }
00638 free(ports);
00639 }
00640 return count;
00641 }
00642
00643 int JackNetMasterManager::SetSyncCallback(jack_transport_state_t state, jack_position_t* pos, void* arg)
00644 {
00645 return static_cast<JackNetMasterManager*>(arg)->SyncCallback(state, pos);
00646 }
00647
00648 int JackNetMasterManager::SyncCallback(jack_transport_state_t state, jack_position_t* pos)
00649 {
00650
00651 int ret = 1;
00652 master_list_it_t it;
00653 for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
00654 if (!(*it)->IsSlaveReadyToRoll()) {
00655 ret = 0;
00656 }
00657 }
00658 jack_log("JackNetMasterManager::SyncCallback returns '%s'", (ret) ? "true" : "false");
00659 return ret;
00660 }
00661
00662 void* JackNetMasterManager::NetManagerThread(void* arg)
00663 {
00664 JackNetMasterManager* master_manager = static_cast<JackNetMasterManager*>(arg);
00665 jack_info("Starting Jack NetManager");
00666 jack_info("Listening on '%s:%d'", master_manager->fMulticastIP, master_manager->fSocket.GetPort());
00667 master_manager->Run();
00668 return NULL;
00669 }
00670
00671 void JackNetMasterManager::Run()
00672 {
00673 jack_log("JackNetMasterManager::Run");
00674
00675 int attempt = 0;
00676
00677
00678 session_params_t host_params;
00679 int rx_bytes = 0;
00680 JackNetMaster* net_master;
00681
00682
00683 if (SocketAPIInit() < 0) {
00684 jack_error("Can't init Socket API, exiting...");
00685 return;
00686 }
00687
00688
00689 if (fSocket.NewSocket() == SOCKET_ERROR) {
00690 jack_error("Can't create NetManager input socket : %s", StrError(NET_ERROR_CODE));
00691 return;
00692 }
00693
00694
00695 if (fSocket.Bind() == SOCKET_ERROR) {
00696 jack_error("Can't bind NetManager socket : %s", StrError(NET_ERROR_CODE));
00697 fSocket.Close();
00698 return;
00699 }
00700
00701
00702 if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) {
00703 jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE));
00704 }
00705
00706
00707 if (fSocket.SetLocalLoop() == SOCKET_ERROR) {
00708 jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE));
00709 }
00710
00711
00712 if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) {
00713 jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE));
00714 }
00715
00716
00717 do
00718 {
00719 session_params_t net_params;
00720 rx_bytes = fSocket.CatchHost(&net_params, sizeof(session_params_t), 0);
00721 SessionParamsNToH(&net_params, &host_params);
00722 if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) {
00723 jack_error("Error in receive : %s", StrError(NET_ERROR_CODE));
00724 if (++attempt == 10) {
00725 jack_error("Can't receive on the socket, exiting net manager");
00726 return;
00727 }
00728 }
00729
00730 if (rx_bytes == sizeof(session_params_t)) {
00731 switch (GetPacketType (&host_params))
00732 {
00733 case SLAVE_AVAILABLE:
00734 if ((net_master = InitMaster(host_params))) {
00735 SessionParamsDisplay(&net_master->fParams);
00736 } else {
00737 jack_error("Can't init new NetMaster...");
00738 }
00739 jack_info("Waiting for a slave...");
00740 break;
00741 case KILL_MASTER:
00742 if (KillMaster(&host_params)) {
00743 jack_info("Waiting for a slave...");
00744 }
00745 break;
00746 default:
00747 break;
00748 }
00749 }
00750 }
00751 while (fRunning);
00752 }
00753
00754 JackNetMaster* JackNetMasterManager::InitMaster(session_params_t& params)
00755 {
00756 jack_log("JackNetMasterManager::InitMaster, Slave : %s", params.fName);
00757
00758
00759 if (params.fProtocolVersion != MASTER_PROTOCOL) {
00760 jack_error("Error : slave %s is running with a different protocol %d != %d", params.fName, params.fProtocolVersion, MASTER_PROTOCOL);
00761 return NULL;
00762 }
00763
00764
00765 fSocket.GetName(params.fMasterNetName);
00766 params.fID = ++fGlobalID;
00767 params.fSampleRate = jack_get_sample_rate(fManagerClient);
00768 params.fPeriodSize = jack_get_buffer_size(fManagerClient);
00769
00770 if (params.fSendAudioChannels == -1) {
00771 params.fSendAudioChannels = CountIO(JackPortIsPhysical | JackPortIsOutput);
00772 jack_info("Takes physical %d inputs for client", params.fSendAudioChannels);
00773 }
00774
00775 if (params.fReturnAudioChannels == -1) {
00776 params.fReturnAudioChannels = CountIO(JackPortIsPhysical | JackPortIsInput);
00777 jack_info("Takes physical %d outputs for client", params.fReturnAudioChannels);
00778 }
00779
00780
00781 JackNetMaster* master = new JackNetMaster(fSocket, params, fMulticastIP);
00782 if (master->Init(fAutoConnect)) {
00783 fMasterList.push_back(master);
00784 return master;
00785 }
00786 delete master;
00787 return NULL;
00788 }
00789
00790 master_list_it_t JackNetMasterManager::FindMaster(uint32_t id)
00791 {
00792 jack_log("JackNetMasterManager::FindMaster ID = %u", id);
00793
00794 master_list_it_t it;
00795 for (it = fMasterList.begin(); it != fMasterList.end(); it++) {
00796 if ((*it)->fParams.fID == id) {
00797 return it;
00798 }
00799 }
00800 return it;
00801 }
00802
00803 int JackNetMasterManager::KillMaster(session_params_t* params)
00804 {
00805 jack_log("JackNetMasterManager::KillMaster ID = %u", params->fID);
00806
00807 master_list_it_t master = FindMaster(params->fID);
00808 if (master != fMasterList.end()) {
00809 fMasterList.erase(master);
00810 delete *master;
00811 return 1;
00812 }
00813 return 0;
00814 }
00815 }
00816
00817 static Jack::JackNetMasterManager* master_manager = NULL;
00818
00819 #ifdef __cplusplus
00820 extern "C"
00821 {
00822 #endif
00823
00824 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
00825 {
00826 jack_driver_desc_t * desc;
00827 jack_driver_desc_filler_t filler;
00828 jack_driver_param_value_t value;
00829
00830 desc = jack_driver_descriptor_construct("netmanager", JackDriverNone, "netjack multi-cast master component", &filler);
00831
00832 strcpy(value.str, DEFAULT_MULTICAST_IP);
00833 jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL);
00834
00835 value.i = DEFAULT_PORT;
00836 jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL);
00837
00838 value.i = false;
00839 jack_driver_descriptor_add_parameter(desc, &filler, "auto-connect", 'c', JackDriverParamBool, &value, NULL, "Auto connect netmaster to system ports", NULL);
00840
00841 return desc;
00842 }
00843
00844 SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params)
00845 {
00846 if (master_manager) {
00847 jack_error("Master Manager already loaded");
00848 return 1;
00849 } else {
00850 jack_log("Loading Master Manager");
00851 master_manager = new Jack::JackNetMasterManager(jack_client, params);
00852 return (master_manager) ? 0 : 1;
00853 }
00854 }
00855
00856 SERVER_EXPORT int jack_initialize(jack_client_t* jack_client, const char* load_init)
00857 {
00858 JSList* params = NULL;
00859 bool parse_params = true;
00860 int res = 1;
00861 jack_driver_desc_t* desc = jack_get_descriptor();
00862
00863 Jack::JackArgParser parser(load_init);
00864 if (parser.GetArgc() > 0) {
00865 parse_params = parser.ParseParams(desc, ¶ms);
00866 }
00867
00868 if (parse_params) {
00869 res = jack_internal_initialize(jack_client, params);
00870 parser.FreeParams(params);
00871 }
00872 return res;
00873 }
00874
00875 SERVER_EXPORT void jack_finish(void* arg)
00876 {
00877 if (master_manager) {
00878 jack_log ("Unloading Master Manager");
00879 delete master_manager;
00880 master_manager = NULL;
00881 }
00882 }
00883
00884 #ifdef __cplusplus
00885 }
00886 #endif