Jack2  1.9.9
JackNetOneDriver.cpp
1 /*
2 Copyright (C) 2008-2011 Torben Horn
3 
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.
8 
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.
13 
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.
17 */
18 
19 #ifdef WIN32
20 #include <malloc.h>
21 #endif
22 
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"
30 
31 #include "netjack.h"
32 #include "netjack_packet.h"
33 
34 #if HAVE_SAMPLERATE
35 #include <samplerate.h>
36 #endif
37 
38 #if HAVE_CELT
39 #include <celt/celt.h>
40 #endif
41 
42 #if HAVE_OPUS
43 #include <opus/opus.h>
44 #include <opus/opus_custom.h>
45 #endif
46 
47 #define MIN(x,y) ((x)<(y) ? (x) : (y))
48 
49 using namespace std;
50 
51 namespace Jack
52 {
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)
59 {
60  jack_log("JackNetOneDriver::JackNetOneDriver port %d", port);
61 
62 #ifdef WIN32
63  WSADATA wsa;
64  WSAStartup(MAKEWORD(2, 0), &wsa);
65 #endif
66 
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,
79  0,
80  bitdepth,
81  use_autoconfig,
82  latency,
83  redundancy,
84  dont_htonl_floats,
85  always_deadline,
86  jitter_val);
87 }
88 
89 JackNetOneDriver::~JackNetOneDriver()
90 {
91  // No destructor yet.
92 }
93 
94 //open, close, attach and detach------------------------------------------------------
95 
96 int JackNetOneDriver::Close()
97 {
98  // Generic audio driver close
99  int res = JackWaiterDriver::Close();
100 
101  FreePorts();
102  netjack_release(&netj);
103  return res;
104 }
105 
106 int JackNetOneDriver::Attach()
107 {
108  return 0;
109 }
110 
111 int JackNetOneDriver::Detach()
112 {
113  return 0;
114 }
115 
116 int JackNetOneDriver::AllocPorts()
117 {
118  jack_port_id_t port_index;
119  char buf[64];
120  unsigned int chn;
121 
122  //if (netj.handle_transport_sync)
123  // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL);
124 
125  for (chn = 0; chn < netj.capture_channels_audio; chn++) {
126  snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1);
127 
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;
132  }
133  //port = fGraphManager->GetPort(port_index);
134 
135  netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index);
136 
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
165  }
166  }
167 
168  for (chn = netj.capture_channels_audio; chn < netj.capture_channels; chn++) {
169  snprintf (buf, sizeof(buf) - 1, "system:capture_%u", chn + 1);
170 
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;
175  }
176  //port = fGraphManager->GetPort(port_index);
177 
178  netj.capture_ports =
179  jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index);
180  }
181 
182  for (chn = 0; chn < netj.playback_channels_audio; chn++) {
183  snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1);
184 
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;
189  }
190  //port = fGraphManager->GetPort(port_index);
191 
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
225  }
226  }
227  for (chn = netj.playback_channels_audio; chn < netj.playback_channels; chn++) {
228  snprintf (buf, sizeof(buf) - 1, "system:playback_%u", chn + 1);
229 
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;
234  }
235  //port = fGraphManager->GetPort(port_index);
236 
237  netj.playback_ports =
238  jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index);
239  }
240  return 0;
241 }
242 
243 //init and restart--------------------------------------------------------------------
244 bool JackNetOneDriver::Initialize()
245 {
246  jack_log("JackNetOneDriver::Init");
247 
248  FreePorts();
249  netjack_release(&netj);
250 
251  //display some additional infos
252  jack_info("NetOne driver started");
253  if (netjack_startup(&netj)) {
254  return false;
255  }
256 
257  //register jack ports
258  if (AllocPorts() != 0) {
259  jack_error("Can't allocate ports.");
260  return false;
261  }
262 
263  //monitor
264  //driver parametering
265  JackTimedDriver::SetBufferSize(netj.period_size);
266  JackTimedDriver::SetSampleRate(netj.sample_rate);
267 
268  JackDriver::NotifyBufferSize(netj.period_size);
269  JackDriver::NotifySampleRate(netj.sample_rate);
270 
271  //transport engine parametering
272  fEngineControl->fTransport.SetNetworkSync(true);
273  return true;
274 }
275 
276 
277 //jack ports and buffers--------------------------------------------------------------
278 
279 //driver processes--------------------------------------------------------------------
280 
281 int JackNetOneDriver::Read()
282 {
283  int delay;
284  delay = netjack_wait(&netj);
285  if (delay) {
286  NotifyXRun(fBeginDateUst, (float) delay);
287  jack_error("netxruns... duration: %dms", delay / 1000);
288  }
289 
290  if ((netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2)
291  JackTools::ThrowJackNetException();
292 
293  //netjack_read(&netj, netj.period_size);
294  JackDriver::CycleTakeBeginTime();
295 
296  jack_position_t local_trans_pos;
297  jack_transport_state_t local_trans_state;
298 
299  unsigned int *packet_buf, *packet_bufX;
300 
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;
305  }
306  packet_buf = netj.rx_buf;
307 
308  jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf;
309 
310  packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
311 
312  netj.reply_port = pkthdr->reply_port;
313  netj.latency = pkthdr->latency;
314 
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);
320 
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);
325 
326  // read local transport info....
327  //local_trans_state = jack_transport_query(netj.client, &local_trans_pos);
328 
329  local_trans_state = fEngineControl->fTransport.Query(&local_trans_pos);
330 
331  // Now check if we have to start or stop local transport to sync to remote...
332  switch (pkthdr->transport_state) {
333 
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...");
342  }
343 
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;
348 
349 
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);
355  }
356  break;
357 
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);
367  }
368  if (local_trans_state != JackTransportStopped)
369  //jack_transport_stop(netj.client);
370  fEngineControl->fTransport.SetCommand(TransportCommandStop);
371  break;
372 
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;
382 
383  case JackTransportLooping:
384  break;
385  }
386 #endif
387  }
388 
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;
392 }
393 
394 int JackNetOneDriver::Write()
395 {
396  int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0);
397  uint32_t *packet_buf, *packet_bufX;
398 
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;
401 
402  packet_buf = (uint32_t *) alloca(packet_size);
403  pkthdr = (jacknet_packet_header *)packet_buf;
404 
405  if (netj.running_free) {
406  return 0;
407  }
408 
409  // offset packet_bufX by the packetheader.
410  packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
411 
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;
416 
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);
418 
419  packet_header_hton(pkthdr);
420  if (netj.srcaddress_valid) {
421  unsigned int r;
422  static const int flag = 0;
423 
424  if (netj.reply_port)
425  netj.syncsource_address.sin_port = htons(netj.reply_port);
426 
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);
430  }
431  return 0;
432 }
433 
434 void
435 JackNetOneDriver::FreePorts ()
436 {
437  JSList *node = netj.capture_ports;
438 
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);
445  }
446  netj.capture_ports = NULL;
447 
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);
455  }
456  netj.playback_ports = NULL;
457 
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);
467  }
468  netj.playback_srcs = NULL;
469 
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);
477  }
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);
489  }
490  netj.playback_srcs = NULL;
491 
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);
499  }
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);
511  }
512  netj.playback_srcs = NULL;
513 
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);
521  }
522  netj.capture_srcs = NULL;
523 #endif
524  }
525 }
526 
527 //Render functions--------------------------------------------------------------------
528 
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)
532 {
533  uint32_t chn = 0;
534  JSList *node = capture_ports;
535 #if HAVE_SAMPLERATE
536  JSList *src_node = capture_srcs;
537 #endif
538 
539  uint32_t *packet_bufX = (uint32_t *)packet_payload;
540 
541  if (!packet_payload)
542  return;
543 
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);
552 
553  jack_default_audio_sample_t* buf =
554  (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
555 
556  const char *porttype = port->GetType();
557 
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]);
565  }
566 
567  src.data_in = (float *) packet_bufX;
568  src.input_frames = net_period_down;
569 
570  src.data_out = buf;
571  src.output_frames = nframes;
572 
573  src.src_ratio = (float) nframes / (float) net_period_down;
574  src.end_of_input = 0;
575 
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
581  {
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;
589  }
590  }
591  }
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);
598  }
599  packet_bufX = (packet_bufX + net_period_down);
600  node = jack_slist_next (node);
601  chn++;
602  }
603 }
604 
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)
607 {
608  uint32_t chn = 0;
609  JSList *node = playback_ports;
610 #if HAVE_SAMPLERATE
611  JSList *src_node = playback_srcs;
612 #endif
613 
614  uint32_t *packet_bufX = (uint32_t *) packet_payload;
615 
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);
624 
625  jack_default_audio_sample_t* buf =
626  (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
627 
628  const char *porttype = port->GetType();
629 
630  if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
631  // audio port, resample if necessary
632 
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;
638 
639  src.data_out = (float *) packet_bufX;
640  src.output_frames = net_period_up;
641 
642  src.src_ratio = (float) net_period_up / (float) nframes;
643  src.end_of_input = 0;
644 
645  src_set_ratio (src_state, src.src_ratio);
646  src_process (src_state, &src);
647 
648  for (i = 0; i < net_period_up; i++) {
649  packet_bufX[i] = htonl (packet_bufX[i]);
650  }
651  src_node = jack_slist_next (src_node);
652  } else
653 #endif
654  {
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;
662  }
663  }
664  }
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);
671  }
672  packet_bufX = (packet_bufX + net_period_up);
673  node = jack_slist_next (node);
674  chn++;
675  }
676 }
677 
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)
682 {
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;
687 
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);
691 
692  jack_default_audio_sample_t* buf =
693  (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
694 
695  const char *portname = port->GetType();
696 
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;
700 
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
712 
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);
721  }
722  packet_bufX = (packet_bufX + net_period_down);
723  node = jack_slist_next (node);
724  chn++;
725  }
726 }
727 
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)
730 {
731  uint32_t chn = 0;
732  JSList *node = playback_ports;
733  JSList *src_node = playback_srcs;
734 
735  unsigned char *packet_bufX = (unsigned char *)packet_payload;
736 
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);
740 
741  jack_default_audio_sample_t* buf =
742  (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
743 
744  const char *portname = port->GetType();
745 
746  if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
747  // audio port, encode celt data.
748 
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);
767  }
768  packet_bufX = (packet_bufX + net_period_up);
769  node = jack_slist_next (node);
770  chn++;
771  }
772 }
773 
774 #endif
775 
776 #if HAVE_OPUS
777 #define CDO (sizeof(short))
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)
781 {
782  int chn = 0;
783  JSList *node = capture_ports;
784  JSList *src_node = capture_srcs;
785 
786  unsigned char *packet_bufX = (unsigned char *)packet_payload;
787 
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);
791 
792  jack_default_audio_sample_t* buf =
793  (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
794 
795  const char *portname = port->GetType();
796 
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 );
807  }
808 
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);
817  }
818  packet_bufX = (packet_bufX + net_period_down);
819  node = jack_slist_next (node);
820  chn++;
821  }
822 }
823 
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)
826 {
827  int chn = 0;
828  JSList *node = playback_ports;
829  JSList *src_node = playback_srcs;
830 
831  unsigned char *packet_bufX = (unsigned char *)packet_payload;
832 
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);
836 
837  jack_default_audio_sample_t* buf =
838  (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize);
839 
840  const char *portname = port->GetType();
841 
842  if (strncmp (portname, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size()) == 0) {
843  // audio port, encode opus data.
844 
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);
859  }
860  packet_bufX = (packet_bufX + net_period_up);
861  node = jack_slist_next (node);
862  chn++;
863  }
864 }
865 #endif
866 
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)
870 {
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);
882 }
883 
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)
886 {
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);
898 }
899 
900 //driver loader-----------------------------------------------------------------------
901 
902 #ifdef __cplusplus
903 extern "C"
904 {
905 #endif
906 
907  SERVER_EXPORT jack_driver_desc_t* driver_get_descriptor ()
908  {
909  jack_driver_desc_t * desc;
912 
913  desc = jack_driver_descriptor_construct("netone", JackDriverMaster, "netjack one slave backend component", &filler);
914 
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);
918 
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);
922 
923  value.ui = 48000U;
924  jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
925 
926  value.ui = 1024U;
927  jack_driver_descriptor_add_parameter(desc, &filler, "period", 'p', JackDriverParamUInt, &value, NULL, "Frames per period", NULL);
928 
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);
931 
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);
934 
935  value.ui = 1U;
936  jack_driver_descriptor_add_parameter(desc, &filler, "factor", 'f', JackDriverParamUInt, &value, NULL, "Factor for sample rate reduction", NULL);
937 
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);
940 
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);
951 
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);
954 
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);
957 
958  value.ui = 1U;
959  jack_driver_descriptor_add_parameter(desc, &filler, "redundancy", 'R', JackDriverParamUInt, &value, NULL, "Send packets N times", NULL);
960 
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);
963 
964  value.i = 0;
965  jack_driver_descriptor_add_parameter(desc, &filler, "jitterval", 'J', JackDriverParamInt, &value, NULL, "Attempted jitterbuffer microseconds on master", NULL);
966 
967  value.i = false;
968  jack_driver_descriptor_add_parameter(desc, &filler, "always-deadline", 'D', JackDriverParamBool, &value, NULL, "Always use deadline", NULL);
969 
970  return desc;
971  }
972 
973  SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params)
974  {
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;
997 
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;
1004 
1005  case 'o':
1006  playback_ports = param->value.ui;
1007  break;
1008 
1009  case 'I':
1010  capture_ports_midi = param->value.ui;
1011  break;
1012 
1013  case 'O':
1014  playback_ports_midi = param->value.ui;
1015  break;
1016 
1017  case 'r':
1018  sample_rate = param->value.ui;
1019  break;
1020 
1021  case 'p':
1022  period_size = param->value.ui;
1023  break;
1024 
1025  case 'l':
1026  listen_port = param->value.ui;
1027  break;
1028 
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;
1037 
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;
1046 
1047  case 'b':
1048  bitdepth = param->value.ui;
1049  break;
1050 
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;
1060 
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;
1071 
1072  case 't':
1073  handle_transport_sync = param->value.ui;
1074  break;
1075 
1076  case 'a':
1077  use_autoconfig = param->value.ui;
1078  break;
1079 
1080  case 'n':
1081  latency = param->value.ui;
1082  break;
1083 
1084  case 'R':
1085  redundancy = param->value.ui;
1086  break;
1087 
1088  case 'H':
1089  dont_htonl_floats = param->value.ui;
1090  break;
1091 
1092  case 'J':
1093  jitter_val = param->value.i;
1094  break;
1095 
1096  case 'D':
1097  always_deadline = param->value.ui;
1098  break;
1099  }
1100  }
1101 
1102  try {
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));
1109 
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;
1116  }
1117 
1118  } catch (...) {
1119  return NULL;
1120  }
1121  }
1122 
1123 #ifdef __cplusplus
1124 }
1125 #endif
1126 }
To be used as a wrapper of JackNetDriver.
Inter process synchronization using using Mach semaphore.
Locked Engine, access to methods is serialized using a mutex.
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:91
jack_position_bits_t valid
Definition: types.h:561
SERVER_EXPORT void jack_info(const char *fmt,...)
Definition: JackError.cpp:99
LIB_EXPORT int jack_port_type_size(void)
Definition: JackAPI.cpp:1442
jack_nframes_t frame
Definition: types.h:559
The base interface for drivers clients.
Definition: JackDriver.h:122
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:107