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