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