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