00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef WIN32
00023 #include <malloc.h>
00024 #endif
00025
00026 #include "JackNetOneDriver.h"
00027 #include "JackEngineControl.h"
00028 #include "JackGraphManager.h"
00029 #include "JackWaitThreadedDriver.h"
00030 #include "JackTools.h"
00031 #include "driver_interface.h"
00032
00033 #include "netjack.h"
00034 #include "netjack_packet.h"
00035
00036 #if HAVE_SAMPLERATE
00037 #include "samplerate.h"
00038 #endif
00039
00040 #if HAVE_CELT
00041 #include "celt/celt.h"
00042 #endif
00043
00044 #define MIN(x,y) ((x)<(y) ? (x) : (y))
00045
00046 using namespace std;
00047
00048 namespace Jack
00049 {
00050 JackNetOneDriver::JackNetOneDriver ( const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
00051 int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports,
00052 int sample_rate, int period_size, int resample_factor,
00053 const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig,
00054 int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val )
00055 : JackAudioDriver ( name, alias, engine, table )
00056 {
00057 jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port );
00058
00059 #ifdef WIN32
00060 WSADATA wsa;
00061 int rc = WSAStartup(MAKEWORD(2,0),&wsa);
00062 #endif
00063
00064 netjack_init( & (this->netj),
00065 NULL,
00066 name,
00067 capture_ports,
00068 playback_ports,
00069 midi_input_ports,
00070 midi_output_ports,
00071 sample_rate,
00072 period_size,
00073 port,
00074 transport_sync,
00075 resample_factor,
00076 0,
00077 bitdepth,
00078 use_autoconfig,
00079 latency,
00080 redundancy,
00081 dont_htonl_floats,
00082 always_deadline,
00083 jitter_val);
00084 }
00085
00086 JackNetOneDriver::~JackNetOneDriver()
00087 {
00088
00089 }
00090
00091
00092 int JackNetOneDriver::Open ( jack_nframes_t buffer_size, jack_nframes_t samplerate, bool capturing, bool playing,
00093 int inchannels, int outchannels, bool monitor,
00094 const char* capture_driver_name, const char* playback_driver_name,
00095 jack_nframes_t capture_latency, jack_nframes_t playback_latency )
00096 {
00097 if ( JackAudioDriver::Open ( buffer_size,
00098 samplerate,
00099 capturing,
00100 playing,
00101 inchannels,
00102 outchannels,
00103 monitor,
00104 capture_driver_name,
00105 playback_driver_name,
00106 capture_latency,
00107 playback_latency ) == 0 )
00108 {
00109 fEngineControl->fPeriod = 0;
00110 fEngineControl->fComputation = 500 * 1000;
00111 fEngineControl->fConstraint = 500 * 1000;
00112 return 0;
00113 }
00114 else
00115 {
00116 jack_error( "open fail" );
00117 return -1;
00118 }
00119 }
00120
00121 int JackNetOneDriver::Close()
00122 {
00123 FreePorts();
00124 netjack_release( &netj );
00125 return JackDriver::Close();
00126 }
00127
00128 int JackNetOneDriver::Attach()
00129 {
00130 return 0;
00131 }
00132
00133 int JackNetOneDriver::Detach()
00134 {
00135 return 0;
00136 }
00137
00138 int JackNetOneDriver::AllocPorts()
00139 {
00140 jack_port_id_t port_id;
00141 char buf[64];
00142 unsigned int chn;
00143 int port_flags;
00144
00145
00146
00147
00148
00149 port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
00150
00151 for (chn = 0; chn < netj.capture_channels_audio; chn++) {
00152 snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1);
00153
00154 if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE,
00155 static_cast<JackPortFlags> ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT )
00156 {
00157 jack_error ( "driver: cannot register port for %s", buf );
00158 return -1;
00159 }
00160
00161
00162 netj.capture_ports =
00163 jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id);
00164
00165 if( netj.bitdepth == CELT_MODE ) {
00166 #if HAVE_CELT
00167 #if HAVE_CELT_API_0_7
00168 celt_int32 lookahead;
00169 CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL );
00170 netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) );
00171 #else
00172 celt_int32_t lookahead;
00173 CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL );
00174 netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) );
00175 #endif
00176 celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead );
00177 netj.codec_latency = 2*lookahead;
00178 #endif
00179 } else {
00180 #if HAVE_SAMPLERATE
00181 netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL));
00182 #endif
00183 }
00184 }
00185 for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) {
00186 snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1);
00187
00188 if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE,
00189 static_cast<JackPortFlags> ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT )
00190 {
00191 jack_error ( "driver: cannot register port for %s", buf );
00192 return -1;
00193 }
00194
00195
00196 netj.capture_ports =
00197 jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id);
00198 }
00199
00200 port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
00201
00202 for (chn = 0; chn < netj.playback_channels_audio; chn++) {
00203 snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1);
00204
00205 if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE,
00206 static_cast<JackPortFlags> ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT )
00207 {
00208 jack_error ( "driver: cannot register port for %s", buf );
00209 return -1;
00210 }
00211
00212
00213 netj.playback_ports =
00214 jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id);
00215
00216 if( netj.bitdepth == CELT_MODE ) {
00217 #if HAVE_CELT
00218 #if HAVE_CELT_API_0_7
00219 CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL );
00220 netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
00221 #else
00222 CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL );
00223 netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) );
00224 #endif
00225 #endif
00226 } else {
00227 #if HAVE_SAMPLERATE
00228 netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL));
00229 #endif
00230 }
00231 }
00232 for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) {
00233 snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1);
00234
00235 if ( ( port_id = fGraphManager->AllocatePort ( fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE,
00236 static_cast<JackPortFlags> ( port_flags ), fEngineControl->fBufferSize ) ) == NO_PORT )
00237 {
00238 jack_error ( "driver: cannot register port for %s", buf );
00239 return -1;
00240 }
00241
00242
00243 netj.playback_ports =
00244 jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id);
00245 }
00246 return 0;
00247 }
00248
00249
00250 bool JackNetOneDriver::Initialize()
00251 {
00252 jack_log ( "JackNetOneDriver::Init()" );
00253
00254 if( global_packcache != NULL ) {
00255 FreePorts();
00256 netjack_release( &netj );
00257 }
00258
00259
00260 jack_info ( "NetOne driver started" );
00261 if( netjack_startup( &netj ) ) {
00262 return false;
00263 }
00264
00265
00266 if ( AllocPorts() != 0 )
00267 {
00268 jack_error ( "Can't allocate ports." );
00269 return false;
00270 }
00271
00272
00273
00274
00275 JackAudioDriver::SetBufferSize ( netj.period_size );
00276 JackAudioDriver::SetSampleRate ( netj.sample_rate );
00277
00278 JackDriver::NotifyBufferSize ( netj.period_size );
00279 JackDriver::NotifySampleRate ( netj.sample_rate );
00280
00281
00282 fEngineControl->fTransport.SetNetworkSync ( true );
00283 return true;
00284 }
00285
00286
00287
00288
00289
00290 int JackNetOneDriver::Read()
00291 {
00292 int delay;
00293 delay = netjack_wait( &netj );
00294 if( delay ) {
00295 NotifyXRun(fBeginDateUst, (float) delay);
00296 jack_error( "netxruns... duration: %dms", delay/1000 );
00297 }
00298
00299 if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 )
00300 JackTools::ThrowJackNetException();
00301
00302
00303 JackDriver::CycleTakeBeginTime();
00304
00305 jack_position_t local_trans_pos;
00306 jack_transport_state_t local_trans_state;
00307
00308 unsigned int *packet_buf, *packet_bufX;
00309
00310 if( ! netj.packet_data_valid ) {
00311 jack_log( "data not valid" );
00312 render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats );
00313 return 0;
00314 }
00315 packet_buf = netj.rx_buf;
00316
00317 jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf;
00318
00319 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
00320
00321 netj.reply_port = pkthdr->reply_port;
00322 netj.latency = pkthdr->latency;
00323
00324
00325 if( netj.latency == 0 )
00326 netj.resync_threshold = 0;
00327 else
00328 netj.resync_threshold = MIN( 15, pkthdr->latency-1 );
00329
00330
00331 if (netj.handle_transport_sync) {
00332 #if 1
00333 unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency);
00334
00335
00336
00337
00338 local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos );
00339
00340
00341 switch (pkthdr->transport_state) {
00342 case JackTransportStarting:
00343
00344 if (local_trans_state == JackTransportStopped) {
00345 fEngineControl->fTransport.SetCommand ( TransportCommandStart );
00346
00347
00348 netj.sync_state = 0;
00349 jack_info("locally stopped... starting...");
00350 }
00351
00352 if (local_trans_pos.frame != compensated_tranport_pos)
00353 {
00354 jack_position_t new_pos = local_trans_pos;
00355 new_pos.frame = compensated_tranport_pos + 2*netj.period_size;
00356 new_pos.valid = (jack_position_bits_t) 0;
00357
00358
00359 fEngineControl->fTransport.RequestNewPos ( &new_pos );
00360
00361
00362 netj.sync_state = 0;
00363 jack_info("starting locate to %d", compensated_tranport_pos );
00364 }
00365 break;
00366 case JackTransportStopped:
00367 netj.sync_state = 1;
00368 if (local_trans_pos.frame != (pkthdr->transport_frame)) {
00369 jack_position_t new_pos = local_trans_pos;
00370 new_pos.frame = pkthdr->transport_frame;
00371 new_pos.valid = (jack_position_bits_t)0;
00372 fEngineControl->fTransport.RequestNewPos ( &new_pos );
00373
00374 jack_info("transport is stopped locate to %d", pkthdr->transport_frame);
00375 }
00376 if (local_trans_state != JackTransportStopped)
00377
00378 fEngineControl->fTransport.SetCommand ( TransportCommandStop );
00379 break;
00380 case JackTransportRolling:
00381 netj.sync_state = 1;
00382
00383
00384
00385
00386 if (local_trans_state != JackTransportRolling)
00387 fEngineControl->fTransport.SetState ( JackTransportRolling );
00388
00389 break;
00390
00391 case JackTransportLooping:
00392 break;
00393 }
00394 #endif
00395 }
00396
00397 render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats );
00398 packet_cache_release_packet(global_packcache, netj.expected_framecnt );
00399 return 0;
00400 }
00401
00402 int JackNetOneDriver::Write()
00403 {
00404 int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 );
00405 uint32_t *packet_buf, *packet_bufX;
00406
00407 int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header);
00408 jacknet_packet_header *pkthdr;
00409
00410 packet_buf = (uint32_t *) alloca(packet_size);
00411 pkthdr = (jacknet_packet_header *)packet_buf;
00412
00413 if( netj.running_free ) {
00414 return 0;
00415 }
00416
00417
00418 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
00419
00420 pkthdr->sync_state = syncstate;;
00421 pkthdr->latency = netj.time_to_deadline;
00422
00423 pkthdr->framecnt = netj.expected_framecnt;
00424
00425
00426 render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats );
00427
00428 packet_header_hton(pkthdr);
00429 if (netj.srcaddress_valid)
00430 {
00431 unsigned int r;
00432
00433 #ifdef __APPLE__
00434 static const int flag = 0;
00435 #else
00436 static const int flag = 0;
00437 #endif
00438
00439 if (netj.reply_port)
00440 netj.syncsource_address.sin_port = htons(netj.reply_port);
00441
00442 for( r=0; r<netj.redundancy; r++ )
00443 netjack_sendto(netj.sockfd, (char *)packet_buf, packet_size,
00444 flag, (struct sockaddr*)&(netj.syncsource_address), sizeof(struct sockaddr_in), netj.mtu);
00445 }
00446 return 0;
00447 }
00448
00449 void
00450 JackNetOneDriver::FreePorts ()
00451 {
00452 JSList *node = netj.capture_ports;
00453
00454 while( node != NULL ) {
00455 JSList *this_node = node;
00456 jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data;
00457 node = jack_slist_remove_link( node, this_node );
00458 jack_slist_free_1( this_node );
00459 fGraphManager->ReleasePort( fClientControl.fRefNum, port_id );
00460 }
00461 netj.capture_ports = NULL;
00462
00463 node = netj.playback_ports;
00464 while( node != NULL ) {
00465 JSList *this_node = node;
00466 jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data;
00467 node = jack_slist_remove_link( node, this_node );
00468 jack_slist_free_1( this_node );
00469 fGraphManager->ReleasePort( fClientControl.fRefNum, port_id );
00470 }
00471 netj.playback_ports = NULL;
00472
00473 if( netj.bitdepth == CELT_MODE ) {
00474 #if HAVE_CELT
00475 node = netj.playback_srcs;
00476 while( node != NULL ) {
00477 JSList *this_node = node;
00478 CELTEncoder *enc = (CELTEncoder *) node->data;
00479 node = jack_slist_remove_link( node, this_node );
00480 jack_slist_free_1( this_node );
00481 celt_encoder_destroy( enc );
00482 }
00483 netj.playback_srcs = NULL;
00484
00485 node = netj.capture_srcs;
00486 while( node != NULL ) {
00487 JSList *this_node = node;
00488 CELTDecoder *dec = (CELTDecoder *) node->data;
00489 node = jack_slist_remove_link( node, this_node );
00490 jack_slist_free_1( this_node );
00491 celt_decoder_destroy( dec );
00492 }
00493 netj.capture_srcs = NULL;
00494 #endif
00495 } else {
00496 #if HAVE_SAMPLERATE
00497 node = netj.playback_srcs;
00498 while( node != NULL ) {
00499 JSList *this_node = node;
00500 SRC_STATE *state = (SRC_STATE *) node->data;
00501 node = jack_slist_remove_link( node, this_node );
00502 jack_slist_free_1( this_node );
00503 src_delete( state );
00504 }
00505 netj.playback_srcs = NULL;
00506
00507 node = netj.capture_srcs;
00508 while( node != NULL ) {
00509 JSList *this_node = node;
00510 SRC_STATE *state = (SRC_STATE *) node->data;
00511 node = jack_slist_remove_link( node, this_node );
00512 jack_slist_free_1( this_node );
00513 src_delete( state );
00514 }
00515 netj.capture_srcs = NULL;
00516 #endif
00517 }
00518 }
00519
00520
00521
00522 void
00523 JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
00524 {
00525 uint32_t chn = 0;
00526 JSList *node = capture_ports;
00527 #if HAVE_SAMPLERATE
00528 JSList *src_node = capture_srcs;
00529 #endif
00530
00531 uint32_t *packet_bufX = (uint32_t *)packet_payload;
00532
00533 if( !packet_payload )
00534 return;
00535
00536 while (node != NULL)
00537 {
00538 unsigned int i;
00539 int_float_t val;
00540 #if HAVE_SAMPLERATE
00541 SRC_DATA src;
00542 #endif
00543
00544 jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data;
00545 JackPort *port = fGraphManager->GetPort( port_id );
00546
00547 jack_default_audio_sample_t* buf =
00548 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize);
00549
00550 const char *porttype = port->GetType();
00551
00552 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0)
00553 {
00554 #if HAVE_SAMPLERATE
00555
00556 if (net_period_down != nframes)
00557 {
00558 SRC_STATE *src_state = (SRC_STATE *)src_node->data;
00559 for (i = 0; i < net_period_down; i++)
00560 {
00561 packet_bufX[i] = ntohl (packet_bufX[i]);
00562 }
00563
00564 src.data_in = (float *) packet_bufX;
00565 src.input_frames = net_period_down;
00566
00567 src.data_out = buf;
00568 src.output_frames = nframes;
00569
00570 src.src_ratio = (float) nframes / (float) net_period_down;
00571 src.end_of_input = 0;
00572
00573 src_set_ratio (src_state, src.src_ratio);
00574 src_process (src_state, &src);
00575 src_node = jack_slist_next (src_node);
00576 }
00577 else
00578 #endif
00579 {
00580 if( dont_htonl_floats )
00581 {
00582 memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t));
00583 }
00584 else
00585 {
00586 for (i = 0; i < net_period_down; i++)
00587 {
00588 val.i = packet_bufX[i];
00589 val.i = ntohl (val.i);
00590 buf[i] = val.f;
00591 }
00592 }
00593 }
00594 }
00595 else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0)
00596 {
00597
00598
00599 unsigned int buffer_size_uint32 = net_period_down;
00600 uint32_t * buffer_uint32 = (uint32_t*)packet_bufX;
00601 decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
00602 }
00603 packet_bufX = (packet_bufX + net_period_down);
00604 node = jack_slist_next (node);
00605 chn++;
00606 }
00607 }
00608
00609 void
00610 JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats )
00611 {
00612 uint32_t chn = 0;
00613 JSList *node = playback_ports;
00614 #if HAVE_SAMPLERATE
00615 JSList *src_node = playback_srcs;
00616 #endif
00617
00618 uint32_t *packet_bufX = (uint32_t *) packet_payload;
00619
00620 while (node != NULL)
00621 {
00622 #if HAVE_SAMPLERATE
00623 SRC_DATA src;
00624 #endif
00625 unsigned int i;
00626 int_float_t val;
00627 jack_port_id_t port_id = (jack_port_id_t)(intptr_t) node->data;
00628 JackPort *port = fGraphManager->GetPort( port_id );
00629
00630 jack_default_audio_sample_t* buf =
00631 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize);
00632
00633 const char *porttype = port->GetType();
00634
00635 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0)
00636 {
00637
00638
00639 #if HAVE_SAMPLERATE
00640 if (net_period_up != nframes) {
00641 SRC_STATE *src_state = (SRC_STATE *) src_node->data;
00642 src.data_in = buf;
00643 src.input_frames = nframes;
00644
00645 src.data_out = (float *) packet_bufX;
00646 src.output_frames = net_period_up;
00647
00648 src.src_ratio = (float) net_period_up / (float) nframes;
00649 src.end_of_input = 0;
00650
00651 src_set_ratio (src_state, src.src_ratio);
00652 src_process (src_state, &src);
00653
00654 for (i = 0; i < net_period_up; i++)
00655 {
00656 packet_bufX[i] = htonl (packet_bufX[i]);
00657 }
00658 src_node = jack_slist_next (src_node);
00659 }
00660 else
00661 #endif
00662 {
00663 if( dont_htonl_floats )
00664 {
00665 memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) );
00666 }
00667 else
00668 {
00669 for (i = 0; i < net_period_up; i++)
00670 {
00671 val.f = buf[i];
00672 val.i = htonl (val.i);
00673 packet_bufX[i] = val.i;
00674 }
00675 }
00676 }
00677 }
00678 else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0)
00679 {
00680
00681
00682 unsigned int buffer_size_uint32 = net_period_up;
00683 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
00684 encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
00685 }
00686 packet_bufX = (packet_bufX + net_period_up);
00687 node = jack_slist_next (node);
00688 chn++;
00689 }
00690 }
00691
00692 #if HAVE_CELT
00693
00694 void
00695 JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
00696 {
00697 uint32_t chn = 0;
00698 JSList *node = capture_ports;
00699 JSList *src_node = capture_srcs;
00700
00701 unsigned char *packet_bufX = (unsigned char *)packet_payload;
00702
00703 while (node != NULL)
00704 {
00705 jack_port_id_t port_id = (jack_port_id_t) (intptr_t)node->data;
00706 JackPort *port = fGraphManager->GetPort( port_id );
00707
00708 jack_default_audio_sample_t* buf =
00709 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize);
00710
00711 const char *portname = port->GetType();
00712
00713
00714 if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0)
00715 {
00716
00717
00718 CELTDecoder *decoder = (CELTDecoder *)src_node->data;
00719 if( !packet_payload )
00720 celt_decode_float( decoder, NULL, net_period_down, buf );
00721 else
00722 celt_decode_float( decoder, packet_bufX, net_period_down, buf );
00723
00724 src_node = jack_slist_next (src_node);
00725 }
00726 else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0)
00727 {
00728
00729
00730 unsigned int buffer_size_uint32 = net_period_down / 2;
00731 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
00732 if( packet_payload )
00733 decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
00734 }
00735 packet_bufX = (packet_bufX + net_period_down);
00736 node = jack_slist_next (node);
00737 chn++;
00738 }
00739 }
00740
00741 void
00742 JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
00743 {
00744 uint32_t chn = 0;
00745 JSList *node = playback_ports;
00746 JSList *src_node = playback_srcs;
00747
00748 unsigned char *packet_bufX = (unsigned char *)packet_payload;
00749
00750 while (node != NULL)
00751 {
00752 jack_port_id_t port_id = (jack_port_id_t) (intptr_t) node->data;
00753 JackPort *port = fGraphManager->GetPort( port_id );
00754
00755 jack_default_audio_sample_t* buf =
00756 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_id, fEngineControl->fBufferSize);
00757
00758 const char *portname = port->GetType();
00759
00760 if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0)
00761 {
00762
00763
00764 int encoded_bytes;
00765 float *floatbuf = (float *)alloca (sizeof(float) * nframes );
00766 memcpy( floatbuf, buf, nframes*sizeof(float) );
00767 CELTEncoder *encoder = (CELTEncoder *)src_node->data;
00768 encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up );
00769 if( encoded_bytes != (int)net_period_up )
00770 jack_error( "something in celt changed. netjack needs to be changed to handle this." );
00771 src_node = jack_slist_next( src_node );
00772 }
00773 else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0)
00774 {
00775
00776
00777 unsigned int buffer_size_uint32 = net_period_up / 2;
00778 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
00779 encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
00780 }
00781 packet_bufX = (packet_bufX + net_period_up);
00782 node = jack_slist_next (node);
00783 chn++;
00784 }
00785 }
00786
00787 #endif
00788
00789 void
00790 JackNetOneDriver::render_payload_to_jack_ports (int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats)
00791 {
00792 #if HAVE_CELT
00793 if (bitdepth == CELT_MODE)
00794 render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
00795 else
00796 #endif
00797 render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
00798 }
00799
00800 void
00801 JackNetOneDriver::render_jack_ports_to_payload (int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats)
00802 {
00803 #if HAVE_CELT
00804 if (bitdepth == CELT_MODE)
00805 render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
00806 else
00807 #endif
00808 render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);
00809 }
00810
00811
00812
00813
00814
00815 #ifdef __cplusplus
00816 extern "C"
00817 {
00818 #endif
00819 SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor ()
00820 {
00821 jack_driver_desc_t* desc = ( jack_driver_desc_t* ) calloc ( 1, sizeof ( jack_driver_desc_t ) );
00822 jack_driver_param_desc_t * params;
00823
00824 strcpy ( desc->name, "netone" );
00825 strcpy ( desc->desc, "netjack one slave backend component" );
00826
00827 desc->nparams = 18;
00828 params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
00829
00830 int i = 0;
00831 strcpy (params[i].name, "audio-ins");
00832 params[i].character = 'i';
00833 params[i].type = JackDriverParamUInt;
00834 params[i].value.ui = 2U;
00835 strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)");
00836 strcpy (params[i].long_desc, params[i].short_desc);
00837
00838 i++;
00839 strcpy (params[i].name, "audio-outs");
00840 params[i].character = 'o';
00841 params[i].type = JackDriverParamUInt;
00842 params[i].value.ui = 2U;
00843 strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)");
00844 strcpy (params[i].long_desc, params[i].short_desc);
00845
00846 i++;
00847 strcpy (params[i].name, "midi-ins");
00848 params[i].character = 'I';
00849 params[i].type = JackDriverParamUInt;
00850 params[i].value.ui = 1U;
00851 strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)");
00852 strcpy (params[i].long_desc, params[i].short_desc);
00853
00854 i++;
00855 strcpy (params[i].name, "midi-outs");
00856 params[i].character = 'O';
00857 params[i].type = JackDriverParamUInt;
00858 params[i].value.ui = 1U;
00859 strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)");
00860 strcpy (params[i].long_desc, params[i].short_desc);
00861
00862 i++;
00863 strcpy (params[i].name, "rate");
00864 params[i].character = 'r';
00865 params[i].type = JackDriverParamUInt;
00866 params[i].value.ui = 48000U;
00867 strcpy (params[i].short_desc, "Sample rate");
00868 strcpy (params[i].long_desc, params[i].short_desc);
00869
00870 i++;
00871 strcpy (params[i].name, "period");
00872 params[i].character = 'p';
00873 params[i].type = JackDriverParamUInt;
00874 params[i].value.ui = 1024U;
00875 strcpy (params[i].short_desc, "Frames per period");
00876 strcpy (params[i].long_desc, params[i].short_desc);
00877
00878 i++;
00879 strcpy (params[i].name, "num-periods");
00880 params[i].character = 'n';
00881 params[i].type = JackDriverParamUInt;
00882 params[i].value.ui = 5U;
00883 strcpy (params[i].short_desc,
00884 "Network latency setting in no. of periods");
00885 strcpy (params[i].long_desc, params[i].short_desc);
00886
00887 i++;
00888 strcpy (params[i].name, "listen-port");
00889 params[i].character = 'l';
00890 params[i].type = JackDriverParamUInt;
00891 params[i].value.ui = 3000U;
00892 strcpy (params[i].short_desc,
00893 "The socket port we are listening on for sync packets");
00894 strcpy (params[i].long_desc, params[i].short_desc);
00895
00896 i++;
00897 strcpy (params[i].name, "factor");
00898 params[i].character = 'f';
00899 params[i].type = JackDriverParamUInt;
00900 params[i].value.ui = 1U;
00901 strcpy (params[i].short_desc,
00902 "Factor for sample rate reduction");
00903 strcpy (params[i].long_desc, params[i].short_desc);
00904
00905 i++;
00906 strcpy (params[i].name, "upstream-factor");
00907 params[i].character = 'u';
00908 params[i].type = JackDriverParamUInt;
00909 params[i].value.ui = 0U;
00910 strcpy (params[i].short_desc,
00911 "Factor for sample rate reduction on the upstream");
00912 strcpy (params[i].long_desc, params[i].short_desc);
00913
00914 i++;
00915 strcpy (params[i].name, "celt");
00916 params[i].character = 'c';
00917 params[i].type = JackDriverParamUInt;
00918 params[i].value.ui = 0U;
00919 strcpy (params[i].short_desc,
00920 "sets celt encoding and number of kbits per channel");
00921 strcpy (params[i].long_desc, params[i].short_desc);
00922
00923 i++;
00924 strcpy (params[i].name, "bit-depth");
00925 params[i].character = 'b';
00926 params[i].type = JackDriverParamUInt;
00927 params[i].value.ui = 0U;
00928 strcpy (params[i].short_desc,
00929 "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)");
00930 strcpy (params[i].long_desc, params[i].short_desc);
00931
00932 i++;
00933 strcpy (params[i].name, "transport-sync");
00934 params[i].character = 't';
00935 params[i].type = JackDriverParamBool;
00936 params[i].value.ui = 1U;
00937 strcpy (params[i].short_desc,
00938 "Whether to slave the transport to the master transport");
00939 strcpy (params[i].long_desc, params[i].short_desc);
00940
00941 i++;
00942 strcpy (params[i].name, "autoconf");
00943 params[i].character = 'a';
00944 params[i].type = JackDriverParamBool;
00945 params[i].value.ui = 1U;
00946 strcpy (params[i].short_desc,
00947 "Whether to use Autoconfig, or just start.");
00948 strcpy (params[i].long_desc, params[i].short_desc);
00949
00950 i++;
00951 strcpy (params[i].name, "redundancy");
00952 params[i].character = 'R';
00953 params[i].type = JackDriverParamUInt;
00954 params[i].value.ui = 1U;
00955 strcpy (params[i].short_desc,
00956 "Send packets N times");
00957 strcpy (params[i].long_desc, params[i].short_desc);
00958
00959 i++;
00960 strcpy (params[i].name, "native-endian");
00961 params[i].character = 'e';
00962 params[i].type = JackDriverParamBool;
00963 params[i].value.ui = 0U;
00964 strcpy (params[i].short_desc,
00965 "Dont convert samples to network byte order.");
00966 strcpy (params[i].long_desc, params[i].short_desc);
00967
00968 i++;
00969 strcpy (params[i].name, "jitterval");
00970 params[i].character = 'J';
00971 params[i].type = JackDriverParamInt;
00972 params[i].value.i = 0;
00973 strcpy (params[i].short_desc,
00974 "attempted jitterbuffer microseconds on master");
00975 strcpy (params[i].long_desc, params[i].short_desc);
00976
00977 i++;
00978 strcpy (params[i].name, "always-deadline");
00979 params[i].character = 'D';
00980 params[i].type = JackDriverParamBool;
00981 params[i].value.ui = 0U;
00982 strcpy (params[i].short_desc,
00983 "always use deadline");
00984 strcpy (params[i].long_desc, params[i].short_desc);
00985
00986 desc->params = params;
00987
00988 return desc;
00989 }
00990
00991 SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params )
00992 {
00993 jack_nframes_t sample_rate = 48000;
00994 jack_nframes_t resample_factor = 1;
00995 jack_nframes_t period_size = 1024;
00996 unsigned int capture_ports = 2;
00997 unsigned int playback_ports = 2;
00998 unsigned int capture_ports_midi = 1;
00999 unsigned int playback_ports_midi = 1;
01000 unsigned int listen_port = 3000;
01001 unsigned int resample_factor_up = 0;
01002 unsigned int bitdepth = 0;
01003 unsigned int handle_transport_sync = 1;
01004 unsigned int use_autoconfig = 1;
01005 unsigned int latency = 5;
01006 unsigned int redundancy = 1;
01007 unsigned int mtu = 1400;
01008 int dont_htonl_floats = 0;
01009 int always_deadline = 0;
01010 int jitter_val = 0;
01011 const JSList * node;
01012 const jack_driver_param_t * param;
01013
01014
01015
01016 for ( node = params; node; node = jack_slist_next ( node ) )
01017 {
01018 param = ( const jack_driver_param_t* ) node->data;
01019 switch ( param->character )
01020 {
01021 case 'i':
01022 capture_ports = param->value.ui;
01023 break;
01024
01025 case 'o':
01026 playback_ports = param->value.ui;
01027 break;
01028
01029 case 'I':
01030 capture_ports_midi = param->value.ui;
01031 break;
01032
01033 case 'O':
01034 playback_ports_midi = param->value.ui;
01035 break;
01036
01037 case 'r':
01038 sample_rate = param->value.ui;
01039 break;
01040
01041 case 'p':
01042 period_size = param->value.ui;
01043 break;
01044
01045 case 'l':
01046 listen_port = param->value.ui;
01047 break;
01048
01049 case 'f':
01050 #if HAVE_SAMPLERATE
01051 resample_factor = param->value.ui;
01052 #else
01053 jack_error( "not built with libsamplerate support" );
01054 return NULL;
01055 #endif
01056 break;
01057
01058 case 'u':
01059 #if HAVE_SAMPLERATE
01060 resample_factor_up = param->value.ui;
01061 #else
01062 jack_error( "not built with libsamplerate support" );
01063 return NULL;
01064 #endif
01065 break;
01066
01067 case 'b':
01068 bitdepth = param->value.ui;
01069 break;
01070
01071 case 'c':
01072 #if HAVE_CELT
01073 bitdepth = CELT_MODE;
01074 resample_factor = param->value.ui;
01075 #else
01076 jack_error( "not built with celt support" );
01077 return NULL;
01078 #endif
01079 break;
01080
01081 case 't':
01082 handle_transport_sync = param->value.ui;
01083 break;
01084
01085 case 'a':
01086 use_autoconfig = param->value.ui;
01087 break;
01088
01089 case 'n':
01090 latency = param->value.ui;
01091 break;
01092
01093 case 'R':
01094 redundancy = param->value.ui;
01095 break;
01096
01097 case 'H':
01098 dont_htonl_floats = param->value.ui;
01099 break;
01100
01101 case 'J':
01102 jitter_val = param->value.i;
01103 break;
01104
01105 case 'D':
01106 always_deadline = param->value.ui;
01107 break;
01108 }
01109 }
01110
01111 try
01112 {
01113
01114 Jack::JackDriverClientInterface* driver =
01115 new Jack::JackWaitThreadedDriver (
01116 new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu,
01117 capture_ports_midi, playback_ports_midi, capture_ports, playback_ports,
01118 sample_rate, period_size, resample_factor,
01119 "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy,
01120 dont_htonl_floats, always_deadline, jitter_val ) );
01121
01122 if ( driver->Open ( period_size, sample_rate, 1, 1, capture_ports, playback_ports,
01123 0, "from_master_", "to_master_", 0, 0 ) == 0 )
01124 {
01125 return driver;
01126 }
01127 else
01128 {
01129 delete driver;
01130 return NULL;
01131 }
01132
01133 }
01134 catch ( ... )
01135 {
01136 return NULL;
01137 }
01138 }
01139
01140 #ifdef __cplusplus
01141 }
01142 #endif
01143 }