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