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