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>
42 #define MIN(x,y) ((x)<(y) ? (x) : (y))
48 JackNetOneDriver::JackNetOneDriver(const char* name
, const char* alias
, JackLockedEngine
* engine
, JackSynchro
* table
,
49 int port
, int mtu
, int capture_ports
, int playback_ports
, int midi_input_ports
, int midi_output_ports
,
50 int sample_rate
, int period_size
, int resample_factor
,
51 const char* net_name
, uint transport_sync
, int bitdepth
, int use_autoconfig
,
52 int latency
, int redundancy
, int dont_htonl_floats
, int always_deadline
, int jitter_val
)
53 : JackWaiterDriver(name
, alias
, engine
, table
)
55 jack_log("JackNetOneDriver::JackNetOneDriver port %d", port
);
59 WSAStartup(MAKEWORD(2, 0), &wsa
);
62 netjack_init(& (this->netj
),
84 JackNetOneDriver::~JackNetOneDriver()
89 //open, close, attach and detach------------------------------------------------------
91 int JackNetOneDriver::Close()
93 // Generic audio driver close
94 int res
= JackWaiterDriver::Close();
97 netjack_release(&netj
);
101 int JackNetOneDriver::Attach()
106 int JackNetOneDriver::Detach()
111 int JackNetOneDriver::AllocPorts()
113 jack_port_id_t port_index
;
117 //if (netj.handle_transport_sync)
118 // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL);
120 for (chn
= 0; chn
< netj
.capture_channels_audio
; chn
++) {
121 snprintf (buf
, sizeof(buf
) - 1, "system:capture_%u", chn
+ 1);
123 if (fEngine
->PortRegister(fClientControl
.fRefNum
, buf
, JACK_DEFAULT_AUDIO_TYPE
,
124 CaptureDriverFlags
, fEngineControl
->fBufferSize
, &port_index
) < 0) {
125 jack_error("driver: cannot register port for %s", buf
);
128 //port = fGraphManager->GetPort(port_index);
130 netj
.capture_ports
= jack_slist_append (netj
.capture_ports
, (void *)(intptr_t)port_index
);
132 if (netj
.bitdepth
== CELT_MODE
) {
134 #if HAVE_CELT_API_0_11
135 celt_int32 lookahead
;
136 CELTMode
*celt_mode
= celt_mode_create(netj
.sample_rate
, netj
.period_size
, NULL
);
137 netj
.capture_srcs
= jack_slist_append(netj
.capture_srcs
, celt_decoder_create_custom(celt_mode
, 1, NULL
));
138 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
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(celt_mode
, 1, NULL
));
143 celt_int32_t lookahead
;
144 CELTMode
*celt_mode
= celt_mode_create(netj
.sample_rate
, 1, netj
.period_size
, NULL
);
145 netj
.capture_srcs
= jack_slist_append(netj
.capture_srcs
, celt_decoder_create(celt_mode
));
147 celt_mode_info(celt_mode
, CELT_GET_LOOKAHEAD
, &lookahead
);
148 netj
.codec_latency
= 2 * lookahead
;
152 netj
.capture_srcs
= jack_slist_append(netj
.capture_srcs
, (void *)src_new(SRC_LINEAR
, 1, NULL
));
157 for (chn
= netj
.capture_channels_audio
; chn
< netj
.capture_channels
; chn
++) {
158 snprintf (buf
, sizeof(buf
) - 1, "system:capture_%u", chn
+ 1);
160 if (fEngine
->PortRegister(fClientControl
.fRefNum
, buf
, JACK_DEFAULT_MIDI_TYPE
,
161 CaptureDriverFlags
, fEngineControl
->fBufferSize
, &port_index
) < 0) {
162 jack_error("driver: cannot register port for %s", buf
);
165 //port = fGraphManager->GetPort(port_index);
168 jack_slist_append (netj
.capture_ports
, (void *)(intptr_t)port_index
);
171 for (chn
= 0; chn
< netj
.playback_channels_audio
; chn
++) {
172 snprintf (buf
, sizeof(buf
) - 1, "system:playback_%u", chn
+ 1);
174 if (fEngine
->PortRegister(fClientControl
.fRefNum
, buf
, JACK_DEFAULT_AUDIO_TYPE
,
175 PlaybackDriverFlags
, fEngineControl
->fBufferSize
, &port_index
) < 0) {
176 jack_error("driver: cannot register port for %s", buf
);
179 //port = fGraphManager->GetPort(port_index);
181 netj
.playback_ports
= jack_slist_append (netj
.playback_ports
, (void *)(intptr_t)port_index
);
182 if (netj
.bitdepth
== CELT_MODE
) {
184 #if HAVE_CELT_API_0_11
185 CELTMode
*celt_mode
= celt_mode_create(netj
.sample_rate
, netj
.period_size
, NULL
);
186 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, celt_encoder_create_custom(celt_mode
, 1, NULL
));
187 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
188 CELTMode
*celt_mode
= celt_mode_create(netj
.sample_rate
, netj
.period_size
, NULL
);
189 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, celt_encoder_create(celt_mode
, 1, NULL
));
191 CELTMode
*celt_mode
= celt_mode_create(netj
.sample_rate
, 1, netj
.period_size
, NULL
);
192 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, celt_encoder_create(celt_mode
));
197 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, (void *)src_new(SRC_LINEAR
, 1, NULL
));
201 for (chn
= netj
.playback_channels_audio
; chn
< netj
.playback_channels
; chn
++) {
202 snprintf (buf
, sizeof(buf
) - 1, "system:playback_%u", chn
+ 1);
204 if (fEngine
->PortRegister(fClientControl
.fRefNum
, buf
, JACK_DEFAULT_MIDI_TYPE
,
205 PlaybackDriverFlags
, fEngineControl
->fBufferSize
, &port_index
) < 0) {
206 jack_error("driver: cannot register port for %s", buf
);
209 //port = fGraphManager->GetPort(port_index);
211 netj
.playback_ports
=
212 jack_slist_append (netj
.playback_ports
, (void *)(intptr_t)port_index
);
217 //init and restart--------------------------------------------------------------------
218 bool JackNetOneDriver::Initialize()
220 jack_log("JackNetOneDriver::Init");
223 netjack_release(&netj
);
225 //display some additional infos
226 jack_info("NetOne driver started");
227 if (netjack_startup(&netj
)) {
231 //register jack ports
232 if (AllocPorts() != 0) {
233 jack_error("Can't allocate ports.");
238 //driver parametering
239 JackTimedDriver::SetBufferSize(netj
.period_size
);
240 JackTimedDriver::SetSampleRate(netj
.sample_rate
);
242 JackDriver::NotifyBufferSize(netj
.period_size
);
243 JackDriver::NotifySampleRate(netj
.sample_rate
);
245 //transport engine parametering
246 fEngineControl
->fTransport
.SetNetworkSync(true);
251 //jack ports and buffers--------------------------------------------------------------
253 //driver processes--------------------------------------------------------------------
255 int JackNetOneDriver::Read()
258 delay
= netjack_wait(&netj
);
260 NotifyXRun(fBeginDateUst
, (float) delay
);
261 jack_error("netxruns... duration: %dms", delay
/ 1000);
264 if ((netj
.num_lost_packets
* netj
.period_size
/ netj
.sample_rate
) > 2)
265 JackTools::ThrowJackNetException();
267 //netjack_read(&netj, netj.period_size);
268 JackDriver::CycleTakeBeginTime();
270 jack_position_t local_trans_pos
;
271 jack_transport_state_t local_trans_state
;
273 unsigned int *packet_buf
, *packet_bufX
;
275 if (! netj
.packet_data_valid
) {
276 jack_log("data not valid");
277 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
);
280 packet_buf
= netj
.rx_buf
;
282 jacknet_packet_header
*pkthdr
= (jacknet_packet_header
*)packet_buf
;
284 packet_bufX
= packet_buf
+ sizeof(jacknet_packet_header
) / sizeof(jack_default_audio_sample_t
);
286 netj
.reply_port
= pkthdr
->reply_port
;
287 netj
.latency
= pkthdr
->latency
;
289 // Special handling for latency=0
290 if (netj
.latency
== 0)
291 netj
.resync_threshold
= 0;
293 netj
.resync_threshold
= MIN(15, pkthdr
->latency
- 1);
295 // check whether, we should handle the transport sync stuff, or leave trnasports untouched.
296 if (netj
.handle_transport_sync
) {
298 unsigned int compensated_tranport_pos
= (pkthdr
->transport_frame
+ (pkthdr
->latency
* netj
.period_size
) + netj
.codec_latency
);
300 // read local transport info....
301 //local_trans_state = jack_transport_query(netj.client, &local_trans_pos);
303 local_trans_state
= fEngineControl
->fTransport
.Query(&local_trans_pos
);
305 // Now check if we have to start or stop local transport to sync to remote...
306 switch (pkthdr
->transport_state
) {
308 case JackTransportStarting
:
309 // the master transport is starting... so we set our reply to the sync_callback;
310 if (local_trans_state
== JackTransportStopped
) {
311 fEngineControl
->fTransport
.SetCommand(TransportCommandStart
);
312 //jack_transport_start(netj.client);
313 //last_transport_state = JackTransportStopped;
315 jack_info("locally stopped... starting...");
318 if (local_trans_pos
.frame
!= compensated_tranport_pos
) {
319 jack_position_t new_pos
= local_trans_pos
;
320 new_pos
.frame
= compensated_tranport_pos
+ 2 * netj
.period_size
;
321 new_pos
.valid
= (jack_position_bits_t
) 0;
324 fEngineControl
->fTransport
.RequestNewPos(&new_pos
);
325 //jack_transport_locate(netj.client, compensated_tranport_pos);
326 //last_transport_state = JackTransportRolling;
328 jack_info("starting locate to %d", compensated_tranport_pos
);
332 case JackTransportStopped
:
334 if (local_trans_pos
.frame
!= (pkthdr
->transport_frame
)) {
335 jack_position_t new_pos
= local_trans_pos
;
336 new_pos
.frame
= pkthdr
->transport_frame
;
337 new_pos
.valid
= (jack_position_bits_t
)0;
338 fEngineControl
->fTransport
.RequestNewPos(&new_pos
);
339 //jack_transport_locate(netj.client, (pkthdr->transport_frame));
340 jack_info("transport is stopped locate to %d", pkthdr
->transport_frame
);
342 if (local_trans_state
!= JackTransportStopped
)
343 //jack_transport_stop(netj.client);
344 fEngineControl
->fTransport
.SetCommand(TransportCommandStop
);
347 case JackTransportRolling
:
349 // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) {
350 // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size));
351 // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size);
353 if (local_trans_state
!= JackTransportRolling
)
354 fEngineControl
->fTransport
.SetState(JackTransportRolling
);
357 case JackTransportLooping
:
363 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
);
364 packet_cache_release_packet(netj
.packcache
, netj
.expected_framecnt
);
368 int JackNetOneDriver::Write()
370 int syncstate
= netj
.sync_state
| ((fEngineControl
->fTransport
.GetState() == JackTransportNetStarting
) ? 1 : 0);
371 uint32_t *packet_buf
, *packet_bufX
;
373 int packet_size
= get_sample_size(netj
.bitdepth
) * netj
.playback_channels
* netj
.net_period_up
+ sizeof(jacknet_packet_header
);
374 jacknet_packet_header
*pkthdr
;
376 packet_buf
= (uint32_t *) alloca(packet_size
);
377 pkthdr
= (jacknet_packet_header
*)packet_buf
;
379 if (netj
.running_free
) {
383 // offset packet_bufX by the packetheader.
384 packet_bufX
= packet_buf
+ sizeof(jacknet_packet_header
) / sizeof(jack_default_audio_sample_t
);
386 pkthdr
->sync_state
= syncstate
;;
387 pkthdr
->latency
= netj
.time_to_deadline
;
388 //printf("time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness);
389 pkthdr
->framecnt
= netj
.expected_framecnt
;
391 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
);
393 packet_header_hton(pkthdr
);
394 if (netj
.srcaddress_valid
) {
396 static const int flag
= 0;
399 netj
.syncsource_address
.sin_port
= htons(netj
.reply_port
);
401 for (r
= 0; r
< netj
.redundancy
; r
++)
402 netjack_sendto(netj
.sockfd
, (char *)packet_buf
, packet_size
,
403 flag
, (struct sockaddr
*) & (netj
.syncsource_address
), sizeof(struct sockaddr_in
), netj
.mtu
);
409 JackNetOneDriver::FreePorts ()
411 JSList
*node
= netj
.capture_ports
;
413 while (node
!= NULL
) {
414 JSList
*this_node
= node
;
415 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
416 node
= jack_slist_remove_link(node
, this_node
);
417 jack_slist_free_1(this_node
);
418 fEngine
->PortUnRegister(fClientControl
.fRefNum
, port_index
);
420 netj
.capture_ports
= NULL
;
422 node
= netj
.playback_ports
;
423 while (node
!= NULL
) {
424 JSList
*this_node
= node
;
425 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
426 node
= jack_slist_remove_link(node
, this_node
);
427 jack_slist_free_1(this_node
);
428 fEngine
->PortUnRegister(fClientControl
.fRefNum
, port_index
);
430 netj
.playback_ports
= NULL
;
432 if (netj
.bitdepth
== CELT_MODE
) {
434 node
= netj
.playback_srcs
;
435 while (node
!= NULL
) {
436 JSList
*this_node
= node
;
437 CELTEncoder
*enc
= (CELTEncoder
*) node
->data
;
438 node
= jack_slist_remove_link(node
, this_node
);
439 jack_slist_free_1(this_node
);
440 celt_encoder_destroy(enc
);
442 netj
.playback_srcs
= NULL
;
444 node
= netj
.capture_srcs
;
445 while (node
!= NULL
) {
446 JSList
*this_node
= node
;
447 CELTDecoder
*dec
= (CELTDecoder
*) node
->data
;
448 node
= jack_slist_remove_link(node
, this_node
);
449 jack_slist_free_1(this_node
);
450 celt_decoder_destroy(dec
);
452 netj
.capture_srcs
= NULL
;
456 node
= netj
.playback_srcs
;
457 while (node
!= NULL
) {
458 JSList
*this_node
= node
;
459 SRC_STATE
*state
= (SRC_STATE
*) node
->data
;
460 node
= jack_slist_remove_link(node
, this_node
);
461 jack_slist_free_1(this_node
);
464 netj
.playback_srcs
= NULL
;
466 node
= netj
.capture_srcs
;
467 while (node
!= NULL
) {
468 JSList
*this_node
= node
;
469 SRC_STATE
*state
= (SRC_STATE
*) node
->data
;
470 node
= jack_slist_remove_link(node
, this_node
);
471 jack_slist_free_1(this_node
);
474 netj
.capture_srcs
= NULL
;
479 //Render functions--------------------------------------------------------------------
481 // render functions for float
483 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
)
486 JSList
*node
= capture_ports
;
488 JSList
*src_node
= capture_srcs
;
491 uint32_t *packet_bufX
= (uint32_t *)packet_payload
;
496 while (node
!= NULL
) {
502 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
503 JackPort
*port
= fGraphManager
->GetPort(port_index
);
505 jack_default_audio_sample_t
* buf
=
506 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
508 const char *porttype
= port
->GetType();
510 if (strncmp (porttype
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
512 // audio port, resample if necessary
513 if (net_period_down
!= nframes
) {
514 SRC_STATE
*src_state
= (SRC_STATE
*)src_node
->data
;
515 for (i
= 0; i
< net_period_down
; i
++) {
516 packet_bufX
[i
] = ntohl (packet_bufX
[i
]);
519 src
.data_in
= (float *) packet_bufX
;
520 src
.input_frames
= net_period_down
;
523 src
.output_frames
= nframes
;
525 src
.src_ratio
= (float) nframes
/ (float) net_period_down
;
526 src
.end_of_input
= 0;
528 src_set_ratio (src_state
, src
.src_ratio
);
529 src_process (src_state
, &src
);
530 src_node
= jack_slist_next (src_node
);
534 if (dont_htonl_floats
) {
535 memcpy(buf
, packet_bufX
, net_period_down
* sizeof(jack_default_audio_sample_t
));
537 for (i
= 0; i
< net_period_down
; i
++) {
538 val
.i
= packet_bufX
[i
];
539 val
.i
= ntohl (val
.i
);
544 } else if (strncmp (porttype
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
545 // midi port, decode midi events
546 // convert the data buffer to a standard format (uint32_t based)
547 unsigned int buffer_size_uint32
= net_period_down
;
548 uint32_t * buffer_uint32
= (uint32_t*)packet_bufX
;
549 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
551 packet_bufX
= (packet_bufX
+ net_period_down
);
552 node
= jack_slist_next (node
);
558 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
)
561 JSList
*node
= playback_ports
;
563 JSList
*src_node
= playback_srcs
;
566 uint32_t *packet_bufX
= (uint32_t *) packet_payload
;
568 while (node
!= NULL
) {
574 jack_port_id_t port_index
= (jack_port_id_t
)(intptr_t) node
->data
;
575 JackPort
*port
= fGraphManager
->GetPort(port_index
);
577 jack_default_audio_sample_t
* buf
=
578 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
580 const char *porttype
= port
->GetType();
582 if (strncmp (porttype
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
583 // audio port, resample if necessary
586 if (net_period_up
!= nframes
) {
587 SRC_STATE
*src_state
= (SRC_STATE
*) src_node
->data
;
589 src
.input_frames
= nframes
;
591 src
.data_out
= (float *) packet_bufX
;
592 src
.output_frames
= net_period_up
;
594 src
.src_ratio
= (float) net_period_up
/ (float) nframes
;
595 src
.end_of_input
= 0;
597 src_set_ratio (src_state
, src
.src_ratio
);
598 src_process (src_state
, &src
);
600 for (i
= 0; i
< net_period_up
; i
++) {
601 packet_bufX
[i
] = htonl (packet_bufX
[i
]);
603 src_node
= jack_slist_next (src_node
);
607 if (dont_htonl_floats
) {
608 memcpy(packet_bufX
, buf
, net_period_up
* sizeof(jack_default_audio_sample_t
));
610 for (i
= 0; i
< net_period_up
; i
++) {
612 val
.i
= htonl (val
.i
);
613 packet_bufX
[i
] = val
.i
;
617 } else if (strncmp(porttype
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
618 // encode midi events from port to packet
619 // convert the data buffer to a standard format (uint32_t based)
620 unsigned int buffer_size_uint32
= net_period_up
;
621 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
622 encode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
624 packet_bufX
= (packet_bufX
+ net_period_up
);
625 node
= jack_slist_next (node
);
631 // render functions for celt.
633 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
)
636 JSList
*node
= capture_ports
;
637 JSList
*src_node
= capture_srcs
;
638 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
640 while (node
!= NULL
) {
641 jack_port_id_t port_index
= (jack_port_id_t
) (intptr_t)node
->data
;
642 JackPort
*port
= fGraphManager
->GetPort(port_index
);
644 jack_default_audio_sample_t
* buf
=
645 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
647 const char *portname
= port
->GetType();
649 if (strncmp(portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
650 // audio port, decode celt data.
651 CELTDecoder
*decoder
= (CELTDecoder
*)src_node
->data
;
653 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
655 celt_decode_float(decoder
, NULL
, net_period_down
, buf
, nframes
);
657 celt_decode_float(decoder
, packet_bufX
, net_period_down
, buf
, nframes
);
660 celt_decode_float(decoder
, NULL
, net_period_down
, buf
);
662 celt_decode_float(decoder
, packet_bufX
, net_period_down
, buf
);
665 src_node
= jack_slist_next (src_node
);
666 } else if (strncmp(portname
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
667 // midi port, decode midi events
668 // convert the data buffer to a standard format (uint32_t based)
669 unsigned int buffer_size_uint32
= net_period_down
/ 2;
670 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
672 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
674 packet_bufX
= (packet_bufX
+ net_period_down
);
675 node
= jack_slist_next (node
);
681 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
)
684 JSList
*node
= playback_ports
;
685 JSList
*src_node
= playback_srcs
;
687 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
689 while (node
!= NULL
) {
690 jack_port_id_t port_index
= (jack_port_id_t
) (intptr_t) node
->data
;
691 JackPort
*port
= fGraphManager
->GetPort(port_index
);
693 jack_default_audio_sample_t
* buf
=
694 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_index
, fEngineControl
->fBufferSize
);
696 const char *portname
= port
->GetType();
698 if (strncmp (portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0) {
699 // audio port, encode celt data.
702 jack_default_audio_sample_t
*floatbuf
= (jack_default_audio_sample_t
*)alloca (sizeof(jack_default_audio_sample_t
) * nframes
);
703 memcpy(floatbuf
, buf
, nframes
* sizeof(jack_default_audio_sample_t
));
704 CELTEncoder
*encoder
= (CELTEncoder
*)src_node
->data
;
705 #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
706 encoded_bytes
= celt_encode_float(encoder
, floatbuf
, nframes
, packet_bufX
, net_period_up
);
708 encoded_bytes
= celt_encode_float(encoder
, floatbuf
, NULL
, packet_bufX
, net_period_up
);
710 if (encoded_bytes
!= (int)net_period_up
)
711 jack_error("something in celt changed. netjack needs to be changed to handle this.");
712 src_node
= jack_slist_next(src_node
);
713 } else if (strncmp(portname
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0) {
714 // encode midi events from port to packet
715 // convert the data buffer to a standard format (uint32_t based)
716 unsigned int buffer_size_uint32
= net_period_up
/ 2;
717 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
718 encode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
720 packet_bufX
= (packet_bufX
+ net_period_up
);
721 node
= jack_slist_next (node
);
727 /* Wrapper functions with bitdepth argument... */
729 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
)
732 if (bitdepth
== CELT_MODE
)
733 render_payload_to_jack_ports_celt (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
);
736 render_payload_to_jack_ports_float (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
, dont_htonl_floats
);
740 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
)
743 if (bitdepth
== CELT_MODE
)
744 render_jack_ports_to_payload_celt (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
);
747 render_jack_ports_to_payload_float (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
, dont_htonl_floats
);
750 //driver loader-----------------------------------------------------------------------
757 SERVER_EXPORT jack_driver_desc_t
* driver_get_descriptor ()
759 jack_driver_desc_t
* desc
;
760 jack_driver_desc_filler_t filler
;
761 jack_driver_param_value_t value
;
763 desc
= jack_driver_descriptor_construct("netone", JackDriverMaster
, "netjack one slave backend component", &filler
);
766 jack_driver_descriptor_add_parameter(desc
, &filler
, "audio-ins", 'i', JackDriverParamUInt
, &value
, NULL
, "Number of capture channels (defaults to 2)", NULL
);
767 jack_driver_descriptor_add_parameter(desc
, &filler
, "audio-outs", 'o', JackDriverParamUInt
, &value
, NULL
, "Number of playback channels (defaults to 2)", NULL
);
770 jack_driver_descriptor_add_parameter(desc
, &filler
, "midi-ins", 'I', JackDriverParamUInt
, &value
, NULL
, "Number of midi capture channels (defaults to 1)", NULL
);
771 jack_driver_descriptor_add_parameter(desc
, &filler
, "midi-outs", 'O', JackDriverParamUInt
, &value
, NULL
, "Number of midi playback channels (defaults to 1)", NULL
);
774 jack_driver_descriptor_add_parameter(desc
, &filler
, "rate", 'r', JackDriverParamUInt
, &value
, NULL
, "Sample rate", NULL
);
777 jack_driver_descriptor_add_parameter(desc
, &filler
, "period", 'p', JackDriverParamUInt
, &value
, NULL
, "Frames per period", NULL
);
780 jack_driver_descriptor_add_parameter(desc
, &filler
, "num-periods", 'n', JackDriverParamUInt
, &value
, NULL
, "Network latency setting in no. of periods", NULL
);
783 jack_driver_descriptor_add_parameter(desc
, &filler
, "listen-port", 'l', JackDriverParamUInt
, &value
, NULL
, "The socket port we are listening on for sync packets", NULL
);
786 jack_driver_descriptor_add_parameter(desc
, &filler
, "factor", 'f', JackDriverParamUInt
, &value
, NULL
, "Factor for sample rate reduction", NULL
);
789 jack_driver_descriptor_add_parameter(desc
, &filler
, "upstream-factor", 'u', JackDriverParamUInt
, &value
, NULL
, "Factor for sample rate reduction on the upstream", NULL
);
793 jack_driver_descriptor_add_parameter(desc
, &filler
, "celt", 'c', JackDriverParamUInt
, &value
, NULL
, "Set CELT encoding and number of kbits per channel", NULL
);
796 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
);
799 jack_driver_descriptor_add_parameter(desc
, &filler
, "transport-sync", 't', JackDriverParamBool
, &value
, NULL
, "Whether to slave the transport to the master transport", NULL
);
802 jack_driver_descriptor_add_parameter(desc
, &filler
, "autoconf", 'a', JackDriverParamBool
, &value
, NULL
, "Whether to use Autoconfig, or just start", NULL
);
805 jack_driver_descriptor_add_parameter(desc
, &filler
, "redundancy", 'R', JackDriverParamUInt
, &value
, NULL
, "Send packets N times", NULL
);
808 jack_driver_descriptor_add_parameter(desc
, &filler
, "native-endian", 'e', JackDriverParamBool
, &value
, NULL
, "Dont convert samples to network byte order", NULL
);
811 jack_driver_descriptor_add_parameter(desc
, &filler
, "jitterval", 'J', JackDriverParamInt
, &value
, NULL
, "Attempted jitterbuffer microseconds on master", NULL
);
814 jack_driver_descriptor_add_parameter(desc
, &filler
, "always-deadline", 'D', JackDriverParamBool
, &value
, NULL
, "Always use deadline", NULL
);
819 SERVER_EXPORT
Jack::JackDriverClientInterface
* driver_initialize(Jack::JackLockedEngine
* engine
, Jack::JackSynchro
* table
, const JSList
* params
)
821 jack_nframes_t sample_rate
= 48000;
822 jack_nframes_t resample_factor
= 1;
823 jack_nframes_t period_size
= 1024;
824 unsigned int capture_ports
= 2;
825 unsigned int playback_ports
= 2;
826 unsigned int capture_ports_midi
= 1;
827 unsigned int playback_ports_midi
= 1;
828 unsigned int listen_port
= 3000;
829 unsigned int bitdepth
= 0;
830 unsigned int handle_transport_sync
= 1;
831 unsigned int use_autoconfig
= 1;
832 unsigned int latency
= 5;
833 unsigned int redundancy
= 1;
834 unsigned int mtu
= 1400;
836 unsigned int resample_factor_up
= 1;
838 int dont_htonl_floats
= 0;
839 int always_deadline
= 0;
842 const jack_driver_param_t
* param
;
844 for (node
= params
; node
; node
= jack_slist_next(node
)) {
845 param
= (const jack_driver_param_t
*) node
->data
;
846 switch (param
->character
) {
848 capture_ports
= param
->value
.ui
;
852 playback_ports
= param
->value
.ui
;
856 capture_ports_midi
= param
->value
.ui
;
860 playback_ports_midi
= param
->value
.ui
;
864 sample_rate
= param
->value
.ui
;
868 period_size
= param
->value
.ui
;
872 listen_port
= param
->value
.ui
;
877 resample_factor
= param
->value
.ui
;
879 jack_error("not built with libsamplerate support");
886 resample_factor_up
= param
->value
.ui
;
888 jack_error("not built with libsamplerate support");
894 bitdepth
= param
->value
.ui
;
899 bitdepth
= CELT_MODE
;
900 resample_factor
= param
->value
.ui
;
902 jack_error("not built with celt support");
908 handle_transport_sync
= param
->value
.ui
;
912 use_autoconfig
= param
->value
.ui
;
916 latency
= param
->value
.ui
;
920 redundancy
= param
->value
.ui
;
924 dont_htonl_floats
= param
->value
.ui
;
928 jitter_val
= param
->value
.i
;
932 always_deadline
= param
->value
.ui
;
938 Jack::JackDriverClientInterface
* driver
= new Jack::JackWaitThreadedDriver (
939 new Jack::JackNetOneDriver("system", "net_pcm", engine
, table
, listen_port
, mtu
,
940 capture_ports_midi
, playback_ports_midi
, capture_ports
, playback_ports
,
941 sample_rate
, period_size
, resample_factor
,
942 "net_pcm", handle_transport_sync
, bitdepth
, use_autoconfig
, latency
, redundancy
,
943 dont_htonl_floats
, always_deadline
, jitter_val
));
945 if (driver
->Open(period_size
, sample_rate
, 1, 1, capture_ports
, playback_ports
,
946 0, "from_master_", "to_master_", 0, 0) == 0) {