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