2 Copyright (C) 2018 Karl Linden <karl.j.linden@gmail.com>
3 Copyright (C) 2008-2011 Torben Horn
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.
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.
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.
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"
31 #include "netjack_packet.h"
34 #include <samplerate.h>
38 #include <celt/celt.h>
42 #include <opus/opus.h>
43 #include <opus/opus_custom.h>
46 #define MIN(x,y) ((x)<(y) ? (x) : (y))
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
)
59 jack_log("JackNetOneDriver::JackNetOneDriver port %d", port
);
63 WSAStartup(MAKEWORD(2, 0), &wsa
);
66 netjack_init(& (this->netj
),
88 JackNetOneDriver::~JackNetOneDriver()
93 //open, close, attach and detach------------------------------------------------------
95 int JackNetOneDriver::Close()
97 // Generic audio driver close
98 int res
= JackWaiterDriver::Close();
101 netjack_release(&netj
);
105 int JackNetOneDriver::Attach()
110 int JackNetOneDriver::Detach()
115 int JackNetOneDriver::AllocPorts()
117 jack_port_id_t port_index
;
121 //if (netj.handle_transport_sync)
122 // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL);
124 for (chn
= 0; chn
< netj
.capture_channels_audio
; chn
++) {
125 snprintf (buf
, sizeof(buf
) - 1, "system:capture_%u", chn
+ 1);
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
);
132 //port = fGraphManager->GetPort(port_index);
134 netj
.capture_ports
= jack_slist_append (netj
.capture_ports
, (void *)(intptr_t)port_index
);
136 if (netj
.bitdepth
== CELT_MODE
) {
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
));
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
));
151 celt_mode_info(celt_mode
, CELT_GET_LOOKAHEAD
, &lookahead
);
152 netj
.codec_latency
= 2 * lookahead
;
154 } else if (netj
.bitdepth
== OPUS_MODE
) {
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
);
162 netj
.capture_srcs
= jack_slist_append(netj
.capture_srcs
, (void *)src_new(SRC_LINEAR
, 1, NULL
));
167 for (chn
= netj
.capture_channels_audio
; chn
< netj
.capture_channels
; chn
++) {
168 snprintf (buf
, sizeof(buf
) - 1, "system:capture_%u", chn
+ 1);
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
);
175 //port = fGraphManager->GetPort(port_index);
178 jack_slist_append (netj
.capture_ports
, (void *)(intptr_t)port_index
);
181 for (chn
= 0; chn
< netj
.playback_channels_audio
; chn
++) {
182 snprintf (buf
, sizeof(buf
) - 1, "system:playback_%u", chn
+ 1);
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
);
189 //port = fGraphManager->GetPort(port_index);
191 netj
.playback_ports
= jack_slist_append (netj
.playback_ports
, (void *)(intptr_t)port_index
);
192 if (netj
.bitdepth
== CELT_MODE
) {
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
));
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
));
205 } else if (netj
.bitdepth
== OPUS_MODE
) {
207 const int kbps
= netj
.resample_factor
;
208 jack_error("NEW ONE OPUS ENCODER 128 <> %d!!", kbps
);
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
);
222 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, (void *)src_new(SRC_LINEAR
, 1, NULL
));
226 for (chn
= netj
.playback_channels_audio
; chn
< netj
.playback_channels
; chn
++) {
227 snprintf (buf
, sizeof(buf
) - 1, "system:playback_%u", chn
+ 1);
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
);
234 //port = fGraphManager->GetPort(port_index);
236 netj
.playback_ports
=
237 jack_slist_append (netj
.playback_ports
, (void *)(intptr_t)port_index
);
242 //init and restart--------------------------------------------------------------------
243 bool JackNetOneDriver::Initialize()
245 jack_log("JackNetOneDriver::Init");
248 netjack_release(&netj
);
250 //display some additional infos
251 jack_info("NetOne driver started");
252 if (netjack_startup(&netj
)) {
256 //register jack ports
257 if (AllocPorts() != 0) {
258 jack_error("Can't allocate ports.");
263 //driver parametering
264 JackTimedDriver::SetBufferSize(netj
.period_size
);
265 JackTimedDriver::SetSampleRate(netj
.sample_rate
);
267 JackDriver::NotifyBufferSize(netj
.period_size
);
268 JackDriver::NotifySampleRate(netj
.sample_rate
);
270 //transport engine parametering
271 fEngineControl
->fTransport
.SetNetworkSync(true);
276 //jack ports and buffers--------------------------------------------------------------
278 //driver processes--------------------------------------------------------------------
280 int JackNetOneDriver::Read()
283 delay
= netjack_wait(&netj
);
285 NotifyXRun(fBeginDateUst
, (float) delay
);
286 jack_error("netxruns... duration: %dms", delay
/ 1000);
289 if ((netj
.num_lost_packets
* netj
.period_size
/ netj
.sample_rate
) > 2)
290 throw JackNetException();
292 //netjack_read(&netj, netj.period_size);
293 JackDriver::CycleTakeBeginTime();
295 jack_position_t local_trans_pos
;
296 jack_transport_state_t local_trans_state
;
298 unsigned int *packet_buf
, *packet_bufX
;
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
);
305 packet_buf
= netj
.rx_buf
;
307 jacknet_packet_header
*pkthdr
= (jacknet_packet_header
*)packet_buf
;
309 packet_bufX
= packet_buf
+ sizeof(jacknet_packet_header
) / sizeof(jack_default_audio_sample_t
);
311 netj
.reply_port
= pkthdr
->reply_port
;
312 netj
.latency
= pkthdr
->latency
;
314 // Special handling for latency=0
315 if (netj
.latency
== 0)
316 netj
.resync_threshold
= 0;
318 netj
.resync_threshold
= MIN(15, pkthdr
->latency
- 1);
320 // check whether, we should handle the transport sync stuff, or leave trnasports untouched.
321 if (netj
.handle_transport_sync
) {
323 unsigned int compensated_tranport_pos
= (pkthdr
->transport_frame
+ (pkthdr
->latency
* netj
.period_size
) + netj
.codec_latency
);
325 // read local transport info....
326 //local_trans_state = jack_transport_query(netj.client, &local_trans_pos);
328 local_trans_state
= fEngineControl
->fTransport
.Query(&local_trans_pos
);
330 // Now check if we have to start or stop local transport to sync to remote...
331 switch (pkthdr
->transport_state
) {
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;
340 jack_info("locally stopped... starting...");
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;
349 fEngineControl
->fTransport
.RequestNewPos(&new_pos
);
350 //jack_transport_locate(netj.client, compensated_tranport_pos);
351 //last_transport_state = JackTransportRolling;
353 jack_info("starting locate to %d", compensated_tranport_pos
);
357 case JackTransportStopped
:
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
);
367 if (local_trans_state
!= JackTransportStopped
)
368 //jack_transport_stop(netj.client);
369 fEngineControl
->fTransport
.SetCommand(TransportCommandStop
);
372 case JackTransportRolling
:
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);
378 if (local_trans_state
!= JackTransportRolling
)
379 fEngineControl
->fTransport
.SetState(JackTransportRolling
);
382 case JackTransportLooping
:
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
);
393 int JackNetOneDriver::Write()
395 int syncstate
= netj
.sync_state
| ((fEngineControl
->fTransport
.GetState() == JackTransportNetStarting
) ? 1 : 0);
396 uint32_t *packet_buf
, *packet_bufX
;
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
;
401 packet_buf
= (uint32_t *) alloca(packet_size
);
402 pkthdr
= (jacknet_packet_header
*)packet_buf
;
404 if (netj
.running_free
) {
408 // offset packet_bufX by the packetheader.
409 packet_bufX
= packet_buf
+ sizeof(jacknet_packet_header
) / sizeof(jack_default_audio_sample_t
);
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
;
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
);
418 packet_header_hton(pkthdr
);
419 if (netj
.srcaddress_valid
) {
421 static const int flag
= 0;
424 netj
.syncsource_address
.sin_port
= htons(netj
.reply_port
);
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
);
434 JackNetOneDriver::FreePorts ()
436 JSList
*node
= netj
.capture_ports
;
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
);
445 netj
.capture_ports
= NULL
;
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
);
455 netj
.playback_ports
= NULL
;
457 if (netj
.bitdepth
== CELT_MODE
) {
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
);
467 netj
.playback_srcs
= NULL
;
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
);
477 netj
.capture_srcs
= NULL
;
479 } else if (netj
.bitdepth
== OPUS_MODE
) {
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
);
489 netj
.playback_srcs
= NULL
;
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
);
499 netj
.capture_srcs
= NULL
;
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
);
511 netj
.playback_srcs
= NULL
;
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
);
521 netj
.capture_srcs
= NULL
;
526 //Render functions--------------------------------------------------------------------
528 // render functions for float
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
)
533 JSList
*node
= capture_ports
;
535 JSList
*src_node
= capture_srcs
;
538 uint32_t *packet_bufX
= (uint32_t *)packet_payload
;
543 while (node
!= NULL
) {
549 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
550 JackPort
*port
= fGraphManager
->GetPort(port_index
);
552 jack_default_audio_sample_t
* buf
=
553 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
555 const char *porttype
= port
->GetType();
557 if (strncmp (porttype
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
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
]);
566 src
.data_in
= (float *) packet_bufX
;
567 src
.input_frames
= net_period_down
;
570 src
.output_frames
= nframes
;
572 src
.src_ratio
= (float) nframes
/ (float) net_period_down
;
573 src
.end_of_input
= 0;
575 src_set_ratio (src_state
, src
.src_ratio
);
576 src_process (src_state
, &src
);
577 src_node
= jack_slist_next (src_node
);
581 if (dont_htonl_floats
) {
582 memcpy(buf
, packet_bufX
, net_period_down
* sizeof(jack_default_audio_sample_t
));
584 for (i
= 0; i
< net_period_down
; i
++) {
585 val
.i
= packet_bufX
[i
];
586 val
.i
= ntohl (val
.i
);
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
);
598 packet_bufX
= (packet_bufX
+ net_period_down
);
599 node
= jack_slist_next (node
);
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
)
608 JSList
*node
= playback_ports
;
610 JSList
*src_node
= playback_srcs
;
613 uint32_t *packet_bufX
= (uint32_t *) packet_payload
;
615 while (node
!= NULL
) {
621 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
622 JackPort
*port
= fGraphManager
->GetPort(port_index
);
624 jack_default_audio_sample_t
* buf
=
625 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
627 const char *porttype
= port
->GetType();
629 if (strncmp (porttype
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
630 // audio port, resample if necessary
633 if (net_period_up
!= nframes
) {
634 SRC_STATE
*src_state
= (SRC_STATE
*) src_node
->data
;
636 src
.input_frames
= nframes
;
638 src
.data_out
= (float *) packet_bufX
;
639 src
.output_frames
= net_period_up
;
641 src
.src_ratio
= (float) net_period_up
/ (float) nframes
;
642 src
.end_of_input
= 0;
644 src_set_ratio (src_state
, src
.src_ratio
);
645 src_process (src_state
, &src
);
647 for (i
= 0; i
< net_period_up
; i
++) {
648 packet_bufX
[i
] = htonl (packet_bufX
[i
]);
650 src_node
= jack_slist_next (src_node
);
654 if (dont_htonl_floats
) {
655 memcpy(packet_bufX
, buf
, net_period_up
* sizeof(jack_default_audio_sample_t
));
657 for (i
= 0; i
< net_period_up
; i
++) {
659 val
.i
= htonl (val
.i
);
660 packet_bufX
[i
] = val
.i
;
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
);
671 packet_bufX
= (packet_bufX
+ net_period_up
);
672 node
= jack_slist_next (node
);
678 // render functions for celt.
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
)
683 JSList
*node
= capture_ports
;
684 JSList
*src_node
= capture_srcs
;
685 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
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
);
691 jack_default_audio_sample_t
* buf
=
692 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
694 const char *portname
= port
->GetType();
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
;
700 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
702 celt_decode_float(decoder
, NULL
, net_period_down
, buf
, nframes
);
704 celt_decode_float(decoder
, packet_bufX
, net_period_down
, buf
, nframes
);
707 celt_decode_float(decoder
, NULL
, net_period_down
, buf
);
709 celt_decode_float(decoder
, packet_bufX
, net_period_down
, buf
);
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
;
719 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
721 packet_bufX
= (packet_bufX
+ net_period_down
);
722 node
= jack_slist_next (node
);
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
)
731 JSList
*node
= playback_ports
;
732 JSList
*src_node
= playback_srcs
;
734 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
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
);
740 jack_default_audio_sample_t
* buf
=
741 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
743 const char *portname
= port
->GetType();
745 if (strncmp (portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
746 // audio port, encode celt data.
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
);
755 encoded_bytes
= celt_encode_float(encoder
, floatbuf
, NULL
, packet_bufX
, net_period_up
);
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
);
767 packet_bufX
= (packet_bufX
+ net_period_up
);
768 node
= jack_slist_next (node
);
776 #define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
777 // render functions for Opus.
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
)
782 JSList
*node
= capture_ports
;
783 JSList
*src_node
= capture_srcs
;
785 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
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
);
791 jack_default_audio_sample_t
* buf
=
792 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
794 const char *portname
= port
->GetType();
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));
803 memcpy(&len
, packet_bufX
, CDO
);
805 opus_custom_decode_float( decoder
, packet_bufX
+ CDO
, len
, buf
, nframes
);
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
;
815 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
817 packet_bufX
= (packet_bufX
+ net_period_down
);
818 node
= jack_slist_next (node
);
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
)
827 JSList
*node
= playback_ports
;
828 JSList
*src_node
= playback_srcs
;
830 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
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
);
836 jack_default_audio_sample_t
* buf
=
837 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
839 const char *portname
= port
->GetType();
841 if (strncmp (portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
842 // audio port, encode opus data.
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
);
859 packet_bufX
= (packet_bufX
+ net_period_up
);
860 node
= jack_slist_next (node
);
866 /* Wrapper functions with bitdepth argument... */
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
)
871 if (bitdepth
== CELT_MODE
)
872 render_payload_to_jack_ports_celt (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
);
876 if (bitdepth
== OPUS_MODE
)
877 render_payload_to_jack_ports_opus (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
);
880 render_payload_to_jack_ports_float (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
, dont_htonl_floats
);
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
)
887 if (bitdepth
== CELT_MODE
)
888 render_jack_ports_to_payload_celt (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
);
892 if (bitdepth
== OPUS_MODE
)
893 render_jack_ports_to_payload_opus (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
);
896 render_jack_ports_to_payload_float (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
, dont_htonl_floats
);
899 //driver loader-----------------------------------------------------------------------
906 SERVER_EXPORT jack_driver_desc_t
* driver_get_descriptor ()
908 jack_driver_desc_t
* desc
;
909 jack_driver_desc_filler_t filler
;
910 jack_driver_param_value_t value
;
912 desc
= jack_driver_descriptor_construct("netone", JackDriverMaster
, "netjack one slave backend component", &filler
);
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
);
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
);
923 jack_driver_descriptor_add_parameter(desc
, &filler
, "rate", 'r', JackDriverParamUInt
, &value
, NULL
, "Sample rate", NULL
);
926 jack_driver_descriptor_add_parameter(desc
, &filler
, "period", 'p', JackDriverParamUInt
, &value
, NULL
, "Frames per period", NULL
);
929 jack_driver_descriptor_add_parameter(desc
, &filler
, "num-periods", 'n', JackDriverParamUInt
, &value
, NULL
, "Network latency setting in no. of periods", NULL
);
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
);
935 jack_driver_descriptor_add_parameter(desc
, &filler
, "factor", 'f', JackDriverParamUInt
, &value
, NULL
, "Factor for sample rate reduction", NULL
);
938 jack_driver_descriptor_add_parameter(desc
, &filler
, "upstream-factor", 'u', JackDriverParamUInt
, &value
, NULL
, "Factor for sample rate reduction on the upstream", NULL
);
942 jack_driver_descriptor_add_parameter(desc
, &filler
, "celt", 'c', JackDriverParamUInt
, &value
, NULL
, "Set CELT encoding and number of kbits per channel", NULL
);
946 jack_driver_descriptor_add_parameter(desc
, &filler
, "opus", 'P', JackDriverParamUInt
, &value
, NULL
, "Set Opus encoding and number of kbits per channel", NULL
);
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
);
952 jack_driver_descriptor_add_parameter(desc
, &filler
, "transport-sync", 't', JackDriverParamBool
, &value
, NULL
, "Whether to slave the transport to the master transport", NULL
);
955 jack_driver_descriptor_add_parameter(desc
, &filler
, "autoconf", 'a', JackDriverParamBool
, &value
, NULL
, "Whether to use Autoconfig, or just start", NULL
);
958 jack_driver_descriptor_add_parameter(desc
, &filler
, "redundancy", 'R', JackDriverParamUInt
, &value
, NULL
, "Send packets N times", NULL
);
961 jack_driver_descriptor_add_parameter(desc
, &filler
, "native-endian", 'e', JackDriverParamBool
, &value
, NULL
, "Don't convert samples to network byte order", NULL
);
964 jack_driver_descriptor_add_parameter(desc
, &filler
, "jitterval", 'J', JackDriverParamInt
, &value
, NULL
, "Attempted jitterbuffer microseconds on master", NULL
);
967 jack_driver_descriptor_add_parameter(desc
, &filler
, "always-deadline", 'D', JackDriverParamBool
, &value
, NULL
, "Always use deadline", NULL
);
972 SERVER_EXPORT
Jack::JackDriverClientInterface
* driver_initialize(Jack::JackLockedEngine
* engine
, Jack::JackSynchro
* table
, const JSList
* params
)
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;
989 unsigned int resample_factor_up
= 1;
991 int dont_htonl_floats
= 0;
992 int always_deadline
= 0;
995 const jack_driver_param_t
* param
;
997 for (node
= params
; node
; node
= jack_slist_next(node
)) {
998 param
= (const jack_driver_param_t
*) node
->data
;
999 switch (param
->character
) {
1001 capture_ports
= param
->value
.ui
;
1005 playback_ports
= param
->value
.ui
;
1009 capture_ports_midi
= param
->value
.ui
;
1013 playback_ports_midi
= param
->value
.ui
;
1017 sample_rate
= param
->value
.ui
;
1021 period_size
= param
->value
.ui
;
1025 listen_port
= param
->value
.ui
;
1030 resample_factor
= param
->value
.ui
;
1032 jack_error("not built with libsamplerate support");
1039 resample_factor_up
= param
->value
.ui
;
1041 jack_error("not built with libsamplerate support");
1047 bitdepth
= param
->value
.ui
;
1052 bitdepth
= CELT_MODE
;
1053 resample_factor
= param
->value
.ui
;
1055 jack_error("not built with celt support");
1062 bitdepth
= OPUS_MODE
;
1063 resample_factor
= param
->value
.ui
;
1064 jack_error("OPUS: %d\n", resample_factor
);
1066 jack_error("not built with Opus support");
1072 handle_transport_sync
= param
->value
.ui
;
1076 use_autoconfig
= param
->value
.ui
;
1080 latency
= param
->value
.ui
;
1084 redundancy
= param
->value
.ui
;
1088 dont_htonl_floats
= param
->value
.ui
;
1092 jitter_val
= param
->value
.i
;
1096 always_deadline
= param
->value
.ui
;
1102 Jack::JackDriverClientInterface
* driver
= new Jack::JackWaitThreadedDriver (
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
));
1109 if (driver
->Open(period_size
, sample_rate
, 1, 1, capture_ports
, playback_ports
,
1110 0, "from_master", "to_master", 0, 0) == 0) {
1123 (void)resample_factor_up
;