Jack2 1.9.7
|
00001 /* 00002 Copyright (C) 2001 Paul Davis 00003 Copyright (C) 2008 Romain Moret at Grame 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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, // client 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 // No destructor yet. 00087 } 00088 00089 //open, close, attach and detach------------------------------------------------------ 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 //if (netj.handle_transport_sync) 00143 // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); 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 //port = fGraphManager->GetPort ( port_id ); 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 //port = fGraphManager->GetPort ( port_id ); 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 //port = fGraphManager->GetPort ( port_id ); 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 //port = fGraphManager->GetPort ( port_id ); 00238 00239 netj.playback_ports = 00240 jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); 00241 } 00242 return 0; 00243 } 00244 00245 //init and restart-------------------------------------------------------------------- 00246 bool JackNetOneDriver::Initialize() 00247 { 00248 jack_log ( "JackNetOneDriver::Init()" ); 00249 00250 FreePorts(); 00251 netjack_release( &netj ); 00252 00253 //display some additional infos 00254 jack_info ( "NetOne driver started" ); 00255 if( netjack_startup( &netj ) ) { 00256 return false; 00257 } 00258 00259 //register jack ports 00260 if ( AllocPorts() != 0 ) 00261 { 00262 jack_error ( "Can't allocate ports." ); 00263 return false; 00264 } 00265 00266 //monitor 00267 //driver parametering 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 //transport engine parametering 00275 fEngineControl->fTransport.SetNetworkSync ( true ); 00276 return true; 00277 } 00278 00279 00280 //jack ports and buffers-------------------------------------------------------------- 00281 00282 //driver processes-------------------------------------------------------------------- 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 //netjack_read( &netj, netj.period_size ); 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 // Special handling for latency=0 00318 if( netj.latency == 0 ) 00319 netj.resync_threshold = 0; 00320 else 00321 netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); 00322 00323 // check whether, we should handle the transport sync stuff, or leave trnasports untouched. 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 // read local transport info.... 00329 //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); 00330 00331 local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); 00332 00333 // Now check if we have to start or stop local transport to sync to remote... 00334 switch (pkthdr->transport_state) { 00335 00336 case JackTransportStarting: 00337 // the master transport is starting... so we set our reply to the sync_callback; 00338 if (local_trans_state == JackTransportStopped) { 00339 fEngineControl->fTransport.SetCommand ( TransportCommandStart ); 00340 //jack_transport_start(netj.client); 00341 //last_transport_state = JackTransportStopped; 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 //jack_transport_locate(netj.client, compensated_tranport_pos); 00354 //last_transport_state = JackTransportRolling; 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 //jack_transport_locate(netj.client, (pkthdr->transport_frame)); 00368 jack_info("transport is stopped locate to %d", pkthdr->transport_frame); 00369 } 00370 if (local_trans_state != JackTransportStopped) 00371 //jack_transport_stop(netj.client); 00372 fEngineControl->fTransport.SetCommand ( TransportCommandStop ); 00373 break; 00374 00375 case JackTransportRolling: 00376 netj.sync_state = 1; 00377 // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { 00378 // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); 00379 // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); 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 // offset packet_bufX by the packetheader. 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 //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); 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 //Render functions-------------------------------------------------------------------- 00509 00510 // render functions for float 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 // audio port, resample if necessary 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 // midi port, decode midi events 00586 // convert the data buffer to a standard format (uint32_t based) 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 // audio port, resample if necessary 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 // encode midi events from port to packet 00669 // convert the data buffer to a standard format (uint32_t based) 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 // render functions for celt. 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 // audio port, decode celt data. 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 // midi port, decode midi events 00722 // convert the data buffer to a standard format (uint32_t based) 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 // audio port, encode celt data. 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 // encode midi events from port to packet 00773 // convert the data buffer to a standard format (uint32_t based) 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 /* Wrapper functions with bitdepth argument... */ 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 //driver loader----------------------------------------------------------------------- 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" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 00820 strcpy ( desc->desc, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 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 }