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