Use ARM neon intrinsics for AudioBufferMixdown
[jack2.git] / common / JackNetOneDriver.cpp
bloba7fc083ea4d560773f6f4d6dd4567b9915eb350e
1 /*
2 Copyright (C) 2008-2011 Torben Horn
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #ifdef WIN32
20 #include <malloc.h>
21 #endif
23 #include "JackNetOneDriver.h"
24 #include "JackEngineControl.h"
25 #include "JackLockedEngine.h"
26 #include "JackGraphManager.h"
27 #include "JackWaitThreadedDriver.h"
28 #include "JackTools.h"
29 #include "driver_interface.h"
31 #include "netjack.h"
32 #include "netjack_packet.h"
34 #if HAVE_SAMPLERATE
35 #include <samplerate.h>
36 #endif
38 #if HAVE_CELT
39 #include <celt/celt.h>
40 #endif
42 #if HAVE_OPUS
43 #include <opus/opus.h>
44 #include <opus/opus_custom.h>
45 #endif
47 #define MIN(x,y) ((x)<(y) ? (x) : (y))
49 using namespace std;
51 namespace Jack
53 JackNetOneDriver::JackNetOneDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table,
54 int port, int mtu, int capture_ports, int playback_ports, int midi_input_ports, int midi_output_ports,
55 int sample_rate, int period_size, int resample_factor,
56 const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig,
57 int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val)
58 : JackWaiterDriver(name, alias, engine, table)
60 jack_log("JackNetOneDriver::JackNetOneDriver port %d", port);
62 #ifdef WIN32
63 WSADATA wsa;
64 WSAStartup(MAKEWORD(2, 0), &wsa);
65 #endif
67 netjack_init(& (this->netj),
68 NULL, // client
69 name,
70 capture_ports,
71 playback_ports,
72 midi_input_ports,
73 midi_output_ports,
74 sample_rate,
75 period_size,
76 port,
77 transport_sync,
78 resample_factor,
80 bitdepth,
81 use_autoconfig,
82 latency,
83 redundancy,
84 dont_htonl_floats,
85 always_deadline,
86 jitter_val);
89 JackNetOneDriver::~JackNetOneDriver()
91 // No destructor yet.
94 //open, close, attach and detach------------------------------------------------------
96 int JackNetOneDriver::Close()
98 // Generic audio driver close
99 int res = JackWaiterDriver::Close();
101 FreePorts();
102 netjack_release(&netj);
103 return res;
106 int JackNetOneDriver::Attach()
108 return 0;
111 int JackNetOneDriver::Detach()
113 return 0;
116 int JackNetOneDriver::AllocPorts()
118 jack_port_id_t port_index;
119 char buf[64];
120 unsigned int chn;
122 //if (netj.handle_transport_sync)
123 // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL);
125 for (chn = 0; chn < netj.capture_channels_audio; chn++) {
126 snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1);
128 if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE,
129 CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
130 jack_error("driver: cannot register port for %s", buf);
131 return -1;
133 //port = fGraphManager->GetPort(port_index);
135 netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index);
137 if (netj.bitdepth == CELT_MODE) {
138 #if HAVE_CELT
139 #if HAVE_CELT_API_0_11
140 celt_int32 lookahead;
141 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL);
142 netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create_custom(celt_mode, 1, NULL));
143 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
144 celt_int32 lookahead;
145 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL);
146 netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create(celt_mode, 1, NULL));
147 #else
148 celt_int32_t lookahead;
149 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL);
150 netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create(celt_mode));
151 #endif
152 celt_mode_info(celt_mode, CELT_GET_LOOKAHEAD, &lookahead);
153 netj.codec_latency = 2 * lookahead;
154 #endif
155 } else if (netj.bitdepth == OPUS_MODE) {
156 #if HAVE_OPUS
157 OpusCustomMode *opus_mode = opus_custom_mode_create(netj.sample_rate, netj.period_size, NULL); // XXX free me in the end
158 OpusCustomDecoder *decoder = opus_custom_decoder_create( opus_mode, 1, NULL );
159 netj.capture_srcs = jack_slist_append(netj.capture_srcs, decoder);
160 #endif
161 } else {
162 #if HAVE_SAMPLERATE
163 netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL));
164 #endif
168 for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) {
169 snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1);
171 if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE,
172 CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
173 jack_error("driver: cannot register port for %s", buf);
174 return -1;
176 //port = fGraphManager->GetPort(port_index);
178 netj.capture_ports =
179 jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index);
182 for (chn = 0; chn < netj.playback_channels_audio; chn++) {
183 snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1);
185 if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE,
186 PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
187 jack_error("driver: cannot register port for %s", buf);
188 return -1;
190 //port = fGraphManager->GetPort(port_index);
192 netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index);
193 if (netj.bitdepth == CELT_MODE) {
194 #if HAVE_CELT
195 #if HAVE_CELT_API_0_11
196 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL);
197 netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create_custom(celt_mode, 1, NULL));
198 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
199 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL);
200 netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode, 1, NULL));
201 #else
202 CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL);
203 netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode));
204 #endif
205 #endif
206 } else if (netj.bitdepth == OPUS_MODE) {
207 #if HAVE_OPUS
208 const int kbps = netj.resample_factor;
209 jack_error("NEW ONE OPUS ENCODER 128 <> %d!!", kbps);
210 int err;
211 OpusCustomMode *opus_mode = opus_custom_mode_create( netj.sample_rate, netj.period_size, &err ); // XXX free me in the end
212 if (err != OPUS_OK) { jack_error("opus mode failed"); }
213 OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err );
214 if (err != OPUS_OK) { jack_error("opus mode failed"); }
215 opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
216 opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
217 opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
218 opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
219 netj.playback_srcs = jack_slist_append(netj.playback_srcs, oe);
220 #endif
221 } else {
222 #if HAVE_SAMPLERATE
223 netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL));
224 #endif
227 for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) {
228 snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1);
230 if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE,
231 PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
232 jack_error("driver: cannot register port for %s", buf);
233 return -1;
235 //port = fGraphManager->GetPort(port_index);
237 netj.playback_ports =
238 jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index);
240 return 0;
243 //init and restart--------------------------------------------------------------------
244 bool JackNetOneDriver::Initialize()
246 jack_log("JackNetOneDriver::Init");
248 FreePorts();
249 netjack_release(&netj);
251 //display some additional infos
252 jack_info("NetOne driver started");
253 if (netjack_startup(&netj)) {
254 return false;
257 //register jack ports
258 if (AllocPorts() != 0) {
259 jack_error("Can't allocate ports.");
260 return false;
263 //monitor
264 //driver parametering
265 JackTimedDriver::SetBufferSize(netj.period_size);
266 JackTimedDriver::SetSampleRate(netj.sample_rate);
268 JackDriver::NotifyBufferSize(netj.period_size);
269 JackDriver::NotifySampleRate(netj.sample_rate);
271 //transport engine parametering
272 fEngineControl->fTransport.SetNetworkSync(true);
273 return true;
277 //jack ports and buffers--------------------------------------------------------------
279 //driver processes--------------------------------------------------------------------
281 int JackNetOneDriver::Read()
283 int delay;
284 delay = netjack_wait(&netj);
285 if (delay) {
286 NotifyXRun(fBeginDateUst, (float) delay);
287 jack_error("netxruns... duration: %dms", delay / 1000);
290 if ((netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2)
291 JackTools::ThrowJackNetException();
293 //netjack_read(&netj, netj.period_size);
294 JackDriver::CycleTakeBeginTime();
296 jack_position_t local_trans_pos;
297 jack_transport_state_t local_trans_state;
299 unsigned int *packet_buf, *packet_bufX;
301 if (! netj.packet_data_valid) {
302 jack_log("data not valid");
303 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);
304 return 0;
306 packet_buf = netj.rx_buf;
308 jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf;
310 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
312 netj.reply_port = pkthdr->reply_port;
313 netj.latency = pkthdr->latency;
315 // Special handling for latency=0
316 if (netj.latency == 0)
317 netj.resync_threshold = 0;
318 else
319 netj.resync_threshold = MIN(15, pkthdr->latency - 1);
321 // check whether, we should handle the transport sync stuff, or leave trnasports untouched.
322 if (netj.handle_transport_sync) {
323 #if 1
324 unsigned int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * netj.period_size) + netj.codec_latency);
326 // read local transport info....
327 //local_trans_state = jack_transport_query(netj.client, &local_trans_pos);
329 local_trans_state = fEngineControl->fTransport.Query(&local_trans_pos);
331 // Now check if we have to start or stop local transport to sync to remote...
332 switch (pkthdr->transport_state) {
334 case JackTransportStarting:
335 // the master transport is starting... so we set our reply to the sync_callback;
336 if (local_trans_state == JackTransportStopped) {
337 fEngineControl->fTransport.SetCommand(TransportCommandStart);
338 //jack_transport_start(netj.client);
339 //last_transport_state = JackTransportStopped;
340 netj.sync_state = 0;
341 jack_info("locally stopped... starting...");
344 if (local_trans_pos.frame != compensated_tranport_pos) {
345 jack_position_t new_pos = local_trans_pos;
346 new_pos.frame = compensated_tranport_pos + 2 * netj.period_size;
347 new_pos.valid = (jack_position_bits_t) 0;
350 fEngineControl->fTransport.RequestNewPos(&new_pos);
351 //jack_transport_locate(netj.client, compensated_tranport_pos);
352 //last_transport_state = JackTransportRolling;
353 netj.sync_state = 0;
354 jack_info("starting locate to %d", compensated_tranport_pos);
356 break;
358 case JackTransportStopped:
359 netj.sync_state = 1;
360 if (local_trans_pos.frame != (pkthdr->transport_frame)) {
361 jack_position_t new_pos = local_trans_pos;
362 new_pos.frame = pkthdr->transport_frame;
363 new_pos.valid = (jack_position_bits_t)0;
364 fEngineControl->fTransport.RequestNewPos(&new_pos);
365 //jack_transport_locate(netj.client, (pkthdr->transport_frame));
366 jack_info("transport is stopped locate to %d", pkthdr->transport_frame);
368 if (local_trans_state != JackTransportStopped)
369 //jack_transport_stop(netj.client);
370 fEngineControl->fTransport.SetCommand(TransportCommandStop);
371 break;
373 case JackTransportRolling:
374 netj.sync_state = 1;
375 // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) {
376 // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size));
377 // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size);
378 // }
379 if (local_trans_state != JackTransportRolling)
380 fEngineControl->fTransport.SetState(JackTransportRolling);
381 break;
383 case JackTransportLooping:
384 break;
386 #endif
389 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);
390 packet_cache_release_packet(netj.packcache, netj.expected_framecnt);
391 return 0;
394 int JackNetOneDriver::Write()
396 int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0);
397 uint32_t *packet_buf, *packet_bufX;
399 int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header);
400 jacknet_packet_header *pkthdr;
402 packet_buf = (uint32_t *) alloca(packet_size);
403 pkthdr = (jacknet_packet_header *)packet_buf;
405 if (netj.running_free) {
406 return 0;
409 // offset packet_bufX by the packetheader.
410 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
412 pkthdr->sync_state = syncstate;;
413 pkthdr->latency = netj.time_to_deadline;
414 //printf("time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness);
415 pkthdr->framecnt = netj.expected_framecnt;
417 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);
419 packet_header_hton(pkthdr);
420 if (netj.srcaddress_valid) {
421 unsigned int r;
422 static const int flag = 0;
424 if (netj.reply_port)
425 netj.syncsource_address.sin_port = htons(netj.reply_port);
427 for (r = 0; r < netj.redundancy; r++)
428 netjack_sendto(netj.sockfd, (char *)packet_buf, packet_size,
429 flag, (struct sockaddr*) & (netj.syncsource_address), sizeof(struct sockaddr_in), netj.mtu);
431 return 0;
434 void
435 JackNetOneDriver::FreePorts ()
437 JSList *node = netj.capture_ports;
439 while (node != NULL) {
440 JSList *this_node = node;
441 jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data;
442 node = jack_slist_remove_link(node, this_node);
443 jack_slist_free_1(this_node);
444 fEngine->PortUnRegister(fClientControl.fRefNum, port_index);
446 netj.capture_ports = NULL;
448 node = netj.playback_ports;
449 while (node != NULL) {
450 JSList *this_node = node;
451 jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data;
452 node = jack_slist_remove_link(node, this_node);
453 jack_slist_free_1(this_node);
454 fEngine->PortUnRegister(fClientControl.fRefNum, port_index);
456 netj.playback_ports = NULL;
458 if (netj.bitdepth == CELT_MODE) {
459 #if HAVE_CELT
460 node = netj.playback_srcs;
461 while (node != NULL) {
462 JSList *this_node = node;
463 CELTEncoder *enc = (CELTEncoder *) node->data;
464 node = jack_slist_remove_link(node, this_node);
465 jack_slist_free_1(this_node);
466 celt_encoder_destroy(enc);
468 netj.playback_srcs = NULL;
470 node = netj.capture_srcs;
471 while (node != NULL) {
472 JSList *this_node = node;
473 CELTDecoder *dec = (CELTDecoder *) node->data;
474 node = jack_slist_remove_link(node, this_node);
475 jack_slist_free_1(this_node);
476 celt_decoder_destroy(dec);
478 netj.capture_srcs = NULL;
479 #endif
480 } else if (netj.bitdepth == OPUS_MODE) {
481 #if HAVE_OPUS
482 node = netj.playback_srcs;
483 while (node != NULL) {
484 JSList *this_node = node;
485 OpusCustomEncoder *enc = (OpusCustomEncoder *) node->data;
486 node = jack_slist_remove_link(node, this_node);
487 jack_slist_free_1(this_node);
488 opus_custom_encoder_destroy(enc);
490 netj.playback_srcs = NULL;
492 node = netj.capture_srcs;
493 while (node != NULL) {
494 JSList *this_node = node;
495 OpusCustomDecoder *dec = (OpusCustomDecoder *) node->data;
496 node = jack_slist_remove_link(node, this_node);
497 jack_slist_free_1(this_node);
498 opus_custom_decoder_destroy(dec);
500 netj.capture_srcs = NULL;
501 #endif
502 } else {
503 #if HAVE_SAMPLERATE
504 node = netj.playback_srcs;
505 while (node != NULL) {
506 JSList *this_node = node;
507 SRC_STATE *state = (SRC_STATE *) node->data;
508 node = jack_slist_remove_link(node, this_node);
509 jack_slist_free_1(this_node);
510 src_delete(state);
512 netj.playback_srcs = NULL;
514 node = netj.capture_srcs;
515 while (node != NULL) {
516 JSList *this_node = node;
517 SRC_STATE *state = (SRC_STATE *) node->data;
518 node = jack_slist_remove_link(node, this_node);
519 jack_slist_free_1(this_node);
520 src_delete(state);
522 netj.capture_srcs = NULL;
523 #endif
527 //Render functions--------------------------------------------------------------------
529 // render functions for float
530 void
531 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)
533 uint32_t chn = 0;
534 JSList *node = capture_ports;
535 #if HAVE_SAMPLERATE
536 JSList *src_node = capture_srcs;
537 #endif
539 uint32_t *packet_bufX = (uint32_t *)packet_payload;
541 if (!packet_payload)
542 return;
544 while (node != NULL) {
545 unsigned int i;
546 int_float_t val;
547 #if HAVE_SAMPLERATE
548 SRC_DATA src;
549 #endif
550 jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data;
551 JackPort *port = fGraphManager->GetPort(port_index);
553 jack_default_audio_sample_t* buf =
554 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
556 const char *porttype = port->GetType();
558 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
559 #if HAVE_SAMPLERATE
560 // audio port, resample if necessary
561 if (net_period_down != nframes) {
562 SRC_STATE *src_state = (SRC_STATE *)src_node->data;
563 for (i = 0; i < net_period_down; i++) {
564 packet_bufX[i] = ntohl (packet_bufX[i]);
567 src.data_in = (float *) packet_bufX;
568 src.input_frames = net_period_down;
570 src.data_out = buf;
571 src.output_frames = nframes;
573 src.src_ratio = (float) nframes / (float) net_period_down;
574 src.end_of_input = 0;
576 src_set_ratio (src_state, src.src_ratio);
577 src_process (src_state, &src);
578 src_node = jack_slist_next (src_node);
579 } else
580 #endif
582 if (dont_htonl_floats) {
583 memcpy(buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t));
584 } else {
585 for (i = 0; i < net_period_down; i++) {
586 val.i = packet_bufX[i];
587 val.i = ntohl (val.i);
588 buf[i] = val.f;
592 } else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
593 // midi port, decode midi events
594 // convert the data buffer to a standard format (uint32_t based)
595 unsigned int buffer_size_uint32 = net_period_down;
596 uint32_t * buffer_uint32 = (uint32_t*)packet_bufX;
597 decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
599 packet_bufX = (packet_bufX + net_period_down);
600 node = jack_slist_next (node);
601 chn++;
605 void
606 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)
608 uint32_t chn = 0;
609 JSList *node = playback_ports;
610 #if HAVE_SAMPLERATE
611 JSList *src_node = playback_srcs;
612 #endif
614 uint32_t *packet_bufX = (uint32_t *) packet_payload;
616 while (node != NULL) {
617 #if HAVE_SAMPLERATE
618 SRC_DATA src;
619 #endif
620 unsigned int i;
621 int_float_t val;
622 jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data;
623 JackPort *port = fGraphManager->GetPort(port_index);
625 jack_default_audio_sample_t* buf =
626 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
628 const char *porttype = port->GetType();
630 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
631 // audio port, resample if necessary
633 #if HAVE_SAMPLERATE
634 if (net_period_up != nframes) {
635 SRC_STATE *src_state = (SRC_STATE *) src_node->data;
636 src.data_in = buf;
637 src.input_frames = nframes;
639 src.data_out = (float *) packet_bufX;
640 src.output_frames = net_period_up;
642 src.src_ratio = (float) net_period_up / (float) nframes;
643 src.end_of_input = 0;
645 src_set_ratio (src_state, src.src_ratio);
646 src_process (src_state, &src);
648 for (i = 0; i < net_period_up; i++) {
649 packet_bufX[i] = htonl (packet_bufX[i]);
651 src_node = jack_slist_next (src_node);
652 } else
653 #endif
655 if (dont_htonl_floats) {
656 memcpy(packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t));
657 } else {
658 for (i = 0; i < net_period_up; i++) {
659 val.f = buf[i];
660 val.i = htonl (val.i);
661 packet_bufX[i] = val.i;
665 } else if (strncmp(porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
666 // encode midi events from port to packet
667 // convert the data buffer to a standard format (uint32_t based)
668 unsigned int buffer_size_uint32 = net_period_up;
669 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
670 encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
672 packet_bufX = (packet_bufX + net_period_up);
673 node = jack_slist_next (node);
674 chn++;
678 #if HAVE_CELT
679 // render functions for celt.
680 void
681 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)
683 uint32_t chn = 0;
684 JSList *node = capture_ports;
685 JSList *src_node = capture_srcs;
686 unsigned char *packet_bufX = (unsigned char *)packet_payload;
688 while (node != NULL) {
689 jack_port_id_t port_index = (jack_port_id_t) (intptr_t)node->data;
690 JackPort *port = fGraphManager->GetPort(port_index);
692 jack_default_audio_sample_t* buf =
693 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
695 const char *portname = port->GetType();
697 if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
698 // audio port, decode celt data.
699 CELTDecoder *decoder = (CELTDecoder *)src_node->data;
701 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
702 if (!packet_payload)
703 celt_decode_float(decoder, NULL, net_period_down, buf, nframes);
704 else
705 celt_decode_float(decoder, packet_bufX, net_period_down, buf, nframes);
706 #else
707 if (!packet_payload)
708 celt_decode_float(decoder, NULL, net_period_down, buf);
709 else
710 celt_decode_float(decoder, packet_bufX, net_period_down, buf);
711 #endif
713 src_node = jack_slist_next (src_node);
714 } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
715 // midi port, decode midi events
716 // convert the data buffer to a standard format (uint32_t based)
717 unsigned int buffer_size_uint32 = net_period_down / 2;
718 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
719 if (packet_payload)
720 decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
722 packet_bufX = (packet_bufX + net_period_down);
723 node = jack_slist_next (node);
724 chn++;
728 void
729 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)
731 uint32_t chn = 0;
732 JSList *node = playback_ports;
733 JSList *src_node = playback_srcs;
735 unsigned char *packet_bufX = (unsigned char *)packet_payload;
737 while (node != NULL) {
738 jack_port_id_t port_index = (jack_port_id_t) (intptr_t) node->data;
739 JackPort *port = fGraphManager->GetPort(port_index);
741 jack_default_audio_sample_t* buf =
742 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
744 const char *portname = port->GetType();
746 if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
747 // audio port, encode celt data.
749 int encoded_bytes;
750 jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes);
751 memcpy(floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t));
752 CELTEncoder *encoder = (CELTEncoder *)src_node->data;
753 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
754 encoded_bytes = celt_encode_float(encoder, floatbuf, nframes, packet_bufX, net_period_up);
755 #else
756 encoded_bytes = celt_encode_float(encoder, floatbuf, NULL, packet_bufX, net_period_up);
757 #endif
758 if (encoded_bytes != (int)net_period_up)
759 jack_error("something in celt changed. netjack needs to be changed to handle this.");
760 src_node = jack_slist_next(src_node);
761 } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
762 // encode midi events from port to packet
763 // convert the data buffer to a standard format (uint32_t based)
764 unsigned int buffer_size_uint32 = net_period_up / 2;
765 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
766 encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
768 packet_bufX = (packet_bufX + net_period_up);
769 node = jack_slist_next (node);
770 chn++;
774 #endif
776 #if HAVE_OPUS
777 #define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
778 // render functions for Opus.
779 void
780 JackNetOneDriver::render_payload_to_jack_ports_opus (void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes)
782 int chn = 0;
783 JSList *node = capture_ports;
784 JSList *src_node = capture_srcs;
786 unsigned char *packet_bufX = (unsigned char *)packet_payload;
788 while (node != NULL) {
789 jack_port_id_t port_index = (jack_port_id_t) (intptr_t)node->data;
790 JackPort *port = fGraphManager->GetPort(port_index);
792 jack_default_audio_sample_t* buf =
793 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
795 const char *portname = port->GetType();
797 if (strncmp(portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
798 // audio port, decode opus data.
799 OpusCustomDecoder *decoder = (OpusCustomDecoder*) src_node->data;
800 if( !packet_payload )
801 memset(buf, 0, nframes * sizeof(float));
802 else {
803 unsigned short len;
804 memcpy(&len, packet_bufX, CDO);
805 len = ntohs(len);
806 opus_custom_decode_float( decoder, packet_bufX + CDO, len, buf, nframes );
809 src_node = jack_slist_next (src_node);
810 } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
811 // midi port, decode midi events
812 // convert the data buffer to a standard format (uint32_t based)
813 unsigned int buffer_size_uint32 = net_period_down / 2;
814 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
815 if( packet_payload )
816 decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
818 packet_bufX = (packet_bufX + net_period_down);
819 node = jack_slist_next (node);
820 chn++;
824 void
825 JackNetOneDriver::render_jack_ports_to_payload_opus (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up)
827 int chn = 0;
828 JSList *node = playback_ports;
829 JSList *src_node = playback_srcs;
831 unsigned char *packet_bufX = (unsigned char *)packet_payload;
833 while (node != NULL) {
834 jack_port_id_t port_index = (jack_port_id_t) (intptr_t) node->data;
835 JackPort *port = fGraphManager->GetPort(port_index);
837 jack_default_audio_sample_t* buf =
838 (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
840 const char *portname = port->GetType();
842 if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
843 // audio port, encode opus data.
845 int encoded_bytes;
846 jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes);
847 memcpy(floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t));
848 OpusCustomEncoder *encoder = (OpusCustomEncoder*) src_node->data;
849 encoded_bytes = opus_custom_encode_float( encoder, floatbuf, nframes, packet_bufX + CDO, net_period_up - CDO );
850 unsigned short len = htons(encoded_bytes);
851 memcpy(packet_bufX, &len, CDO);
852 src_node = jack_slist_next( src_node );
853 } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) {
854 // encode midi events from port to packet
855 // convert the data buffer to a standard format (uint32_t based)
856 unsigned int buffer_size_uint32 = net_period_up / 2;
857 uint32_t * buffer_uint32 = (uint32_t*) packet_bufX;
858 encode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
860 packet_bufX = (packet_bufX + net_period_up);
861 node = jack_slist_next (node);
862 chn++;
865 #endif
867 /* Wrapper functions with bitdepth argument... */
868 void
869 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)
871 #if HAVE_CELT
872 if (bitdepth == CELT_MODE)
873 render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
874 else
875 #endif
876 #if HAVE_OPUS
877 if (bitdepth == OPUS_MODE)
878 render_payload_to_jack_ports_opus (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
879 else
880 #endif
881 render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
884 void
885 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)
887 #if HAVE_CELT
888 if (bitdepth == CELT_MODE)
889 render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
890 else
891 #endif
892 #if HAVE_OPUS
893 if (bitdepth == OPUS_MODE)
894 render_jack_ports_to_payload_opus (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
895 else
896 #endif
897 render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);
900 //driver loader-----------------------------------------------------------------------
902 #ifdef __cplusplus
903 extern "C"
905 #endif
907 SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor ()
909 jack_driver_desc_t * desc;
910 jack_driver_desc_filler_t filler;
911 jack_driver_param_value_t value;
913 desc = jack_driver_descriptor_construct("netone", JackDriverMaster, "netjack one slave backend component", &filler);
915 value.ui = 2U;
916 jack_driver_descriptor_add_parameter(desc, &filler, "audio-ins", 'i', JackDriverParamUInt, &value, NULL, "Number of capture channels (defaults to 2)", NULL);
917 jack_driver_descriptor_add_parameter(desc, &filler, "audio-outs", 'o', JackDriverParamUInt, &value, NULL, "Number of playback channels (defaults to 2)", NULL);
919 value.ui = 1U;
920 jack_driver_descriptor_add_parameter(desc, &filler, "midi-ins", 'I', JackDriverParamUInt, &value, NULL, "Number of midi capture channels (defaults to 1)", NULL);
921 jack_driver_descriptor_add_parameter(desc, &filler, "midi-outs", 'O', JackDriverParamUInt, &value, NULL, "Number of midi playback channels (defaults to 1)", NULL);
923 value.ui = 48000U;
924 jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
926 value.ui = 1024U;
927 jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);
929 value.ui = 5U;
930 jack_driver_descriptor_add_parameter(desc, &filler, "num-periods", 'n', JackDriverParamUInt, &value, NULL, "Network latency setting in no. of periods", NULL);
932 value.ui = 3000U;
933 jack_driver_descriptor_add_parameter(desc, &filler, "listen-port", 'l', JackDriverParamUInt, &value, NULL, "The socket port we are listening on for sync packets", NULL);
935 value.ui = 1U;
936 jack_driver_descriptor_add_parameter(desc, &filler, "factor", 'f', JackDriverParamUInt, &value, NULL, "Factor for sample rate reduction", NULL);
938 value.ui = 0U;
939 jack_driver_descriptor_add_parameter(desc, &filler, "upstream-factor", 'u', JackDriverParamUInt, &value, NULL, "Factor for sample rate reduction on the upstream", NULL);
941 #if HAVE_CELT
942 value.ui = 0U;
943 jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamUInt, &value, NULL, "Set CELT encoding and number of kbits per channel", NULL);
944 #endif
945 #if HAVE_OPUS
946 value.ui = 0U;
947 jack_driver_descriptor_add_parameter(desc, &filler, "opus", 'P', JackDriverParamUInt, &value, NULL, "Set Opus encoding and number of kbits per channel", NULL);
948 #endif
949 value.ui = 0U;
950 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);
952 value.i = true;
953 jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamBool, &value, NULL, "Whether to slave the transport to the master transport", NULL);
955 value.ui = true;
956 jack_driver_descriptor_add_parameter(desc, &filler, "autoconf", 'a', JackDriverParamBool, &value, NULL, "Whether to use Autoconfig, or just start", NULL);
958 value.ui = 1U;
959 jack_driver_descriptor_add_parameter(desc, &filler, "redundancy", 'R', JackDriverParamUInt, &value, NULL, "Send packets N times", NULL);
961 value.ui = false;
962 jack_driver_descriptor_add_parameter(desc, &filler, "native-endian", 'e', JackDriverParamBool, &value, NULL, "Dont convert samples to network byte order", NULL);
964 value.i = 0;
965 jack_driver_descriptor_add_parameter(desc, &filler, "jitterval", 'J', JackDriverParamInt, &value, NULL, "Attempted jitterbuffer microseconds on master", NULL);
967 value.i = false;
968 jack_driver_descriptor_add_parameter(desc, &filler, "always-deadline", 'D', JackDriverParamBool, &value, NULL, "Always use deadline", NULL);
970 return desc;
973 SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
975 jack_nframes_t sample_rate = 48000;
976 jack_nframes_t resample_factor = 1;
977 jack_nframes_t period_size = 1024;
978 unsigned int capture_ports = 2;
979 unsigned int playback_ports = 2;
980 unsigned int capture_ports_midi = 1;
981 unsigned int playback_ports_midi = 1;
982 unsigned int listen_port = 3000;
983 unsigned int bitdepth = 0;
984 unsigned int handle_transport_sync = 1;
985 unsigned int use_autoconfig = 1;
986 unsigned int latency = 5;
987 unsigned int redundancy = 1;
988 unsigned int mtu = 1400;
989 #if HAVE_SAMPLERATE
990 unsigned int resample_factor_up = 1;
991 #endif
992 int dont_htonl_floats = 0;
993 int always_deadline = 0;
994 int jitter_val = 0;
995 const JSList * node;
996 const jack_driver_param_t * param;
998 for (node = params; node; node = jack_slist_next(node)) {
999 param = (const jack_driver_param_t*) node->data;
1000 switch (param->character) {
1001 case 'i':
1002 capture_ports = param->value.ui;
1003 break;
1005 case 'o':
1006 playback_ports = param->value.ui;
1007 break;
1009 case 'I':
1010 capture_ports_midi = param->value.ui;
1011 break;
1013 case 'O':
1014 playback_ports_midi = param->value.ui;
1015 break;
1017 case 'r':
1018 sample_rate = param->value.ui;
1019 break;
1021 case 'p':
1022 period_size = param->value.ui;
1023 break;
1025 case 'l':
1026 listen_port = param->value.ui;
1027 break;
1029 case 'f':
1030 #if HAVE_SAMPLERATE
1031 resample_factor = param->value.ui;
1032 #else
1033 jack_error("not built with libsamplerate support");
1034 return NULL;
1035 #endif
1036 break;
1038 case 'u':
1039 #if HAVE_SAMPLERATE
1040 resample_factor_up = param->value.ui;
1041 #else
1042 jack_error("not built with libsamplerate support");
1043 return NULL;
1044 #endif
1045 break;
1047 case 'b':
1048 bitdepth = param->value.ui;
1049 break;
1051 case 'c':
1052 #if HAVE_CELT
1053 bitdepth = CELT_MODE;
1054 resample_factor = param->value.ui;
1055 #else
1056 jack_error("not built with celt support");
1057 return NULL;
1058 #endif
1059 break;
1061 case 'P':
1062 #if HAVE_OPUS
1063 bitdepth = OPUS_MODE;
1064 resample_factor = param->value.ui;
1065 jack_error("OPUS: %d\n", resample_factor);
1066 #else
1067 jack_error("not built with Opus support");
1068 return NULL;
1069 #endif
1070 break;
1072 case 't':
1073 handle_transport_sync = param->value.ui;
1074 break;
1076 case 'a':
1077 use_autoconfig = param->value.ui;
1078 break;
1080 case 'n':
1081 latency = param->value.ui;
1082 break;
1084 case 'R':
1085 redundancy = param->value.ui;
1086 break;
1088 case 'H':
1089 dont_htonl_floats = param->value.ui;
1090 break;
1092 case 'J':
1093 jitter_val = param->value.i;
1094 break;
1096 case 'D':
1097 always_deadline = param->value.ui;
1098 break;
1102 try {
1103 Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver (
1104 new Jack::JackNetOneDriver("system", "net_pcm", engine, table, listen_port, mtu,
1105 capture_ports_midi, playback_ports_midi, capture_ports, playback_ports,
1106 sample_rate, period_size, resample_factor,
1107 "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy,
1108 dont_htonl_floats, always_deadline, jitter_val));
1110 if (driver->Open(period_size, sample_rate, 1, 1, capture_ports, playback_ports,
1111 0, "from_master", "to_master", 0, 0) == 0) {
1112 return driver;
1113 } else {
1114 delete driver;
1115 return NULL;
1118 } catch (...) {
1119 return NULL;
1123 #ifdef __cplusplus
1125 #endif