00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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,
00064 name,
00065 capture_ports,
00066 playback_ports,
00067 midi_input_ports,
00068 midi_output_ports,
00069 sample_rate,
00070 period_size,
00071 port,
00072 transport_sync,
00073 resample_factor,
00074 0,
00075 bitdepth,
00076 use_autoconfig,
00077 latency,
00078 redundancy,
00079 dont_htonl_floats,
00080 always_deadline,
00081 jitter_val);
00082 }
00083
00084 JackNetOneDriver::~JackNetOneDriver()
00085 {
00086
00087 }
00088
00089
00090
00091 int JackNetOneDriver::Close()
00092 {
00093
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
00118
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
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
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
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
00210
00211 netj.playback_ports =
00212 jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index);
00213 }
00214 return 0;
00215 }
00216
00217
00218 bool JackNetOneDriver::Initialize()
00219 {
00220 jack_log("JackNetOneDriver::Init");
00221
00222 FreePorts();
00223 netjack_release(&netj);
00224
00225
00226 jack_info("NetOne driver started");
00227 if (netjack_startup(&netj)) {
00228 return false;
00229 }
00230
00231
00232 if (AllocPorts() != 0) {
00233 jack_error("Can't allocate ports.");
00234 return false;
00235 }
00236
00237
00238
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
00246 fEngineControl->fTransport.SetNetworkSync(true);
00247 return true;
00248 }
00249
00250
00251
00252
00253
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
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
00290 if (netj.latency == 0)
00291 netj.resync_threshold = 0;
00292 else
00293 netj.resync_threshold = MIN(15, pkthdr->latency - 1);
00294
00295
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
00301
00302
00303 local_trans_state = fEngineControl->fTransport.Query(&local_trans_pos);
00304
00305
00306 switch (pkthdr->transport_state) {
00307
00308 case JackTransportStarting:
00309
00310 if (local_trans_state == JackTransportStopped) {
00311 fEngineControl->fTransport.SetCommand(TransportCommandStart);
00312
00313
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
00326
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
00340 jack_info("transport is stopped locate to %d", pkthdr->transport_frame);
00341 }
00342 if (local_trans_state != JackTransportStopped)
00343
00344 fEngineControl->fTransport.SetCommand(TransportCommandStop);
00345 break;
00346
00347 case JackTransportRolling:
00348 netj.sync_state = 1;
00349
00350
00351
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
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
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
00480
00481
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
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
00546
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
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
00619
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
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
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
00668
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
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
00715
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
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
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 }