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