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