Jack2 1.9.6
|
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 = 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 //port = fGraphManager->GetPort ( port_id ); 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 //port = fGraphManager->GetPort ( port_id ); 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 //port = fGraphManager->GetPort ( port_id ); 00234 00235 netj.playback_ports = 00236 jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id); 00237 } 00238 return 0; 00239 } 00240 00241 //init and restart-------------------------------------------------------------------- 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 //display some additional infos 00252 jack_info ( "NetOne driver started" ); 00253 if( netjack_startup( &netj ) ) { 00254 return false; 00255 } 00256 00257 //register jack ports 00258 if ( AllocPorts() != 0 ) 00259 { 00260 jack_error ( "Can't allocate ports." ); 00261 return false; 00262 } 00263 00264 00265 //monitor 00266 //driver parametering 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 //transport engine parametering 00274 fEngineControl->fTransport.SetNetworkSync ( true ); 00275 return true; 00276 } 00277 00278 00279 //jack ports and buffers-------------------------------------------------------------- 00280 00281 //driver processes-------------------------------------------------------------------- 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 //netjack_read( &netj, netj.period_size ); 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 // Special handling for latency=0 00317 if( netj.latency == 0 ) 00318 netj.resync_threshold = 0; 00319 else 00320 netj.resync_threshold = MIN( 15, pkthdr->latency-1 ); 00321 00322 // check whether, we should handle the transport sync stuff, or leave trnasports untouched. 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 // read local transport info.... 00328 //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); 00329 00330 local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); 00331 00332 // Now check if we have to start or stop local transport to sync to remote... 00333 switch (pkthdr->transport_state) { 00334 case JackTransportStarting: 00335 // the master transport is starting... so we set our reply to the sync_callback; 00336 if (local_trans_state == JackTransportStopped) { 00337 fEngineControl->fTransport.SetCommand ( TransportCommandStart ); 00338 //jack_transport_start(netj.client); 00339 //last_transport_state = JackTransportStopped; 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 //jack_transport_locate(netj.client, compensated_tranport_pos); 00353 //last_transport_state = JackTransportRolling; 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 //jack_transport_locate(netj.client, (pkthdr->transport_frame)); 00366 jack_info("transport is stopped locate to %d", pkthdr->transport_frame); 00367 } 00368 if (local_trans_state != JackTransportStopped) 00369 //jack_transport_stop(netj.client); 00370 fEngineControl->fTransport.SetCommand ( TransportCommandStop ); 00371 break; 00372 case JackTransportRolling: 00373 netj.sync_state = 1; 00374 // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { 00375 // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); 00376 // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); 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 // offset packet_bufX by the packetheader. 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 //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); 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 //Render functions-------------------------------------------------------------------- 00512 00513 // render functions for float 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 // audio port, resample if necessary 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 // midi port, decode midi events 00590 // convert the data buffer to a standard format (uint32_t based) 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 // audio port, resample if necessary 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 // encode midi events from port to packet 00673 // convert the data buffer to a standard format (uint32_t based) 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 // render functions for celt. 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 // audio port, decode celt data. 00709 00710 CELTDecoder *decoder = (CELTDecoder *)src_node->data; 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 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 // midi port, decode midi events 00721 // convert the data buffer to a standard format (uint32_t based) 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 // audio port, encode celt data. 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 // encode midi events from port to packet 00768 // convert the data buffer to a standard format (uint32_t based) 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 /* Wrapper functions with bitdepth argument... */ 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 //driver loader----------------------------------------------------------------------- 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" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 00817 strcpy ( desc->desc, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 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 }