2 Copyright (C) 2008-2011 Torben Horn
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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"
32 #include "netjack_packet.h"
35 #include <samplerate.h>
39 #include <celt/celt.h>
43 #include <opus/opus.h>
44 #include <opus/opus_custom.h>
47 #define MIN(x,y) ((x)<(y) ? (x) : (y))
53 JackNetOneDriver::JackNetOneDriver(const char* name
, const char* alias
, JackLockedEngine
* engine
, JackSynchro
* table
,
54 int port
, int mtu
, int capture_ports
, int playback_ports
, int midi_input_ports
, int midi_output_ports
,
55 int sample_rate
, int period_size
, int resample_factor
,
56 const char* net_name
, uint transport_sync
, int bitdepth
, int use_autoconfig
,
57 int latency
, int redundancy
, int dont_htonl_floats
, int always_deadline
, int jitter_val
)
58 : JackWaiterDriver(name
, alias
, engine
, table
)
60 jack_log("JackNetOneDriver::JackNetOneDriver port %d", port
);
64 WSAStartup(MAKEWORD(2, 0), &wsa
);
67 netjack_init(& (this->netj
),
89 JackNetOneDriver::~JackNetOneDriver()
94 //open, close, attach and detach------------------------------------------------------
96 int JackNetOneDriver::Close()
98 // Generic audio driver close
99 int res
= JackWaiterDriver::Close();
102 netjack_release(&netj
);
106 int JackNetOneDriver::Attach()
111 int JackNetOneDriver::Detach()
116 int JackNetOneDriver::AllocPorts()
118 jack_port_id_t port_index
;
122 //if (netj.handle_transport_sync)
123 // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL);
125 for (chn
= 0; chn
< netj
.capture_channels_audio
; chn
++) {
126 snprintf (buf
, sizeof(buf
) - 1, "system:capture_%u", chn
+ 1);
128 if (fEngine
->PortRegister(fClientControl
.fRefNum
, buf
, JACK_DEFAULT_AUDIO_TYPE
,
129 CaptureDriverFlags
, fEngineControl
->fBufferSize
, &port_index
) < 0) {
130 jack_error("driver: cannot register port for %s", buf
);
133 //port = fGraphManager->GetPort(port_index);
135 netj
.capture_ports
= jack_slist_append (netj
.capture_ports
, (void *)(intptr_t)port_index
);
137 if (netj
.bitdepth
== CELT_MODE
) {
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
));
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
));
152 celt_mode_info(celt_mode
, CELT_GET_LOOKAHEAD
, &lookahead
);
153 netj
.codec_latency
= 2 * lookahead
;
155 } else if (netj
.bitdepth
== OPUS_MODE
) {
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
);
163 netj
.capture_srcs
= jack_slist_append(netj
.capture_srcs
, (void *)src_new(SRC_LINEAR
, 1, NULL
));
168 for (chn
= netj
.capture_channels_audio
; chn
< netj
.capture_channels
; chn
++) {
169 snprintf (buf
, sizeof(buf
) - 1, "system:capture_%u", chn
+ 1);
171 if (fEngine
->PortRegister(fClientControl
.fRefNum
, buf
, JACK_DEFAULT_MIDI_TYPE
,
172 CaptureDriverFlags
, fEngineControl
->fBufferSize
, &port_index
) < 0) {
173 jack_error("driver: cannot register port for %s", buf
);
176 //port = fGraphManager->GetPort(port_index);
179 jack_slist_append (netj
.capture_ports
, (void *)(intptr_t)port_index
);
182 for (chn
= 0; chn
< netj
.playback_channels_audio
; chn
++) {
183 snprintf (buf
, sizeof(buf
) - 1, "system:playback_%u", chn
+ 1);
185 if (fEngine
->PortRegister(fClientControl
.fRefNum
, buf
, JACK_DEFAULT_AUDIO_TYPE
,
186 PlaybackDriverFlags
, fEngineControl
->fBufferSize
, &port_index
) < 0) {
187 jack_error("driver: cannot register port for %s", buf
);
190 //port = fGraphManager->GetPort(port_index);
192 netj
.playback_ports
= jack_slist_append (netj
.playback_ports
, (void *)(intptr_t)port_index
);
193 if (netj
.bitdepth
== CELT_MODE
) {
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
));
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
));
206 } else if (netj
.bitdepth
== OPUS_MODE
) {
208 const int kbps
= netj
.resample_factor
;
209 jack_error("NEW ONE OPUS ENCODER 128 <> %d!!", kbps
);
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
);
223 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, (void *)src_new(SRC_LINEAR
, 1, NULL
));
227 for (chn
= netj
.playback_channels_audio
; chn
< netj
.playback_channels
; chn
++) {
228 snprintf (buf
, sizeof(buf
) - 1, "system:playback_%u", chn
+ 1);
230 if (fEngine
->PortRegister(fClientControl
.fRefNum
, buf
, JACK_DEFAULT_MIDI_TYPE
,
231 PlaybackDriverFlags
, fEngineControl
->fBufferSize
, &port_index
) < 0) {
232 jack_error("driver: cannot register port for %s", buf
);
235 //port = fGraphManager->GetPort(port_index);
237 netj
.playback_ports
=
238 jack_slist_append (netj
.playback_ports
, (void *)(intptr_t)port_index
);
243 //init and restart--------------------------------------------------------------------
244 bool JackNetOneDriver::Initialize()
246 jack_log("JackNetOneDriver::Init");
249 netjack_release(&netj
);
251 //display some additional infos
252 jack_info("NetOne driver started");
253 if (netjack_startup(&netj
)) {
257 //register jack ports
258 if (AllocPorts() != 0) {
259 jack_error("Can't allocate ports.");
264 //driver parametering
265 JackTimedDriver::SetBufferSize(netj
.period_size
);
266 JackTimedDriver::SetSampleRate(netj
.sample_rate
);
268 JackDriver::NotifyBufferSize(netj
.period_size
);
269 JackDriver::NotifySampleRate(netj
.sample_rate
);
271 //transport engine parametering
272 fEngineControl
->fTransport
.SetNetworkSync(true);
277 //jack ports and buffers--------------------------------------------------------------
279 //driver processes--------------------------------------------------------------------
281 int JackNetOneDriver::Read()
284 delay
= netjack_wait(&netj
);
286 NotifyXRun(fBeginDateUst
, (float) delay
);
287 jack_error("netxruns... duration: %dms", delay
/ 1000);
290 if ((netj
.num_lost_packets
* netj
.period_size
/ netj
.sample_rate
) > 2)
291 JackTools::ThrowJackNetException();
293 //netjack_read(&netj, netj.period_size);
294 JackDriver::CycleTakeBeginTime();
296 jack_position_t local_trans_pos
;
297 jack_transport_state_t local_trans_state
;
299 unsigned int *packet_buf
, *packet_bufX
;
301 if (! netj
.packet_data_valid
) {
302 jack_log("data not valid");
303 render_payload_to_jack_ports (netj
.bitdepth
, NULL
, netj
.net_period_down
, netj
.capture_ports
, netj
.capture_srcs
, netj
.period_size
, netj
.dont_htonl_floats
);
306 packet_buf
= netj
.rx_buf
;
308 jacknet_packet_header
*pkthdr
= (jacknet_packet_header
*)packet_buf
;
310 packet_bufX
= packet_buf
+ sizeof(jacknet_packet_header
) / sizeof(jack_default_audio_sample_t
);
312 netj
.reply_port
= pkthdr
->reply_port
;
313 netj
.latency
= pkthdr
->latency
;
315 // Special handling for latency=0
316 if (netj
.latency
== 0)
317 netj
.resync_threshold
= 0;
319 netj
.resync_threshold
= MIN(15, pkthdr
->latency
- 1);
321 // check whether, we should handle the transport sync stuff, or leave trnasports untouched.
322 if (netj
.handle_transport_sync
) {
324 unsigned int compensated_tranport_pos
= (pkthdr
->transport_frame
+ (pkthdr
->latency
* netj
.period_size
) + netj
.codec_latency
);
326 // read local transport info....
327 //local_trans_state = jack_transport_query(netj.client, &local_trans_pos);
329 local_trans_state
= fEngineControl
->fTransport
.Query(&local_trans_pos
);
331 // Now check if we have to start or stop local transport to sync to remote...
332 switch (pkthdr
->transport_state
) {
334 case JackTransportStarting
:
335 // the master transport is starting... so we set our reply to the sync_callback;
336 if (local_trans_state
== JackTransportStopped
) {
337 fEngineControl
->fTransport
.SetCommand(TransportCommandStart
);
338 //jack_transport_start(netj.client);
339 //last_transport_state = JackTransportStopped;
341 jack_info("locally stopped... starting...");
344 if (local_trans_pos
.frame
!= compensated_tranport_pos
) {
345 jack_position_t new_pos
= local_trans_pos
;
346 new_pos
.frame
= compensated_tranport_pos
+ 2 * netj
.period_size
;
347 new_pos
.valid
= (jack_position_bits_t
) 0;
350 fEngineControl
->fTransport
.RequestNewPos(&new_pos
);
351 //jack_transport_locate(netj.client, compensated_tranport_pos);
352 //last_transport_state = JackTransportRolling;
354 jack_info("starting locate to %d", compensated_tranport_pos
);
358 case JackTransportStopped
:
360 if (local_trans_pos
.frame
!= (pkthdr
->transport_frame
)) {
361 jack_position_t new_pos
= local_trans_pos
;
362 new_pos
.frame
= pkthdr
->transport_frame
;
363 new_pos
.valid
= (jack_position_bits_t
)0;
364 fEngineControl
->fTransport
.RequestNewPos(&new_pos
);
365 //jack_transport_locate(netj.client, (pkthdr->transport_frame));
366 jack_info("transport is stopped locate to %d", pkthdr
->transport_frame
);
368 if (local_trans_state
!= JackTransportStopped
)
369 //jack_transport_stop(netj.client);
370 fEngineControl
->fTransport
.SetCommand(TransportCommandStop
);
373 case JackTransportRolling
:
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);
379 if (local_trans_state
!= JackTransportRolling
)
380 fEngineControl
->fTransport
.SetState(JackTransportRolling
);
383 case JackTransportLooping
:
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
);
394 int JackNetOneDriver::Write()
396 int syncstate
= netj
.sync_state
| ((fEngineControl
->fTransport
.GetState() == JackTransportNetStarting
) ? 1 : 0);
397 uint32_t *packet_buf
, *packet_bufX
;
399 int packet_size
= get_sample_size(netj
.bitdepth
) * netj
.playback_channels
* netj
.net_period_up
+ sizeof(jacknet_packet_header
);
400 jacknet_packet_header
*pkthdr
;
402 packet_buf
= (uint32_t *) alloca(packet_size
);
403 pkthdr
= (jacknet_packet_header
*)packet_buf
;
405 if (netj
.running_free
) {
409 // offset packet_bufX by the packetheader.
410 packet_bufX
= packet_buf
+ sizeof(jacknet_packet_header
) / sizeof(jack_default_audio_sample_t
);
412 pkthdr
->sync_state
= syncstate
;;
413 pkthdr
->latency
= netj
.time_to_deadline
;
414 //printf("time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness);
415 pkthdr
->framecnt
= netj
.expected_framecnt
;
417 render_jack_ports_to_payload(netj
.bitdepth
, netj
.playback_ports
, netj
.playback_srcs
, netj
.period_size
, packet_bufX
, netj
.net_period_up
, netj
.dont_htonl_floats
);
419 packet_header_hton(pkthdr
);
420 if (netj
.srcaddress_valid
) {
422 static const int flag
= 0;
425 netj
.syncsource_address
.sin_port
= htons(netj
.reply_port
);
427 for (r
= 0; r
< netj
.redundancy
; r
++)
428 netjack_sendto(netj
.sockfd
, (char *)packet_buf
, packet_size
,
429 flag
, (struct sockaddr
*) & (netj
.syncsource_address
), sizeof(struct sockaddr_in
), netj
.mtu
);
435 JackNetOneDriver::FreePorts ()
437 JSList
*node
= netj
.capture_ports
;
439 while (node
!= NULL
) {
440 JSList
*this_node
= node
;
441 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
442 node
= jack_slist_remove_link(node
, this_node
);
443 jack_slist_free_1(this_node
);
444 fEngine
->PortUnRegister(fClientControl
.fRefNum
, port_index
);
446 netj
.capture_ports
= NULL
;
448 node
= netj
.playback_ports
;
449 while (node
!= NULL
) {
450 JSList
*this_node
= node
;
451 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
452 node
= jack_slist_remove_link(node
, this_node
);
453 jack_slist_free_1(this_node
);
454 fEngine
->PortUnRegister(fClientControl
.fRefNum
, port_index
);
456 netj
.playback_ports
= NULL
;
458 if (netj
.bitdepth
== CELT_MODE
) {
460 node
= netj
.playback_srcs
;
461 while (node
!= NULL
) {
462 JSList
*this_node
= node
;
463 CELTEncoder
*enc
= (CELTEncoder
*) node
->data
;
464 node
= jack_slist_remove_link(node
, this_node
);
465 jack_slist_free_1(this_node
);
466 celt_encoder_destroy(enc
);
468 netj
.playback_srcs
= NULL
;
470 node
= netj
.capture_srcs
;
471 while (node
!= NULL
) {
472 JSList
*this_node
= node
;
473 CELTDecoder
*dec
= (CELTDecoder
*) node
->data
;
474 node
= jack_slist_remove_link(node
, this_node
);
475 jack_slist_free_1(this_node
);
476 celt_decoder_destroy(dec
);
478 netj
.capture_srcs
= NULL
;
480 } else if (netj
.bitdepth
== OPUS_MODE
) {
482 node
= netj
.playback_srcs
;
483 while (node
!= NULL
) {
484 JSList
*this_node
= node
;
485 OpusCustomEncoder
*enc
= (OpusCustomEncoder
*) node
->data
;
486 node
= jack_slist_remove_link(node
, this_node
);
487 jack_slist_free_1(this_node
);
488 opus_custom_encoder_destroy(enc
);
490 netj
.playback_srcs
= NULL
;
492 node
= netj
.capture_srcs
;
493 while (node
!= NULL
) {
494 JSList
*this_node
= node
;
495 OpusCustomDecoder
*dec
= (OpusCustomDecoder
*) node
->data
;
496 node
= jack_slist_remove_link(node
, this_node
);
497 jack_slist_free_1(this_node
);
498 opus_custom_decoder_destroy(dec
);
500 netj
.capture_srcs
= NULL
;
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
);
512 netj
.playback_srcs
= NULL
;
514 node
= netj
.capture_srcs
;
515 while (node
!= NULL
) {
516 JSList
*this_node
= node
;
517 SRC_STATE
*state
= (SRC_STATE
*) node
->data
;
518 node
= jack_slist_remove_link(node
, this_node
);
519 jack_slist_free_1(this_node
);
522 netj
.capture_srcs
= NULL
;
527 //Render functions--------------------------------------------------------------------
529 // render functions for float
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
)
534 JSList
*node
= capture_ports
;
536 JSList
*src_node
= capture_srcs
;
539 uint32_t *packet_bufX
= (uint32_t *)packet_payload
;
544 while (node
!= NULL
) {
550 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
551 JackPort
*port
= fGraphManager
->GetPort(port_index
);
553 jack_default_audio_sample_t
* buf
=
554 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
556 const char *porttype
= port
->GetType();
558 if (strncmp (porttype
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
560 // audio port, resample if necessary
561 if (net_period_down
!= nframes
) {
562 SRC_STATE
*src_state
= (SRC_STATE
*)src_node
->data
;
563 for (i
= 0; i
< net_period_down
; i
++) {
564 packet_bufX
[i
] = ntohl (packet_bufX
[i
]);
567 src
.data_in
= (float *) packet_bufX
;
568 src
.input_frames
= net_period_down
;
571 src
.output_frames
= nframes
;
573 src
.src_ratio
= (float) nframes
/ (float) net_period_down
;
574 src
.end_of_input
= 0;
576 src_set_ratio (src_state
, src
.src_ratio
);
577 src_process (src_state
, &src
);
578 src_node
= jack_slist_next (src_node
);
582 if (dont_htonl_floats
) {
583 memcpy(buf
, packet_bufX
, net_period_down
* sizeof(jack_default_audio_sample_t
));
585 for (i
= 0; i
< net_period_down
; i
++) {
586 val
.i
= packet_bufX
[i
];
587 val
.i
= ntohl (val
.i
);
592 } else if (strncmp (porttype
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
593 // midi port, decode midi events
594 // convert the data buffer to a standard format (uint32_t based)
595 unsigned int buffer_size_uint32
= net_period_down
;
596 uint32_t * buffer_uint32
= (uint32_t*)packet_bufX
;
597 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
599 packet_bufX
= (packet_bufX
+ net_period_down
);
600 node
= jack_slist_next (node
);
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
)
609 JSList
*node
= playback_ports
;
611 JSList
*src_node
= playback_srcs
;
614 uint32_t *packet_bufX
= (uint32_t *) packet_payload
;
616 while (node
!= NULL
) {
622 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
623 JackPort
*port
= fGraphManager
->GetPort(port_index
);
625 jack_default_audio_sample_t
* buf
=
626 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
628 const char *porttype
= port
->GetType();
630 if (strncmp (porttype
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
631 // audio port, resample if necessary
634 if (net_period_up
!= nframes
) {
635 SRC_STATE
*src_state
= (SRC_STATE
*) src_node
->data
;
637 src
.input_frames
= nframes
;
639 src
.data_out
= (float *) packet_bufX
;
640 src
.output_frames
= net_period_up
;
642 src
.src_ratio
= (float) net_period_up
/ (float) nframes
;
643 src
.end_of_input
= 0;
645 src_set_ratio (src_state
, src
.src_ratio
);
646 src_process (src_state
, &src
);
648 for (i
= 0; i
< net_period_up
; i
++) {
649 packet_bufX
[i
] = htonl (packet_bufX
[i
]);
651 src_node
= jack_slist_next (src_node
);
655 if (dont_htonl_floats
) {
656 memcpy(packet_bufX
, buf
, net_period_up
* sizeof(jack_default_audio_sample_t
));
658 for (i
= 0; i
< net_period_up
; i
++) {
660 val
.i
= htonl (val
.i
);
661 packet_bufX
[i
] = val
.i
;
665 } else if (strncmp(porttype
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
666 // encode midi events from port to packet
667 // convert the data buffer to a standard format (uint32_t based)
668 unsigned int buffer_size_uint32
= net_period_up
;
669 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
670 encode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
672 packet_bufX
= (packet_bufX
+ net_period_up
);
673 node
= jack_slist_next (node
);
679 // render functions for celt.
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
)
684 JSList
*node
= capture_ports
;
685 JSList
*src_node
= capture_srcs
;
686 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
688 while (node
!= NULL
) {
689 jack_port_id_t port_index
= (jack_port_id_t
) (intptr_t)node
->data
;
690 JackPort
*port
= fGraphManager
->GetPort(port_index
);
692 jack_default_audio_sample_t
* buf
=
693 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
695 const char *portname
= port
->GetType();
697 if (strncmp(portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
698 // audio port, decode celt data.
699 CELTDecoder
*decoder
= (CELTDecoder
*)src_node
->data
;
701 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
703 celt_decode_float(decoder
, NULL
, net_period_down
, buf
, nframes
);
705 celt_decode_float(decoder
, packet_bufX
, net_period_down
, buf
, nframes
);
708 celt_decode_float(decoder
, NULL
, net_period_down
, buf
);
710 celt_decode_float(decoder
, packet_bufX
, net_period_down
, buf
);
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
;
720 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
722 packet_bufX
= (packet_bufX
+ net_period_down
);
723 node
= jack_slist_next (node
);
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
)
732 JSList
*node
= playback_ports
;
733 JSList
*src_node
= playback_srcs
;
735 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
737 while (node
!= NULL
) {
738 jack_port_id_t port_index
= (jack_port_id_t
) (intptr_t) node
->data
;
739 JackPort
*port
= fGraphManager
->GetPort(port_index
);
741 jack_default_audio_sample_t
* buf
=
742 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
744 const char *portname
= port
->GetType();
746 if (strncmp (portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
747 // audio port, encode celt data.
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
);
756 encoded_bytes
= celt_encode_float(encoder
, floatbuf
, NULL
, packet_bufX
, net_period_up
);
758 if (encoded_bytes
!= (int)net_period_up
)
759 jack_error("something in celt changed. netjack needs to be changed to handle this.");
760 src_node
= jack_slist_next(src_node
);
761 } else if (strncmp(portname
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
762 // encode midi events from port to packet
763 // convert the data buffer to a standard format (uint32_t based)
764 unsigned int buffer_size_uint32
= net_period_up
/ 2;
765 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
766 encode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
768 packet_bufX
= (packet_bufX
+ net_period_up
);
769 node
= jack_slist_next (node
);
777 #define CDO (sizeof(short)) ///< compressed data offset (first 2 bytes are length)
778 // render functions for Opus.
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
)
783 JSList
*node
= capture_ports
;
784 JSList
*src_node
= capture_srcs
;
786 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
788 while (node
!= NULL
) {
789 jack_port_id_t port_index
= (jack_port_id_t
) (intptr_t)node
->data
;
790 JackPort
*port
= fGraphManager
->GetPort(port_index
);
792 jack_default_audio_sample_t
* buf
=
793 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
795 const char *portname
= port
->GetType();
797 if (strncmp(portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
798 // audio port, decode opus data.
799 OpusCustomDecoder
*decoder
= (OpusCustomDecoder
*) src_node
->data
;
800 if( !packet_payload
)
801 memset(buf
, 0, nframes
* sizeof(float));
804 memcpy(&len
, packet_bufX
, CDO
);
806 opus_custom_decode_float( decoder
, packet_bufX
+ CDO
, len
, buf
, nframes
);
809 src_node
= jack_slist_next (src_node
);
810 } else if (strncmp(portname
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
811 // midi port, decode midi events
812 // convert the data buffer to a standard format (uint32_t based)
813 unsigned int buffer_size_uint32
= net_period_down
/ 2;
814 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
816 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
818 packet_bufX
= (packet_bufX
+ net_period_down
);
819 node
= jack_slist_next (node
);
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
)
828 JSList
*node
= playback_ports
;
829 JSList
*src_node
= playback_srcs
;
831 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
833 while (node
!= NULL
) {
834 jack_port_id_t port_index
= (jack_port_id_t
) (intptr_t) node
->data
;
835 JackPort
*port
= fGraphManager
->GetPort(port_index
);
837 jack_default_audio_sample_t
* buf
=
838 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
840 const char *portname
= port
->GetType();
842 if (strncmp (portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
843 // audio port, encode opus data.
846 jack_default_audio_sample_t
*floatbuf
= (jack_default_audio_sample_t
*)alloca (sizeof(jack_default_audio_sample_t
) * nframes
);
847 memcpy(floatbuf
, buf
, nframes
* sizeof(jack_default_audio_sample_t
));
848 OpusCustomEncoder
*encoder
= (OpusCustomEncoder
*) src_node
->data
;
849 encoded_bytes
= opus_custom_encode_float( encoder
, floatbuf
, nframes
, packet_bufX
+ CDO
, net_period_up
- CDO
);
850 unsigned short len
= htons(encoded_bytes
);
851 memcpy(packet_bufX
, &len
, CDO
);
852 src_node
= jack_slist_next( src_node
);
853 } else if (strncmp(portname
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
854 // encode midi events from port to packet
855 // convert the data buffer to a standard format (uint32_t based)
856 unsigned int buffer_size_uint32
= net_period_up
/ 2;
857 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
858 encode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
860 packet_bufX
= (packet_bufX
+ net_period_up
);
861 node
= jack_slist_next (node
);
867 /* Wrapper functions with bitdepth argument... */
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
)
872 if (bitdepth
== CELT_MODE
)
873 render_payload_to_jack_ports_celt (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
);
877 if (bitdepth
== OPUS_MODE
)
878 render_payload_to_jack_ports_opus (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
);
881 render_payload_to_jack_ports_float (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
, dont_htonl_floats
);
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
)
888 if (bitdepth
== CELT_MODE
)
889 render_jack_ports_to_payload_celt (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
);
893 if (bitdepth
== OPUS_MODE
)
894 render_jack_ports_to_payload_opus (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
);
897 render_jack_ports_to_payload_float (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
, dont_htonl_floats
);
900 //driver loader-----------------------------------------------------------------------
907 SERVER_EXPORT jack_driver_desc_t
* driver_get_descriptor ()
909 jack_driver_desc_t
* desc
;
910 jack_driver_desc_filler_t filler
;
911 jack_driver_param_value_t value
;
913 desc
= jack_driver_descriptor_construct("netone", JackDriverMaster
, "netjack one slave backend component", &filler
);
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
);
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
);
924 jack_driver_descriptor_add_parameter(desc
, &filler
, "rate", 'r', JackDriverParamUInt
, &value
, NULL
, "Sample rate", NULL
);
927 jack_driver_descriptor_add_parameter(desc
, &filler
, "period", 'p', JackDriverParamUInt
, &value
, NULL
, "Frames per period", NULL
);
930 jack_driver_descriptor_add_parameter(desc
, &filler
, "num-periods", 'n', JackDriverParamUInt
, &value
, NULL
, "Network latency setting in no. of periods", NULL
);
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
);
936 jack_driver_descriptor_add_parameter(desc
, &filler
, "factor", 'f', JackDriverParamUInt
, &value
, NULL
, "Factor for sample rate reduction", NULL
);
939 jack_driver_descriptor_add_parameter(desc
, &filler
, "upstream-factor", 'u', JackDriverParamUInt
, &value
, NULL
, "Factor for sample rate reduction on the upstream", NULL
);
943 jack_driver_descriptor_add_parameter(desc
, &filler
, "celt", 'c', JackDriverParamUInt
, &value
, NULL
, "Set CELT encoding and number of kbits per channel", NULL
);
947 jack_driver_descriptor_add_parameter(desc
, &filler
, "opus", 'P', JackDriverParamUInt
, &value
, NULL
, "Set Opus encoding and number of kbits per channel", NULL
);
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
);
953 jack_driver_descriptor_add_parameter(desc
, &filler
, "transport-sync", 't', JackDriverParamBool
, &value
, NULL
, "Whether to slave the transport to the master transport", NULL
);
956 jack_driver_descriptor_add_parameter(desc
, &filler
, "autoconf", 'a', JackDriverParamBool
, &value
, NULL
, "Whether to use Autoconfig, or just start", NULL
);
959 jack_driver_descriptor_add_parameter(desc
, &filler
, "redundancy", 'R', JackDriverParamUInt
, &value
, NULL
, "Send packets N times", NULL
);
962 jack_driver_descriptor_add_parameter(desc
, &filler
, "native-endian", 'e', JackDriverParamBool
, &value
, NULL
, "Dont convert samples to network byte order", NULL
);
965 jack_driver_descriptor_add_parameter(desc
, &filler
, "jitterval", 'J', JackDriverParamInt
, &value
, NULL
, "Attempted jitterbuffer microseconds on master", NULL
);
968 jack_driver_descriptor_add_parameter(desc
, &filler
, "always-deadline", 'D', JackDriverParamBool
, &value
, NULL
, "Always use deadline", NULL
);
973 SERVER_EXPORT
Jack::JackDriverClientInterface
* driver_initialize(Jack::JackLockedEngine
* engine
, Jack::JackSynchro
* table
, const JSList
* params
)
975 jack_nframes_t sample_rate
= 48000;
976 jack_nframes_t resample_factor
= 1;
977 jack_nframes_t period_size
= 1024;
978 unsigned int capture_ports
= 2;
979 unsigned int playback_ports
= 2;
980 unsigned int capture_ports_midi
= 1;
981 unsigned int playback_ports_midi
= 1;
982 unsigned int listen_port
= 3000;
983 unsigned int bitdepth
= 0;
984 unsigned int handle_transport_sync
= 1;
985 unsigned int use_autoconfig
= 1;
986 unsigned int latency
= 5;
987 unsigned int redundancy
= 1;
988 unsigned int mtu
= 1400;
990 unsigned int resample_factor_up
= 1;
992 int dont_htonl_floats
= 0;
993 int always_deadline
= 0;
996 const jack_driver_param_t
* param
;
998 for (node
= params
; node
; node
= jack_slist_next(node
)) {
999 param
= (const jack_driver_param_t
*) node
->data
;
1000 switch (param
->character
) {
1002 capture_ports
= param
->value
.ui
;
1006 playback_ports
= param
->value
.ui
;
1010 capture_ports_midi
= param
->value
.ui
;
1014 playback_ports_midi
= param
->value
.ui
;
1018 sample_rate
= param
->value
.ui
;
1022 period_size
= param
->value
.ui
;
1026 listen_port
= param
->value
.ui
;
1031 resample_factor
= param
->value
.ui
;
1033 jack_error("not built with libsamplerate support");
1040 resample_factor_up
= param
->value
.ui
;
1042 jack_error("not built with libsamplerate support");
1048 bitdepth
= param
->value
.ui
;
1053 bitdepth
= CELT_MODE
;
1054 resample_factor
= param
->value
.ui
;
1056 jack_error("not built with celt support");
1063 bitdepth
= OPUS_MODE
;
1064 resample_factor
= param
->value
.ui
;
1065 jack_error("OPUS: %d\n", resample_factor
);
1067 jack_error("not built with Opus support");
1073 handle_transport_sync
= param
->value
.ui
;
1077 use_autoconfig
= param
->value
.ui
;
1081 latency
= param
->value
.ui
;
1085 redundancy
= param
->value
.ui
;
1089 dont_htonl_floats
= param
->value
.ui
;
1093 jitter_val
= param
->value
.i
;
1097 always_deadline
= param
->value
.ui
;
1103 Jack::JackDriverClientInterface
* driver
= new Jack::JackWaitThreadedDriver (
1104 new Jack::JackNetOneDriver("system", "net_pcm", engine
, table
, listen_port
, mtu
,
1105 capture_ports_midi
, playback_ports_midi
, capture_ports
, playback_ports
,
1106 sample_rate
, period_size
, resample_factor
,
1107 "net_pcm", handle_transport_sync
, bitdepth
, use_autoconfig
, latency
, redundancy
,
1108 dont_htonl_floats
, always_deadline
, jitter_val
));
1110 if (driver
->Open(period_size
, sample_rate
, 1, 1, capture_ports
, playback_ports
,
1111 0, "from_master", "to_master", 0, 0) == 0) {