Jack2
1.9.8
|
00001 /* 00002 Copyright (C) 2008-2011 Torben Horn 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00018 00019 #ifdef WIN32 00020 #include <malloc.h> 00021 #endif 00022 00023 #include "JackNetOneDriver.h" 00024 #include "JackEngineControl.h" 00025 #include "JackLockedEngine.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 : JackWaiterDriver(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 00091 int JackNetOneDriver::Close() 00092 { 00093 // Generic audio driver close 00094 int res = JackWaiterDriver::Close(); 00095 00096 FreePorts(); 00097 netjack_release(&netj); 00098 return res; 00099 } 00100 00101 int JackNetOneDriver::Attach() 00102 { 00103 return 0; 00104 } 00105 00106 int JackNetOneDriver::Detach() 00107 { 00108 return 0; 00109 } 00110 00111 int JackNetOneDriver::AllocPorts() 00112 { 00113 jack_port_id_t port_index; 00114 char buf[64]; 00115 unsigned int chn; 00116 00117 //if (netj.handle_transport_sync) 00118 // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL); 00119 00120 for (chn = 0; chn < netj.capture_channels_audio; chn++) { 00121 snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); 00122 00123 if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, 00124 CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { 00125 jack_error("driver: cannot register port for %s", buf); 00126 return -1; 00127 } 00128 //port = fGraphManager->GetPort(port_index); 00129 00130 netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index); 00131 00132 if (netj.bitdepth == CELT_MODE) { 00133 #if HAVE_CELT 00134 #if HAVE_CELT_API_0_11 00135 celt_int32 lookahead; 00136 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); 00137 netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create_custom(celt_mode, 1, NULL)); 00138 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 00139 celt_int32 lookahead; 00140 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); 00141 netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create(celt_mode, 1, NULL)); 00142 #else 00143 celt_int32_t lookahead; 00144 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL); 00145 netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create(celt_mode)); 00146 #endif 00147 celt_mode_info(celt_mode, CELT_GET_LOOKAHEAD, &lookahead); 00148 netj.codec_latency = 2 * lookahead; 00149 #endif 00150 } else { 00151 #if HAVE_SAMPLERATE 00152 netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); 00153 #endif 00154 } 00155 } 00156 00157 for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) { 00158 snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1); 00159 00160 if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, 00161 CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { 00162 jack_error("driver: cannot register port for %s", buf); 00163 return -1; 00164 } 00165 //port = fGraphManager->GetPort(port_index); 00166 00167 netj.capture_ports = 00168 jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index); 00169 } 00170 00171 for (chn = 0; chn < netj.playback_channels_audio; chn++) { 00172 snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); 00173 00174 if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, 00175 PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { 00176 jack_error("driver: cannot register port for %s", buf); 00177 return -1; 00178 } 00179 //port = fGraphManager->GetPort(port_index); 00180 00181 netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index); 00182 if (netj.bitdepth == CELT_MODE) { 00183 #if HAVE_CELT 00184 #if HAVE_CELT_API_0_11 00185 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); 00186 netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create_custom(celt_mode, 1, NULL)); 00187 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 00188 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); 00189 netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode, 1, NULL)); 00190 #else 00191 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL); 00192 netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode)); 00193 #endif 00194 #endif 00195 } else { 00196 #if HAVE_SAMPLERATE 00197 netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL)); 00198 #endif 00199 } 00200 } 00201 for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) { 00202 snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1); 00203 00204 if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, 00205 PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { 00206 jack_error("driver: cannot register port for %s", buf); 00207 return -1; 00208 } 00209 //port = fGraphManager->GetPort(port_index); 00210 00211 netj.playback_ports = 00212 jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index); 00213 } 00214 return 0; 00215 } 00216 00217 //init and restart-------------------------------------------------------------------- 00218 bool JackNetOneDriver::Initialize() 00219 { 00220 jack_log("JackNetOneDriver::Init"); 00221 00222 FreePorts(); 00223 netjack_release(&netj); 00224 00225 //display some additional infos 00226 jack_info("NetOne driver started"); 00227 if (netjack_startup(&netj)) { 00228 return false; 00229 } 00230 00231 //register jack ports 00232 if (AllocPorts() != 0) { 00233 jack_error("Can't allocate ports."); 00234 return false; 00235 } 00236 00237 //monitor 00238 //driver parametering 00239 JackTimedDriver::SetBufferSize(netj.period_size); 00240 JackTimedDriver::SetSampleRate(netj.sample_rate); 00241 00242 JackDriver::NotifyBufferSize(netj.period_size); 00243 JackDriver::NotifySampleRate(netj.sample_rate); 00244 00245 //transport engine parametering 00246 fEngineControl->fTransport.SetNetworkSync(true); 00247 return true; 00248 } 00249 00250 00251 //jack ports and buffers-------------------------------------------------------------- 00252 00253 //driver processes-------------------------------------------------------------------- 00254 00255 int JackNetOneDriver::Read() 00256 { 00257 int delay; 00258 delay = netjack_wait(&netj); 00259 if (delay) { 00260 NotifyXRun(fBeginDateUst, (float) delay); 00261 jack_error("netxruns... duration: %dms", delay / 1000); 00262 } 00263 00264 if ((netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2) 00265 JackTools::ThrowJackNetException(); 00266 00267 //netjack_read(&netj, netj.period_size); 00268 JackDriver::CycleTakeBeginTime(); 00269 00270 jack_position_t local_trans_pos; 00271 jack_transport_state_t local_trans_state; 00272 00273 unsigned int *packet_buf, *packet_bufX; 00274 00275 if (! netj.packet_data_valid) { 00276 jack_log("data not valid"); 00277 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); 00278 return 0; 00279 } 00280 packet_buf = netj.rx_buf; 00281 00282 jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf; 00283 00284 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); 00285 00286 netj.reply_port = pkthdr->reply_port; 00287 netj.latency = pkthdr->latency; 00288 00289 // Special handling for latency=0 00290 if (netj.latency == 0) 00291 netj.resync_threshold = 0; 00292 else 00293 netj.resync_threshold = MIN(15, pkthdr->latency - 1); 00294 00295 // check whether, we should handle the transport sync stuff, or leave trnasports untouched. 00296 if (netj.handle_transport_sync) { 00297 #if 1 00298 unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency); 00299 00300 // read local transport info.... 00301 //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); 00302 00303 local_trans_state = fEngineControl->fTransport.Query(&local_trans_pos); 00304 00305 // Now check if we have to start or stop local transport to sync to remote... 00306 switch (pkthdr->transport_state) { 00307 00308 case JackTransportStarting: 00309 // the master transport is starting... so we set our reply to the sync_callback; 00310 if (local_trans_state == JackTransportStopped) { 00311 fEngineControl->fTransport.SetCommand(TransportCommandStart); 00312 //jack_transport_start(netj.client); 00313 //last_transport_state = JackTransportStopped; 00314 netj.sync_state = 0; 00315 jack_info("locally stopped... starting..."); 00316 } 00317 00318 if (local_trans_pos.frame != compensated_tranport_pos) { 00319 jack_position_t new_pos = local_trans_pos; 00320 new_pos.frame = compensated_tranport_pos + 2 * netj.period_size; 00321 new_pos.valid = (jack_position_bits_t) 0; 00322 00323 00324 fEngineControl->fTransport.RequestNewPos(&new_pos); 00325 //jack_transport_locate(netj.client, compensated_tranport_pos); 00326 //last_transport_state = JackTransportRolling; 00327 netj.sync_state = 0; 00328 jack_info("starting locate to %d", compensated_tranport_pos); 00329 } 00330 break; 00331 00332 case JackTransportStopped: 00333 netj.sync_state = 1; 00334 if (local_trans_pos.frame != (pkthdr->transport_frame)) { 00335 jack_position_t new_pos = local_trans_pos; 00336 new_pos.frame = pkthdr->transport_frame; 00337 new_pos.valid = (jack_position_bits_t)0; 00338 fEngineControl->fTransport.RequestNewPos(&new_pos); 00339 //jack_transport_locate(netj.client, (pkthdr->transport_frame)); 00340 jack_info("transport is stopped locate to %d", pkthdr->transport_frame); 00341 } 00342 if (local_trans_state != JackTransportStopped) 00343 //jack_transport_stop(netj.client); 00344 fEngineControl->fTransport.SetCommand(TransportCommandStop); 00345 break; 00346 00347 case JackTransportRolling: 00348 netj.sync_state = 1; 00349 // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) { 00350 // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size)); 00351 // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); 00352 // } 00353 if (local_trans_state != JackTransportRolling) 00354 fEngineControl->fTransport.SetState(JackTransportRolling); 00355 break; 00356 00357 case JackTransportLooping: 00358 break; 00359 } 00360 #endif 00361 } 00362 00363 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); 00364 packet_cache_release_packet(netj.packcache, netj.expected_framecnt); 00365 return 0; 00366 } 00367 00368 int JackNetOneDriver::Write() 00369 { 00370 int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0); 00371 uint32_t *packet_buf, *packet_bufX; 00372 00373 int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); 00374 jacknet_packet_header *pkthdr; 00375 00376 packet_buf = (uint32_t *) alloca(packet_size); 00377 pkthdr = (jacknet_packet_header *)packet_buf; 00378 00379 if (netj.running_free) { 00380 return 0; 00381 } 00382 00383 // offset packet_bufX by the packetheader. 00384 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t); 00385 00386 pkthdr->sync_state = syncstate;; 00387 pkthdr->latency = netj.time_to_deadline; 00388 //printf("time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness); 00389 pkthdr->framecnt = netj.expected_framecnt; 00390 00391 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); 00392 00393 packet_header_hton(pkthdr); 00394 if (netj.srcaddress_valid) { 00395 unsigned int r; 00396 static const int flag = 0; 00397 00398 if (netj.reply_port) 00399 netj.syncsource_address.sin_port = htons(netj.reply_port); 00400 00401 for (r = 0; r < netj.redundancy; r++) 00402 netjack_sendto(netj.sockfd, (char *)packet_buf, packet_size, 00403 flag, (struct sockaddr*) & (netj.syncsource_address), sizeof(struct sockaddr_in), netj.mtu); 00404 } 00405 return 0; 00406 } 00407 00408 void 00409 JackNetOneDriver::FreePorts () 00410 { 00411 JSList *node = netj.capture_ports; 00412 00413 while (node != NULL) { 00414 JSList *this_node = node; 00415 jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; 00416 node = jack_slist_remove_link(node, this_node); 00417 jack_slist_free_1(this_node); 00418 fEngine->PortUnRegister(fClientControl.fRefNum, port_index); 00419 } 00420 netj.capture_ports = NULL; 00421 00422 node = netj.playback_ports; 00423 while (node != NULL) { 00424 JSList *this_node = node; 00425 jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; 00426 node = jack_slist_remove_link(node, this_node); 00427 jack_slist_free_1(this_node); 00428 fEngine->PortUnRegister(fClientControl.fRefNum, port_index); 00429 } 00430 netj.playback_ports = NULL; 00431 00432 if (netj.bitdepth == CELT_MODE) { 00433 #if HAVE_CELT 00434 node = netj.playback_srcs; 00435 while (node != NULL) { 00436 JSList *this_node = node; 00437 CELTEncoder *enc = (CELTEncoder *) node->data; 00438 node = jack_slist_remove_link(node, this_node); 00439 jack_slist_free_1(this_node); 00440 celt_encoder_destroy(enc); 00441 } 00442 netj.playback_srcs = NULL; 00443 00444 node = netj.capture_srcs; 00445 while (node != NULL) { 00446 JSList *this_node = node; 00447 CELTDecoder *dec = (CELTDecoder *) node->data; 00448 node = jack_slist_remove_link(node, this_node); 00449 jack_slist_free_1(this_node); 00450 celt_decoder_destroy(dec); 00451 } 00452 netj.capture_srcs = NULL; 00453 #endif 00454 } else { 00455 #if HAVE_SAMPLERATE 00456 node = netj.playback_srcs; 00457 while (node != NULL) { 00458 JSList *this_node = node; 00459 SRC_STATE *state = (SRC_STATE *) node->data; 00460 node = jack_slist_remove_link(node, this_node); 00461 jack_slist_free_1(this_node); 00462 src_delete(state); 00463 } 00464 netj.playback_srcs = NULL; 00465 00466 node = netj.capture_srcs; 00467 while (node != NULL) { 00468 JSList *this_node = node; 00469 SRC_STATE *state = (SRC_STATE *) node->data; 00470 node = jack_slist_remove_link(node, this_node); 00471 jack_slist_free_1(this_node); 00472 src_delete(state); 00473 } 00474 netj.capture_srcs = NULL; 00475 #endif 00476 } 00477 } 00478 00479 //Render functions-------------------------------------------------------------------- 00480 00481 // render functions for float 00482 void 00483 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) 00484 { 00485 uint32_t chn = 0; 00486 JSList *node = capture_ports; 00487 #if HAVE_SAMPLERATE 00488 JSList *src_node = capture_srcs; 00489 #endif 00490 00491 uint32_t *packet_bufX = (uint32_t *)packet_payload; 00492 00493 if (!packet_payload) 00494 return; 00495 00496 while (node != NULL) { 00497 unsigned int i; 00498 int_float_t val; 00499 #if HAVE_SAMPLERATE 00500 SRC_DATA src; 00501 #endif 00502 jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; 00503 JackPort *port = fGraphManager->GetPort(port_index); 00504 00505 jack_default_audio_sample_t* buf = 00506 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); 00507 00508 const char *porttype = port->GetType(); 00509 00510 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { 00511 #if HAVE_SAMPLERATE 00512 // audio port, resample if necessary 00513 if (net_period_down != nframes) { 00514 SRC_STATE *src_state = (SRC_STATE *)src_node->data; 00515 for (i = 0; i < net_period_down; i++) { 00516 packet_bufX[i] = ntohl (packet_bufX[i]); 00517 } 00518 00519 src.data_in = (float *) packet_bufX; 00520 src.input_frames = net_period_down; 00521 00522 src.data_out = buf; 00523 src.output_frames = nframes; 00524 00525 src.src_ratio = (float) nframes / (float) net_period_down; 00526 src.end_of_input = 0; 00527 00528 src_set_ratio (src_state, src.src_ratio); 00529 src_process (src_state, &src); 00530 src_node = jack_slist_next (src_node); 00531 } else 00532 #endif 00533 { 00534 if (dont_htonl_floats) { 00535 memcpy(buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t)); 00536 } else { 00537 for (i = 0; i < net_period_down; i++) { 00538 val.i = packet_bufX[i]; 00539 val.i = ntohl (val.i); 00540 buf[i] = val.f; 00541 } 00542 } 00543 } 00544 } else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { 00545 // midi port, decode midi events 00546 // convert the data buffer to a standard format (uint32_t based) 00547 unsigned int buffer_size_uint32 = net_period_down; 00548 uint32_t * buffer_uint32 = (uint32_t*)packet_bufX; 00549 decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); 00550 } 00551 packet_bufX = (packet_bufX + net_period_down); 00552 node = jack_slist_next (node); 00553 chn++; 00554 } 00555 } 00556 00557 void 00558 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) 00559 { 00560 uint32_t chn = 0; 00561 JSList *node = playback_ports; 00562 #if HAVE_SAMPLERATE 00563 JSList *src_node = playback_srcs; 00564 #endif 00565 00566 uint32_t *packet_bufX = (uint32_t *) packet_payload; 00567 00568 while (node != NULL) { 00569 #if HAVE_SAMPLERATE 00570 SRC_DATA src; 00571 #endif 00572 unsigned int i; 00573 int_float_t val; 00574 jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; 00575 JackPort *port = fGraphManager->GetPort(port_index); 00576 00577 jack_default_audio_sample_t* buf = 00578 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); 00579 00580 const char *porttype = port->GetType(); 00581 00582 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { 00583 // audio port, resample if necessary 00584 00585 #if HAVE_SAMPLERATE 00586 if (net_period_up != nframes) { 00587 SRC_STATE *src_state = (SRC_STATE *) src_node->data; 00588 src.data_in = buf; 00589 src.input_frames = nframes; 00590 00591 src.data_out = (float *) packet_bufX; 00592 src.output_frames = net_period_up; 00593 00594 src.src_ratio = (float) net_period_up / (float) nframes; 00595 src.end_of_input = 0; 00596 00597 src_set_ratio (src_state, src.src_ratio); 00598 src_process (src_state, &src); 00599 00600 for (i = 0; i < net_period_up; i++) { 00601 packet_bufX[i] = htonl (packet_bufX[i]); 00602 } 00603 src_node = jack_slist_next (src_node); 00604 } else 00605 #endif 00606 { 00607 if (dont_htonl_floats) { 00608 memcpy(packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t)); 00609 } else { 00610 for (i = 0; i < net_period_up; i++) { 00611 val.f = buf[i]; 00612 val.i = htonl (val.i); 00613 packet_bufX[i] = val.i; 00614 } 00615 } 00616 } 00617 } else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { 00618 // encode midi events from port to packet 00619 // convert the data buffer to a standard format (uint32_t based) 00620 unsigned int buffer_size_uint32 = net_period_up; 00621 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; 00622 encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); 00623 } 00624 packet_bufX = (packet_bufX + net_period_up); 00625 node = jack_slist_next (node); 00626 chn++; 00627 } 00628 } 00629 00630 #if HAVE_CELT 00631 // render functions for celt. 00632 void 00633 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) 00634 { 00635 uint32_t chn = 0; 00636 JSList *node = capture_ports; 00637 JSList *src_node = capture_srcs; 00638 unsigned char *packet_bufX = (unsigned char *)packet_payload; 00639 00640 while (node != NULL) { 00641 jack_port_id_t port_index = (jack_port_id_t) (intptr_t)node->data; 00642 JackPort *port = fGraphManager->GetPort(port_index); 00643 00644 jack_default_audio_sample_t* buf = 00645 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); 00646 00647 const char *portname = port->GetType(); 00648 00649 if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { 00650 // audio port, decode celt data. 00651 CELTDecoder *decoder = (CELTDecoder *)src_node->data; 00652 00653 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 00654 if (!packet_payload) 00655 celt_decode_float(decoder, NULL, net_period_down, buf, nframes); 00656 else 00657 celt_decode_float(decoder, packet_bufX, net_period_down, buf, nframes); 00658 #else 00659 if (!packet_payload) 00660 celt_decode_float(decoder, NULL, net_period_down, buf); 00661 else 00662 celt_decode_float(decoder, packet_bufX, net_period_down, buf); 00663 #endif 00664 00665 src_node = jack_slist_next (src_node); 00666 } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { 00667 // midi port, decode midi events 00668 // convert the data buffer to a standard format (uint32_t based) 00669 unsigned int buffer_size_uint32 = net_period_down / 2; 00670 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; 00671 if (packet_payload) 00672 decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); 00673 } 00674 packet_bufX = (packet_bufX + net_period_down); 00675 node = jack_slist_next (node); 00676 chn++; 00677 } 00678 } 00679 00680 void 00681 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) 00682 { 00683 uint32_t chn = 0; 00684 JSList *node = playback_ports; 00685 JSList *src_node = playback_srcs; 00686 00687 unsigned char *packet_bufX = (unsigned char *)packet_payload; 00688 00689 while (node != NULL) { 00690 jack_port_id_t port_index = (jack_port_id_t) (intptr_t) node->data; 00691 JackPort *port = fGraphManager->GetPort(port_index); 00692 00693 jack_default_audio_sample_t* buf = 00694 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); 00695 00696 const char *portname = port->GetType(); 00697 00698 if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) { 00699 // audio port, encode celt data. 00700 00701 int encoded_bytes; 00702 jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes); 00703 memcpy(floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t)); 00704 CELTEncoder *encoder = (CELTEncoder *)src_node->data; 00705 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 00706 encoded_bytes = celt_encode_float(encoder, floatbuf, nframes, packet_bufX, net_period_up); 00707 #else 00708 encoded_bytes = celt_encode_float(encoder, floatbuf, NULL, packet_bufX, net_period_up); 00709 #endif 00710 if (encoded_bytes != (int)net_period_up) 00711 jack_error("something in celt changed. netjack needs to be changed to handle this."); 00712 src_node = jack_slist_next(src_node); 00713 } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { 00714 // encode midi events from port to packet 00715 // convert the data buffer to a standard format (uint32_t based) 00716 unsigned int buffer_size_uint32 = net_period_up / 2; 00717 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; 00718 encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); 00719 } 00720 packet_bufX = (packet_bufX + net_period_up); 00721 node = jack_slist_next (node); 00722 chn++; 00723 } 00724 } 00725 00726 #endif 00727 /* Wrapper functions with bitdepth argument... */ 00728 void 00729 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) 00730 { 00731 #if HAVE_CELT 00732 if (bitdepth == CELT_MODE) 00733 render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes); 00734 else 00735 #endif 00736 render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats); 00737 } 00738 00739 void 00740 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) 00741 { 00742 #if HAVE_CELT 00743 if (bitdepth == CELT_MODE) 00744 render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up); 00745 else 00746 #endif 00747 render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats); 00748 } 00749 00750 //driver loader----------------------------------------------------------------------- 00751 00752 #ifdef __cplusplus 00753 extern "C" 00754 { 00755 #endif 00756 SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor () 00757 { 00758 jack_driver_desc_t * desc; 00759 jack_driver_desc_filler_t filler; 00760 jack_driver_param_value_t value; 00761 00762 desc = jack_driver_descriptor_construct("netone", JackDriverMaster, "netjack one slave backend component", &filler); 00763 00764 value.ui = 2U; 00765 jack_driver_descriptor_add_parameter(desc, &filler, "audio-ins", 'i', JackDriverParamUInt, &value, NULL, "Number of capture channels (defaults to 2)", NULL); 00766 jack_driver_descriptor_add_parameter(desc, &filler, "audio-outs", 'o', JackDriverParamUInt, &value, NULL, "Number of playback channels (defaults to 2)", NULL); 00767 00768 value.ui = 1U; 00769 jack_driver_descriptor_add_parameter(desc, &filler, "midi-ins", 'I', JackDriverParamUInt, &value, NULL, "Number of midi capture channels (defaults to 1)", NULL); 00770 jack_driver_descriptor_add_parameter(desc, &filler, "midi-outs", 'O', JackDriverParamUInt, &value, NULL, "Number of midi playback channels (defaults to 1)", NULL); 00771 00772 value.ui = 48000U; 00773 jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL); 00774 00775 value.ui = 1024U; 00776 jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL); 00777 00778 value.ui = 5U; 00779 jack_driver_descriptor_add_parameter(desc, &filler, "num-periods", 'n', JackDriverParamUInt, &value, NULL, "Network latency setting in no. of periods", NULL); 00780 00781 value.ui = 3000U; 00782 jack_driver_descriptor_add_parameter(desc, &filler, "listen-port", 'l', JackDriverParamUInt, &value, NULL, "The socket port we are listening on for sync packets", NULL); 00783 00784 value.ui = 1U; 00785 jack_driver_descriptor_add_parameter(desc, &filler, "factor", 'f', JackDriverParamUInt, &value, NULL, "Factor for sample rate reduction", NULL); 00786 00787 value.ui = 0U; 00788 jack_driver_descriptor_add_parameter(desc, &filler, "upstream-factor", 'u', JackDriverParamUInt, &value, NULL, "Factor for sample rate reduction on the upstream", NULL); 00789 00790 #if HAVE_CELT 00791 value.ui = 0U; 00792 jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamUInt, &value, NULL, "Set CELT encoding and number of kbits per channel", NULL); 00793 #endif 00794 value.ui = 0U; 00795 jack_driver_descriptor_add_parameter(desc, &filler, "bit-depth", 'b', JackDriverParamUInt, &value, NULL, "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)", NULL); 00796 00797 value.i = true; 00798 jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamBool, &value, NULL, "Whether to slave the transport to the master transport", NULL); 00799 00800 value.ui = true; 00801 jack_driver_descriptor_add_parameter(desc, &filler, "autoconf", 'a', JackDriverParamBool, &value, NULL, "Whether to use Autoconfig, or just start", NULL); 00802 00803 value.ui = 1U; 00804 jack_driver_descriptor_add_parameter(desc, &filler, "redundancy", 'R', JackDriverParamUInt, &value, NULL, "Send packets N times", NULL); 00805 00806 value.ui = false; 00807 jack_driver_descriptor_add_parameter(desc, &filler, "native-endian", 'e', JackDriverParamBool, &value, NULL, "Dont convert samples to network byte order", NULL); 00808 00809 value.i = 0; 00810 jack_driver_descriptor_add_parameter(desc, &filler, "jitterval", 'J', JackDriverParamInt, &value, NULL, "Attempted jitterbuffer microseconds on master", NULL); 00811 00812 value.i = false; 00813 jack_driver_descriptor_add_parameter(desc, &filler, "always-deadline", 'D', JackDriverParamBool, &value, NULL, "Always use deadline", NULL); 00814 00815 return desc; 00816 } 00817 00818 SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) 00819 { 00820 jack_nframes_t sample_rate = 48000; 00821 jack_nframes_t resample_factor = 1; 00822 jack_nframes_t period_size = 1024; 00823 unsigned int capture_ports = 2; 00824 unsigned int playback_ports = 2; 00825 unsigned int capture_ports_midi = 1; 00826 unsigned int playback_ports_midi = 1; 00827 unsigned int listen_port = 3000; 00828 unsigned int bitdepth = 0; 00829 unsigned int handle_transport_sync = 1; 00830 unsigned int use_autoconfig = 1; 00831 unsigned int latency = 5; 00832 unsigned int redundancy = 1; 00833 unsigned int mtu = 1400; 00834 #if HAVE_SAMPLERATE 00835 unsigned int resample_factor_up = 1; 00836 #endif 00837 int dont_htonl_floats = 0; 00838 int always_deadline = 0; 00839 int jitter_val = 0; 00840 const JSList * node; 00841 const jack_driver_param_t * param; 00842 00843 for (node = params; node; node = jack_slist_next(node)) { 00844 param = (const jack_driver_param_t*) node->data; 00845 switch (param->character) { 00846 case 'i': 00847 capture_ports = param->value.ui; 00848 break; 00849 00850 case 'o': 00851 playback_ports = param->value.ui; 00852 break; 00853 00854 case 'I': 00855 capture_ports_midi = param->value.ui; 00856 break; 00857 00858 case 'O': 00859 playback_ports_midi = param->value.ui; 00860 break; 00861 00862 case 'r': 00863 sample_rate = param->value.ui; 00864 break; 00865 00866 case 'p': 00867 period_size = param->value.ui; 00868 break; 00869 00870 case 'l': 00871 listen_port = param->value.ui; 00872 break; 00873 00874 case 'f': 00875 #if HAVE_SAMPLERATE 00876 resample_factor = param->value.ui; 00877 #else 00878 jack_error("not built with libsamplerate support"); 00879 return NULL; 00880 #endif 00881 break; 00882 00883 case 'u': 00884 #if HAVE_SAMPLERATE 00885 resample_factor_up = param->value.ui; 00886 #else 00887 jack_error("not built with libsamplerate support"); 00888 return NULL; 00889 #endif 00890 break; 00891 00892 case 'b': 00893 bitdepth = param->value.ui; 00894 break; 00895 00896 case 'c': 00897 #if HAVE_CELT 00898 bitdepth = CELT_MODE; 00899 resample_factor = param->value.ui; 00900 #else 00901 jack_error("not built with celt support"); 00902 return NULL; 00903 #endif 00904 break; 00905 00906 case 't': 00907 handle_transport_sync = param->value.ui; 00908 break; 00909 00910 case 'a': 00911 use_autoconfig = param->value.ui; 00912 break; 00913 00914 case 'n': 00915 latency = param->value.ui; 00916 break; 00917 00918 case 'R': 00919 redundancy = param->value.ui; 00920 break; 00921 00922 case 'H': 00923 dont_htonl_floats = param->value.ui; 00924 break; 00925 00926 case 'J': 00927 jitter_val = param->value.i; 00928 break; 00929 00930 case 'D': 00931 always_deadline = param->value.ui; 00932 break; 00933 } 00934 } 00935 00936 try { 00937 Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver ( 00938 new Jack::JackNetOneDriver("system", "net_pcm", engine, table, listen_port, mtu, 00939 capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, 00940 sample_rate, period_size, resample_factor, 00941 "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, 00942 dont_htonl_floats, always_deadline, jitter_val)); 00943 00944 if (driver->Open(period_size, sample_rate, 1, 1, capture_ports, playback_ports, 00945 0, "from_master_", "to_master_", 0, 0) == 0) { 00946 return driver; 00947 } else { 00948 delete driver; 00949 return NULL; 00950 } 00951 00952 } catch (...) { 00953 return NULL; 00954 } 00955 } 00956 00957 #ifdef __cplusplus 00958 } 00959 #endif 00960 }