00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "JackNetAdapter.h"
00020 #include "JackException.h"
00021 #include "JackServer.h"
00022 #include "JackEngineControl.h"
00023
00024 namespace Jack
00025 {
00026 JackNetAdapter::JackNetAdapter ( jack_client_t* jack_client, jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params )
00027 : JackAudioAdapterInterface ( buffer_size, sample_rate ), JackNetSlaveInterface(), fThread ( this )
00028 {
00029 jack_log ( "JackNetAdapter::JackNetAdapter" );
00030
00031
00032
00033
00034
00035 fMulticastIP = new char[16];
00036 strcpy ( fMulticastIP, DEFAULT_MULTICAST_IP );
00037 uint port = DEFAULT_PORT;
00038 GetHostName ( fParams.fName, JACK_CLIENT_NAME_SIZE );
00039 fSocket.GetName ( fParams.fSlaveNetName );
00040 fParams.fMtu = 1500;
00041 fParams.fTransportSync = 0;
00042 fParams.fSendAudioChannels = 2;
00043 fParams.fReturnAudioChannels = 2;
00044 fParams.fSendMidiChannels = 0;
00045 fParams.fReturnMidiChannels = 0;
00046 fParams.fSampleRate = sample_rate;
00047 fParams.fPeriodSize = buffer_size;
00048 fParams.fSlaveSyncMode = 1;
00049 fParams.fNetworkMode = 'n';
00050 fJackClient = jack_client;
00051
00052
00053 const JSList* node;
00054 const jack_driver_param_t* param;
00055 for ( node = params; node; node = jack_slist_next ( node ) )
00056 {
00057 param = ( const jack_driver_param_t* ) node->data;
00058 switch ( param->character )
00059 {
00060 case 'a' :
00061 if ( strlen ( param->value.str ) < 16 )
00062 strcpy ( fMulticastIP, param->value.str );
00063 else
00064 jack_error ( "Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP );
00065 break;
00066 case 'p' :
00067 fSocket.SetPort ( param->value.ui );
00068 break;
00069 case 'M' :
00070 fParams.fMtu = param->value.i;
00071 break;
00072 case 'C' :
00073 fParams.fSendAudioChannels = param->value.i;
00074 break;
00075 case 'P' :
00076 fParams.fReturnAudioChannels = param->value.i;
00077 break;
00078 case 'n' :
00079 strncpy ( fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE );
00080 break;
00081 case 't' :
00082
00083 break;
00084 case 'm' :
00085 if ( strcmp ( param->value.str, "normal" ) == 0 )
00086 fParams.fNetworkMode = 'n';
00087 else if ( strcmp ( param->value.str, "slow" ) == 0 )
00088 fParams.fNetworkMode = 's';
00089 else if ( strcmp ( param->value.str, "fast" ) == 0 )
00090 fParams.fNetworkMode = 'f';
00091 else
00092 jack_error ( "Unknown network mode, using 'normal' mode." );
00093 break;
00094 case 'S' :
00095 fParams.fSlaveSyncMode = 1;
00096 break;
00097 }
00098 }
00099
00100
00101 fSocket.SetPort ( port );
00102 fSocket.SetAddress ( fMulticastIP, port );
00103
00104
00105 SetInputs ( fParams.fSendAudioChannels );
00106 SetOutputs ( fParams.fReturnAudioChannels );
00107
00108
00109 fSoftCaptureBuffer = NULL;
00110 fSoftPlaybackBuffer = NULL;
00111 }
00112
00113 JackNetAdapter::~JackNetAdapter()
00114 {
00115 jack_log ( "JackNetAdapter::~JackNetAdapter" );
00116
00117 int port_index;
00118 if ( fSoftCaptureBuffer )
00119 {
00120 for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
00121 delete[] fSoftCaptureBuffer[port_index];
00122 delete[] fSoftCaptureBuffer;
00123 }
00124 if ( fSoftPlaybackBuffer )
00125 {
00126 for ( port_index = 0; port_index < fPlaybackChannels; port_index++ )
00127 delete[] fSoftPlaybackBuffer[port_index];
00128 delete[] fSoftPlaybackBuffer;
00129 }
00130 }
00131
00132
00133 int JackNetAdapter::Open()
00134 {
00135 jack_log ( "JackNetAdapter::Open" );
00136
00137 jack_info ( "Net adapter started in %s mode %s Master's transport sync.",
00138 ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" );
00139
00140 if ( fThread.StartSync() < 0 )
00141 {
00142 jack_error ( "Cannot start netadapter thread" );
00143 return -1;
00144 }
00145
00146 return 0;
00147 }
00148
00149 int JackNetAdapter::Close()
00150 {
00151 jack_log ( "JackNetAdapter::Close" );
00152
00153 switch ( fThread.GetStatus() )
00154 {
00155
00156 case JackThread::kStarting:
00157 case JackThread::kIniting:
00158 if ( fThread.Kill() < 0 )
00159 {
00160 jack_error ( "Cannot kill thread" );
00161 return -1;
00162 }
00163 break;
00164
00165
00166 case JackThread::kRunning:
00167 if ( fThread.Stop() < 0 )
00168 {
00169 jack_error ( "Cannot stop thread" );
00170 return -1;
00171 }
00172 break;
00173
00174 default:
00175 break;
00176 }
00177 fSocket.Close();
00178 return 0;
00179 }
00180
00181 int JackNetAdapter::SetBufferSize ( jack_nframes_t buffer_size )
00182 {
00183 JackAudioAdapterInterface::SetHostBufferSize ( buffer_size );
00184 return 0;
00185 }
00186
00187
00188 bool JackNetAdapter::Init()
00189 {
00190 jack_log ( "JackNetAdapter::Init" );
00191
00192 int port_index;
00193
00194
00195 if ( !JackNetSlaveInterface::Init() )
00196 return false;
00197
00198
00199 SetParams();
00200
00201
00202 fSoftCaptureBuffer = new sample_t*[fCaptureChannels];
00203 for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
00204 {
00205 fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize];
00206 fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] );
00207 }
00208 fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels];
00209 for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
00210 {
00211 fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize];
00212 fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] );
00213 }
00214
00215
00216 SetAdaptedBufferSize ( fParams.fPeriodSize );
00217 SetAdaptedSampleRate ( fParams.fSampleRate );
00218
00219 if (fThread.AcquireRealTime ( JackServer::fInstance->GetEngineControl()->fPriority - 1 ) < 0) {
00220 jack_error("AcquireRealTime error");
00221 } else {
00222 set_threaded_log_function();
00223 }
00224
00225
00226 SessionParamsDisplay ( &fParams );
00227 return true;
00228 }
00229
00230 bool JackNetAdapter::Execute()
00231 {
00232 try
00233 {
00234
00235 while ( fThread.GetStatus() == JackThread::kRunning )
00236 if ( Process() == SOCKET_ERROR )
00237 return false;
00238 return false;
00239 }
00240 catch ( JackNetException& e )
00241 {
00242 e.PrintMessage();
00243 jack_log ( "NetAdapter is restarted." );
00244 fThread.DropRealTime();
00245 fThread.SetStatus ( JackThread::kIniting );
00246 if ( Init() )
00247 {
00248 fThread.SetStatus ( JackThread::kRunning );
00249 return true;
00250 }
00251 else
00252 return false;
00253 }
00254 }
00255
00256
00257 int JackNetAdapter::DecodeTransportData()
00258 {
00259
00260
00261
00262 if ( fSendTransportData.fNewState && ( fSendTransportData.fState != jack_transport_query ( fJackClient, NULL ) ) )
00263 {
00264 switch ( fSendTransportData.fState )
00265 {
00266 case JackTransportStopped :
00267 jack_transport_stop ( fJackClient );
00268 jack_info ( "NetMaster : transport stops." );
00269 break;
00270
00271 case JackTransportStarting :
00272 jack_transport_reposition ( fJackClient, &fSendTransportData.fPosition );
00273 jack_transport_start ( fJackClient );
00274 jack_info ( "NetMaster : transport starts." );
00275 break;
00276
00277 case JackTransportRolling :
00278
00279
00280
00281 jack_info ( "NetMaster : transport rolls." );
00282 break;
00283 }
00284 }
00285
00286 return 0;
00287 }
00288
00289 int JackNetAdapter::EncodeTransportData()
00290 {
00291
00292 int refnum = -1;
00293 bool conditional = 0;
00294
00295 if ( refnum != fLastTimebaseMaster )
00296 {
00297
00298 if ( refnum == -1 )
00299 {
00300 fReturnTransportData.fTimebaseMaster = RELEASE_TIMEBASEMASTER;
00301 jack_info ( "Sending a timebase master release request." );
00302 }
00303
00304 else
00305 {
00306 fReturnTransportData.fTimebaseMaster = ( conditional ) ? CONDITIONAL_TIMEBASEMASTER : TIMEBASEMASTER;
00307 jack_info ( "Sending a %s timebase master request.", ( conditional ) ? "conditional" : "non-conditional" );
00308 }
00309 fLastTimebaseMaster = refnum;
00310 }
00311 else
00312 fReturnTransportData.fTimebaseMaster = NO_CHANGE;
00313
00314
00315 fReturnTransportData.fState = jack_transport_query ( fJackClient, &fReturnTransportData.fPosition );
00316
00317
00318 fReturnTransportData.fNewState = ( ( fReturnTransportData.fState != fLastTransportState ) &&
00319 ( fReturnTransportData.fState != fSendTransportData.fState ) );
00320 if ( fReturnTransportData.fNewState )
00321 jack_info ( "Sending transport state '%s'.", GetTransportState ( fReturnTransportData.fState ) );
00322 fLastTransportState = fReturnTransportData.fState;
00323
00324 return 0;
00325 }
00326
00327
00328 int JackNetAdapter::DecodeSyncPacket()
00329 {
00330
00331
00332 if ( fParams.fTransportSync )
00333 {
00334
00335 memcpy ( &fSendTransportData, fRxData, sizeof ( net_transport_data_t ) );
00336 if ( DecodeTransportData() < 0 )
00337 return -1;
00338 }
00339
00340
00341 return 0;
00342 }
00343
00344 int JackNetAdapter::EncodeSyncPacket()
00345 {
00346
00347
00348 memset ( fTxData, 0, fPayloadSize );
00349
00350 if ( fParams.fTransportSync )
00351 {
00352 if ( EncodeTransportData() < 0 )
00353 return -1;
00354
00355 memcpy ( fTxData, &fReturnTransportData, sizeof ( net_transport_data_t ) );
00356 }
00357
00358
00359 return 0;
00360 }
00361
00362
00363 int JackNetAdapter::Read()
00364 {
00365
00366
00367 if ( SyncRecv() == SOCKET_ERROR )
00368 return 0;
00369
00370 if ( DecodeSyncPacket() < 0 )
00371 return 0;
00372
00373 return DataRecv();
00374 }
00375
00376 int JackNetAdapter::Write()
00377 {
00378 if ( EncodeSyncPacket() < 0 )
00379 return 0;
00380
00381 if ( SyncSend() == SOCKET_ERROR )
00382 return SOCKET_ERROR;
00383
00384 return DataSend();
00385 }
00386
00387
00388 int JackNetAdapter::Process()
00389 {
00390 bool failure = false;
00391 int port_index;
00392
00393
00394
00395 if ( Read() == SOCKET_ERROR )
00396 return SOCKET_ERROR;
00397
00398
00399 jack_nframes_t time1, time2;
00400 ResampleFactor ( time1, time2 );
00401
00402
00403 for ( port_index = 0; port_index < fCaptureChannels; port_index++ )
00404 {
00405 fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 );
00406 if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize )
00407 failure = true;
00408 }
00409
00410
00411 for ( port_index = 0; port_index < fPlaybackChannels; port_index++ )
00412 {
00413 fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 );
00414 if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize )
00415 failure = true;
00416 }
00417
00418
00419
00420 if ( Write() == SOCKET_ERROR )
00421 return SOCKET_ERROR;
00422
00423
00424 if ( failure )
00425 {
00426 jack_error ( "JackNetAdapter::Execute ringbuffer failure...reset." );
00427 ResetRingBuffers();
00428 }
00429
00430 return true;
00431 }
00432 }
00433
00434
00435 #ifdef __cplusplus
00436 extern "C"
00437 {
00438 #endif
00439
00440 #include "driver_interface.h"
00441 #include "JackAudioAdapter.h"
00442
00443 using namespace Jack;
00444
00445 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
00446 {
00447 jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
00448
00449 strcpy(desc->name, "netadapter");
00450 strcpy(desc->desc, "netjack net <==> audio backend adapter");
00451
00452 desc->nparams = 9;
00453 desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
00454
00455 int i = 0;
00456 strcpy ( desc->params[i].name, "multicast_ip" );
00457 desc->params[i].character = 'a';
00458 desc->params[i].type = JackDriverParamString;
00459 strcpy ( desc->params[i].value.str, DEFAULT_MULTICAST_IP );
00460 strcpy ( desc->params[i].short_desc, "Multicast Address" );
00461 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00462
00463 i++;
00464 strcpy ( desc->params[i].name, "udp_net_port" );
00465 desc->params[i].character = 'p';
00466 desc->params[i].type = JackDriverParamInt;
00467 desc->params[i].value.i = 19000;
00468 strcpy ( desc->params[i].short_desc, "UDP port" );
00469 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00470
00471 i++;
00472 strcpy ( desc->params[i].name, "mtu" );
00473 desc->params[i].character = 'M';
00474 desc->params[i].type = JackDriverParamInt;
00475 desc->params[i].value.i = 1500;
00476 strcpy ( desc->params[i].short_desc, "MTU to the master" );
00477 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00478
00479 i++;
00480 strcpy ( desc->params[i].name, "input_ports" );
00481 desc->params[i].character = 'C';
00482 desc->params[i].type = JackDriverParamInt;
00483 desc->params[i].value.i = 2;
00484 strcpy ( desc->params[i].short_desc, "Number of audio input ports" );
00485 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00486
00487 i++;
00488 strcpy ( desc->params[i].name, "output_ports" );
00489 desc->params[i].character = 'P';
00490 desc->params[i].type = JackDriverParamInt;
00491 desc->params[i].value.i = 2;
00492 strcpy ( desc->params[i].short_desc, "Number of audio output ports" );
00493 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00494
00495 i++;
00496 strcpy ( desc->params[i].name, "client_name" );
00497 desc->params[i].character = 'n';
00498 desc->params[i].type = JackDriverParamString;
00499 strcpy ( desc->params[i].value.str, "'hostname'" );
00500 strcpy ( desc->params[i].short_desc, "Name of the jack client" );
00501 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00502
00503 i++;
00504 strcpy ( desc->params[i].name, "transport_sync" );
00505 desc->params[i].character = 't';
00506 desc->params[i].type = JackDriverParamUInt;
00507 desc->params[i].value.ui = 1U;
00508 strcpy ( desc->params[i].short_desc, "Sync transport with master's" );
00509 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00510
00511 i++;
00512 strcpy ( desc->params[i].name, "mode" );
00513 desc->params[i].character = 'm';
00514 desc->params[i].type = JackDriverParamString;
00515 strcpy ( desc->params[i].value.str, "normal" );
00516 strcpy ( desc->params[i].short_desc, "Slow, Normal or Fast mode." );
00517 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00518
00519 i++;
00520 strcpy ( desc->params[i].name, "sync_mode" );
00521 desc->params[i].character = 'S';
00522 desc->params[i].type = JackDriverParamString;
00523 strcpy ( desc->params[i].value.str, "" );
00524 strcpy ( desc->params[i].short_desc, "Sync mode (same as driver's sync mode) ?" );
00525 strcpy ( desc->params[i].long_desc, desc->params[i].short_desc );
00526
00527 return desc;
00528 }
00529
00530 SERVER_EXPORT int jack_internal_initialize ( jack_client_t* jack_client, const JSList* params )
00531 {
00532 jack_log ( "Loading netadapter" );
00533
00534 Jack::JackAudioAdapter* adapter;
00535 jack_nframes_t buffer_size = jack_get_buffer_size ( jack_client );
00536 jack_nframes_t sample_rate = jack_get_sample_rate ( jack_client );
00537
00538 try {
00539
00540 adapter = new Jack::JackAudioAdapter ( jack_client, new Jack::JackNetAdapter ( jack_client, buffer_size, sample_rate, params ) );
00541 assert ( adapter );
00542
00543 if ( adapter->Open() == 0 )
00544 return 0;
00545 else
00546 {
00547 delete adapter;
00548 return 1;
00549 }
00550
00551 } catch (...) {
00552 return 1;
00553 }
00554 }
00555
00556 SERVER_EXPORT int jack_initialize ( jack_client_t* jack_client, const char* load_init )
00557 {
00558 JSList* params = NULL;
00559 jack_driver_desc_t *desc = jack_get_descriptor();
00560
00561 JackArgParser parser(load_init);
00562 if (parser.GetArgc() > 0)
00563 parser.ParseParams (desc, ¶ms);
00564
00565 int res = jack_internal_initialize(jack_client, params);
00566 parser.FreeParams(params);
00567 return res;
00568 }
00569
00570 SERVER_EXPORT void jack_finish ( void* arg )
00571 {
00572 Jack::JackAudioAdapter* adapter = static_cast<Jack::JackAudioAdapter*> ( arg );
00573
00574 if (adapter) {
00575 jack_log ( "Unloading netadapter" );
00576 adapter->Close();
00577 delete adapter;
00578 }
00579 }
00580
00581 #ifdef __cplusplus
00582 }
00583 #endif