2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2008 Romain Moret at Grame
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.
26 #include "JackNetOneDriver.h"
27 #include "JackEngineControl.h"
28 #include "JackGraphManager.h"
29 #include "JackWaitThreadedDriver.h"
30 #include "JackException.h"
31 #include "driver_interface.h"
34 #include "netjack_packet.h"
37 #include "samplerate.h"
41 #include "celt/celt.h"
44 #define MIN(x,y) ((x)<(y) ? (x) : (y))
50 JackNetOneDriver::JackNetOneDriver ( const char* name
, const char* alias
, JackLockedEngine
* engine
, JackSynchro
* table
,
51 int port
, int mtu
, int capture_ports
, int playback_ports
, int midi_input_ports
, int midi_output_ports
,
52 int sample_rate
, int period_size
, int resample_factor
,
53 char* net_name
, uint transport_sync
, int bitdepth
, int use_autoconfig
,
54 int latency
, int redundancy
, int dont_htonl_floats
, int always_deadline
)
55 : JackAudioDriver ( name
, alias
, engine
, table
)
57 jack_log ( "JackNetOneDriver::JackNetOneDriver port %d", port
);
61 int rc
= WSAStartup(MAKEWORD(2,0),&wsa
);
64 netjack_init( & (this->netj
),
85 JackNetOneDriver::~JackNetOneDriver()
90 //open, close, attach and detach------------------------------------------------------
91 int JackNetOneDriver::Open ( jack_nframes_t buffer_size
, jack_nframes_t samplerate
, bool capturing
, bool playing
,
92 int inchannels
, int outchannels
, bool monitor
,
93 const char* capture_driver_name
, const char* playback_driver_name
,
94 jack_nframes_t capture_latency
, jack_nframes_t playback_latency
)
96 if ( JackAudioDriver::Open ( buffer_size
,
104 playback_driver_name
,
106 playback_latency
) == 0 )
108 fEngineControl
->fPeriod
= 0;
109 fEngineControl
->fComputation
= 500 * 1000;
110 fEngineControl
->fConstraint
= 500 * 1000;
115 jack_error( "open fail\n" );
120 int JackNetOneDriver::Close()
123 netjack_release( &netj
);
124 return JackDriver::Close();
127 int JackNetOneDriver::Attach()
132 int JackNetOneDriver::Detach()
137 int JackNetOneDriver::AllocPorts()
139 jack_port_id_t port_id
;
145 //if (netj.handle_transport_sync)
146 // jack_set_sync_callback(netj.client, (JackSyncCallback) net_driver_sync_cb, NULL);
148 port_flags
= JackPortIsOutput
| JackPortIsPhysical
| JackPortIsTerminal
;
150 for (chn
= 0; chn
< netj
.capture_channels_audio
; chn
++) {
151 snprintf (buf
, sizeof(buf
) - 1, "system:capture_%u", chn
+ 1);
153 if ( ( port_id
= fGraphManager
->AllocatePort ( fClientControl
.fRefNum
, buf
, JACK_DEFAULT_AUDIO_TYPE
,
154 static_cast<JackPortFlags
> ( port_flags
), fEngineControl
->fBufferSize
) ) == NO_PORT
)
156 jack_error ( "driver: cannot register port for %s", buf
);
159 //port = fGraphManager->GetPort ( port_id );
162 jack_slist_append (netj
.capture_ports
, (void *)(intptr_t)port_id
);
164 if( netj
.bitdepth
== CELT_MODE
) {
166 #if HAVE_CELT_API_0_7
167 celt_int32 lookahead
;
168 CELTMode
*celt_mode
= celt_mode_create( netj
.sample_rate
, netj
.period_size
, NULL
);
169 netj
.capture_srcs
= jack_slist_append(netj
.capture_srcs
, celt_decoder_create( celt_mode
, 1, NULL
) );
171 celt_int32_t lookahead
;
172 CELTMode
*celt_mode
= celt_mode_create( netj
.sample_rate
, 1, netj
.period_size
, NULL
);
173 netj
.capture_srcs
= jack_slist_append(netj
.capture_srcs
, celt_decoder_create( celt_mode
) );
175 celt_mode_info( celt_mode
, CELT_GET_LOOKAHEAD
, &lookahead
);
176 netj
.codec_latency
= 2*lookahead
;
180 netj
.capture_srcs
= jack_slist_append(netj
.capture_srcs
, (void *)src_new(SRC_LINEAR
, 1, NULL
));
184 for (chn
= netj
.capture_channels_audio
; chn
< netj
.capture_channels
; chn
++) {
185 snprintf (buf
, sizeof(buf
) - 1, "system:capture_%u", chn
+ 1);
187 if ( ( port_id
= fGraphManager
->AllocatePort ( fClientControl
.fRefNum
, buf
, JACK_DEFAULT_MIDI_TYPE
,
188 static_cast<JackPortFlags
> ( port_flags
), fEngineControl
->fBufferSize
) ) == NO_PORT
)
190 jack_error ( "driver: cannot register port for %s", buf
);
193 //port = fGraphManager->GetPort ( port_id );
196 jack_slist_append (netj
.capture_ports
, (void *)(intptr_t)port_id
);
199 port_flags
= JackPortIsInput
| JackPortIsPhysical
| JackPortIsTerminal
;
201 for (chn
= 0; chn
< netj
.playback_channels_audio
; chn
++) {
202 snprintf (buf
, sizeof(buf
) - 1, "system:playback_%u", chn
+ 1);
204 if ( ( port_id
= fGraphManager
->AllocatePort ( fClientControl
.fRefNum
, buf
, JACK_DEFAULT_AUDIO_TYPE
,
205 static_cast<JackPortFlags
> ( port_flags
), fEngineControl
->fBufferSize
) ) == NO_PORT
)
207 jack_error ( "driver: cannot register port for %s", buf
);
210 //port = fGraphManager->GetPort ( port_id );
212 netj
.playback_ports
=
213 jack_slist_append (netj
.playback_ports
, (void *)(intptr_t)port_id
);
215 if( netj
.bitdepth
== CELT_MODE
) {
217 #if HAVE_CELT_API_0_7
218 CELTMode
*celt_mode
= celt_mode_create( netj
.sample_rate
, netj
.period_size
, NULL
);
219 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, celt_encoder_create( celt_mode
, 1, NULL
) );
221 CELTMode
*celt_mode
= celt_mode_create( netj
.sample_rate
, 1, netj
.period_size
, NULL
);
222 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, celt_encoder_create( celt_mode
) );
227 netj
.playback_srcs
= jack_slist_append(netj
.playback_srcs
, (void *)src_new(SRC_LINEAR
, 1, NULL
));
231 for (chn
= netj
.playback_channels_audio
; chn
< netj
.playback_channels
; chn
++) {
232 snprintf (buf
, sizeof(buf
) - 1, "system:playback_%u", chn
+ 1);
234 if ( ( port_id
= fGraphManager
->AllocatePort ( fClientControl
.fRefNum
, buf
, JACK_DEFAULT_MIDI_TYPE
,
235 static_cast<JackPortFlags
> ( port_flags
), fEngineControl
->fBufferSize
) ) == NO_PORT
)
237 jack_error ( "driver: cannot register port for %s", buf
);
240 //port = fGraphManager->GetPort ( port_id );
242 netj
.playback_ports
=
243 jack_slist_append (netj
.playback_ports
, (void *)(intptr_t)port_id
);
248 //init and restart--------------------------------------------------------------------
249 bool JackNetOneDriver::Initialize()
251 jack_log ( "JackNetOneDriver::Init()" );
253 if( global_packcache
!= NULL
) {
255 netjack_release( &netj
);
258 //display some additional infos
259 jack_info ( "NetOne driver started" );
260 if( netjack_startup( &netj
) ) {
264 //register jack ports
265 if ( AllocPorts() != 0 )
267 jack_error ( "Can't allocate ports." );
273 //driver parametering
274 JackAudioDriver::SetBufferSize ( netj
.period_size
);
275 JackAudioDriver::SetSampleRate ( netj
.sample_rate
);
277 JackDriver::NotifyBufferSize ( netj
.period_size
);
278 JackDriver::NotifySampleRate ( netj
.sample_rate
);
280 //transport engine parametering
281 fEngineControl
->fTransport
.SetNetworkSync ( true );
286 //jack ports and buffers--------------------------------------------------------------
288 //driver processes--------------------------------------------------------------------
289 int JackNetOneDriver::Read()
292 delay
= netjack_wait( &netj
);
294 NotifyXRun(fBeginDateUst
, (float) delay
);
295 jack_error( "netxruns... duration: %dms", delay
/1000 );
298 if( (netj
.num_lost_packets
* netj
.period_size
/ netj
.sample_rate
) > 2 )
299 throw JackNetException();
301 //netjack_read( &netj, netj.period_size );
302 JackDriver::CycleTakeBeginTime();
304 jack_position_t local_trans_pos
;
305 jack_transport_state_t local_trans_state
;
307 unsigned int *packet_buf
, *packet_bufX
;
309 if( ! netj
.packet_data_valid
) {
310 jack_log( "data not valid" );
311 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
);
314 packet_buf
= netj
.rx_buf
;
316 jacknet_packet_header
*pkthdr
= (jacknet_packet_header
*)packet_buf
;
318 packet_bufX
= packet_buf
+ sizeof(jacknet_packet_header
) / sizeof(jack_default_audio_sample_t
);
320 netj
.reply_port
= pkthdr
->reply_port
;
321 netj
.latency
= pkthdr
->latency
;
323 // Special handling for latency=0
324 if( netj
.latency
== 0 )
325 netj
.resync_threshold
= 0;
327 netj
.resync_threshold
= MIN( 15, pkthdr
->latency
-1 );
329 // check whether, we should handle the transport sync stuff, or leave trnasports untouched.
330 if (netj
.handle_transport_sync
) {
332 unsigned int compensated_tranport_pos
= (pkthdr
->transport_frame
+ (pkthdr
->latency
* netj
.period_size
) + netj
.codec_latency
);
334 // read local transport info....
335 //local_trans_state = jack_transport_query(netj.client, &local_trans_pos);
337 local_trans_state
= fEngineControl
->fTransport
.Query ( &local_trans_pos
);
339 // Now check if we have to start or stop local transport to sync to remote...
340 switch (pkthdr
->transport_state
) {
341 case JackTransportStarting
:
342 // the master transport is starting... so we set our reply to the sync_callback;
343 if (local_trans_state
== JackTransportStopped
) {
344 fEngineControl
->fTransport
.SetCommand ( TransportCommandStart
);
345 //jack_transport_start(netj.client);
346 //last_transport_state = JackTransportStopped;
348 jack_info("locally stopped... starting...");
351 if (local_trans_pos
.frame
!= compensated_tranport_pos
)
353 jack_position_t new_pos
= local_trans_pos
;
354 new_pos
.frame
= compensated_tranport_pos
+ 2*netj
.period_size
;
355 new_pos
.valid
= (jack_position_bits_t
) 0;
358 fEngineControl
->fTransport
.RequestNewPos ( &new_pos
);
359 //jack_transport_locate(netj.client, compensated_tranport_pos);
360 //last_transport_state = JackTransportRolling;
362 jack_info("starting locate to %d", compensated_tranport_pos
);
365 case JackTransportStopped
:
367 if (local_trans_pos
.frame
!= (pkthdr
->transport_frame
)) {
368 jack_position_t new_pos
= local_trans_pos
;
369 new_pos
.frame
= pkthdr
->transport_frame
;
370 new_pos
.valid
= (jack_position_bits_t
)0;
371 fEngineControl
->fTransport
.RequestNewPos ( &new_pos
);
372 //jack_transport_locate(netj.client, (pkthdr->transport_frame));
373 jack_info("transport is stopped locate to %d", pkthdr
->transport_frame
);
375 if (local_trans_state
!= JackTransportStopped
)
376 //jack_transport_stop(netj.client);
377 fEngineControl
->fTransport
.SetCommand ( TransportCommandStop
);
379 case JackTransportRolling
:
381 // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * netj.period_size)) {
382 // jack_transport_locate(netj.client, (pkthdr->transport_frame + (pkthdr->latency + 2) * netj.period_size));
383 // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size);
385 if (local_trans_state
!= JackTransportRolling
)
386 fEngineControl
->fTransport
.SetState ( JackTransportRolling
);
390 case JackTransportLooping
:
396 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
);
397 packet_cache_release_packet(global_packcache
, netj
.expected_framecnt
);
401 int JackNetOneDriver::Write()
403 int syncstate
= netj
.sync_state
| ((fEngineControl
->fTransport
.GetState() == JackTransportNetStarting
) ? 1 : 0 );
404 uint32_t *packet_buf
, *packet_bufX
;
406 int packet_size
= get_sample_size(netj
.bitdepth
) * netj
.playback_channels
* netj
.net_period_up
+ sizeof(jacknet_packet_header
);
407 jacknet_packet_header
*pkthdr
;
409 packet_buf
= (uint32_t *) alloca(packet_size
);
410 pkthdr
= (jacknet_packet_header
*)packet_buf
;
412 if( netj
.running_free
) {
416 // offset packet_bufX by the packetheader.
417 packet_bufX
= packet_buf
+ sizeof(jacknet_packet_header
) / sizeof(jack_default_audio_sample_t
);
419 pkthdr
->sync_state
= syncstate
;;
420 pkthdr
->latency
= netj
.time_to_deadline
;
421 //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness );
422 pkthdr
->framecnt
= netj
.expected_framecnt
;
425 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
);
427 packet_header_hton(pkthdr
);
428 if (netj
.srcaddress_valid
)
433 static const int flag
= 0;
435 static const int flag
= 0;
439 netj
.syncsource_address
.sin_port
= htons(netj
.reply_port
);
441 for( r
=0; r
<netj
.redundancy
; r
++ )
442 netjack_sendto(netj
.outsockfd
, (char *)packet_buf
, packet_size
,
443 flag
, (struct sockaddr
*)&(netj
.syncsource_address
), sizeof(struct sockaddr_in
), netj
.mtu
);
449 JackNetOneDriver::FreePorts ()
451 JSList
*node
= netj
.capture_ports
;
453 while( node
!= NULL
) {
454 JSList
*this_node
= node
;
455 jack_port_id_t port_id
= (jack_port_id_t
)(intptr_t) node
->data
;
456 node
= jack_slist_remove_link( node
, this_node
);
457 jack_slist_free_1( this_node
);
458 fGraphManager
->ReleasePort( fClientControl
.fRefNum
, port_id
);
460 netj
.capture_ports
= NULL
;
462 node
= netj
.playback_ports
;
463 while( node
!= NULL
) {
464 JSList
*this_node
= node
;
465 jack_port_id_t port_id
= (jack_port_id_t
)(intptr_t) node
->data
;
466 node
= jack_slist_remove_link( node
, this_node
);
467 jack_slist_free_1( this_node
);
468 fGraphManager
->ReleasePort( fClientControl
.fRefNum
, port_id
);
470 netj
.playback_ports
= NULL
;
472 if( netj
.bitdepth
== CELT_MODE
) {
474 node
= netj
.playback_srcs
;
475 while( node
!= NULL
) {
476 JSList
*this_node
= node
;
477 CELTEncoder
*enc
= (CELTEncoder
*) node
->data
;
478 node
= jack_slist_remove_link( node
, this_node
);
479 jack_slist_free_1( this_node
);
480 celt_encoder_destroy( enc
);
482 netj
.playback_srcs
= NULL
;
484 node
= netj
.capture_srcs
;
485 while( node
!= NULL
) {
486 JSList
*this_node
= node
;
487 CELTDecoder
*dec
= (CELTDecoder
*) node
->data
;
488 node
= jack_slist_remove_link( node
, this_node
);
489 jack_slist_free_1( this_node
);
490 celt_decoder_destroy( dec
);
492 netj
.capture_srcs
= NULL
;
496 node
= netj
.playback_srcs
;
497 while( node
!= NULL
) {
498 JSList
*this_node
= node
;
499 SRC_STATE
*state
= (SRC_STATE
*) node
->data
;
500 node
= jack_slist_remove_link( node
, this_node
);
501 jack_slist_free_1( this_node
);
504 netj
.playback_srcs
= NULL
;
506 node
= netj
.capture_srcs
;
507 while( node
!= NULL
) {
508 JSList
*this_node
= node
;
509 SRC_STATE
*state
= (SRC_STATE
*) node
->data
;
510 node
= jack_slist_remove_link( node
, this_node
);
511 jack_slist_free_1( this_node
);
514 netj
.capture_srcs
= NULL
;
518 //Render functions--------------------------------------------------------------------
520 // render functions for float
522 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
)
525 JSList
*node
= capture_ports
;
527 JSList
*src_node
= capture_srcs
;
530 uint32_t *packet_bufX
= (uint32_t *)packet_payload
;
532 if( !packet_payload
)
543 jack_port_id_t port_id
= (jack_port_id_t
)(intptr_t) node
->data
;
544 JackPort
*port
= fGraphManager
->GetPort( port_id
);
546 jack_default_audio_sample_t
* buf
=
547 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_id
, fEngineControl
->fBufferSize
);
549 const char *porttype
= port
->GetType();
551 if (strncmp (porttype
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0)
554 // audio port, resample if necessary
555 if (net_period_down
!= nframes
)
557 SRC_STATE
*src_state
= (SRC_STATE
*)src_node
->data
;
558 for (i
= 0; i
< net_period_down
; i
++)
560 packet_bufX
[i
] = ntohl (packet_bufX
[i
]);
563 src
.data_in
= (float *) packet_bufX
;
564 src
.input_frames
= net_period_down
;
567 src
.output_frames
= nframes
;
569 src
.src_ratio
= (float) nframes
/ (float) net_period_down
;
570 src
.end_of_input
= 0;
572 src_set_ratio (src_state
, src
.src_ratio
);
573 src_process (src_state
, &src
);
574 src_node
= jack_slist_next (src_node
);
579 if( dont_htonl_floats
)
581 memcpy( buf
, packet_bufX
, net_period_down
*sizeof(jack_default_audio_sample_t
));
585 for (i
= 0; i
< net_period_down
; i
++)
587 val
.i
= packet_bufX
[i
];
588 val
.i
= ntohl (val
.i
);
594 else if (strncmp (porttype
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0)
596 // midi port, decode midi events
597 // convert the data buffer to a standard format (uint32_t based)
598 unsigned int buffer_size_uint32
= net_period_down
;
599 uint32_t * buffer_uint32
= (uint32_t*)packet_bufX
;
600 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
602 packet_bufX
= (packet_bufX
+ net_period_down
);
603 node
= jack_slist_next (node
);
609 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
)
612 JSList
*node
= playback_ports
;
614 JSList
*src_node
= playback_srcs
;
617 uint32_t *packet_bufX
= (uint32_t *) packet_payload
;
626 jack_port_id_t port_id
= (jack_port_id_t
)(intptr_t) node
->data
;
627 JackPort
*port
= fGraphManager
->GetPort( port_id
);
629 jack_default_audio_sample_t
* buf
=
630 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_id
, fEngineControl
->fBufferSize
);
632 const char *porttype
= port
->GetType();
634 if (strncmp (porttype
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0)
636 // audio port, resample if necessary
639 if (net_period_up
!= nframes
) {
640 SRC_STATE
*src_state
= (SRC_STATE
*) src_node
->data
;
642 src
.input_frames
= nframes
;
644 src
.data_out
= (float *) packet_bufX
;
645 src
.output_frames
= net_period_up
;
647 src
.src_ratio
= (float) net_period_up
/ (float) nframes
;
648 src
.end_of_input
= 0;
650 src_set_ratio (src_state
, src
.src_ratio
);
651 src_process (src_state
, &src
);
653 for (i
= 0; i
< net_period_up
; i
++)
655 packet_bufX
[i
] = htonl (packet_bufX
[i
]);
657 src_node
= jack_slist_next (src_node
);
662 if( dont_htonl_floats
)
664 memcpy( packet_bufX
, buf
, net_period_up
*sizeof(jack_default_audio_sample_t
) );
668 for (i
= 0; i
< net_period_up
; i
++)
671 val
.i
= htonl (val
.i
);
672 packet_bufX
[i
] = val
.i
;
677 else if (strncmp(porttype
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0)
679 // encode midi events from port to packet
680 // convert the data buffer to a standard format (uint32_t based)
681 unsigned int buffer_size_uint32
= net_period_up
;
682 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
683 encode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
685 packet_bufX
= (packet_bufX
+ net_period_up
);
686 node
= jack_slist_next (node
);
692 // render functions for celt.
694 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
)
697 JSList
*node
= capture_ports
;
698 JSList
*src_node
= capture_srcs
;
700 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
704 jack_port_id_t port_id
= (jack_port_id_t
) (intptr_t)node
->data
;
705 JackPort
*port
= fGraphManager
->GetPort( port_id
);
707 jack_default_audio_sample_t
* buf
=
708 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_id
, fEngineControl
->fBufferSize
);
710 const char *portname
= port
->GetType();
713 if (strncmp(portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0)
715 // audio port, decode celt data.
717 CELTDecoder
*decoder
= (CELTDecoder
*)src_node
->data
;
718 if( !packet_payload
)
719 celt_decode_float( decoder
, NULL
, net_period_down
, buf
);
721 celt_decode_float( decoder
, packet_bufX
, net_period_down
, buf
);
723 src_node
= jack_slist_next (src_node
);
725 else if (strncmp(portname
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0)
727 // midi port, decode midi events
728 // convert the data buffer to a standard format (uint32_t based)
729 unsigned int buffer_size_uint32
= net_period_down
/ 2;
730 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
732 decode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
734 packet_bufX
= (packet_bufX
+ net_period_down
);
735 node
= jack_slist_next (node
);
741 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
)
744 JSList
*node
= playback_ports
;
745 JSList
*src_node
= playback_srcs
;
747 unsigned char *packet_bufX
= (unsigned char *)packet_payload
;
751 jack_port_id_t port_id
= (jack_port_id_t
) (intptr_t) node
->data
;
752 JackPort
*port
= fGraphManager
->GetPort( port_id
);
754 jack_default_audio_sample_t
* buf
=
755 (jack_default_audio_sample_t
*)fGraphManager
->GetBuffer(port_id
, fEngineControl
->fBufferSize
);
757 const char *portname
= port
->GetType();
759 if (strncmp (portname
, JACK_DEFAULT_AUDIO_TYPE
, jack_port_type_size()) == 0)
761 // audio port, encode celt data.
764 float *floatbuf
= (float *)alloca (sizeof(float) * nframes
);
765 memcpy( floatbuf
, buf
, nframes
*sizeof(float) );
766 CELTEncoder
*encoder
= (CELTEncoder
*)src_node
->data
;
767 encoded_bytes
= celt_encode_float( encoder
, floatbuf
, NULL
, packet_bufX
, net_period_up
);
768 if( encoded_bytes
!= (int)net_period_up
)
769 jack_error( "something in celt changed. netjack needs to be changed to handle this.\n" );
770 src_node
= jack_slist_next( src_node
);
772 else if (strncmp(portname
, JACK_DEFAULT_MIDI_TYPE
, jack_port_type_size()) == 0)
774 // encode midi events from port to packet
775 // convert the data buffer to a standard format (uint32_t based)
776 unsigned int buffer_size_uint32
= net_period_up
/ 2;
777 uint32_t * buffer_uint32
= (uint32_t*) packet_bufX
;
778 encode_midi_buffer (buffer_uint32
, buffer_size_uint32
, buf
);
780 packet_bufX
= (packet_bufX
+ net_period_up
);
781 node
= jack_slist_next (node
);
787 /* Wrapper functions with bitdepth argument... */
789 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
)
792 if (bitdepth
== CELT_MODE
)
793 render_payload_to_jack_ports_celt (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
);
796 render_payload_to_jack_ports_float (packet_payload
, net_period_down
, capture_ports
, capture_srcs
, nframes
, dont_htonl_floats
);
800 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
)
803 if (bitdepth
== CELT_MODE
)
804 render_jack_ports_to_payload_celt (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
);
807 render_jack_ports_to_payload_float (playback_ports
, playback_srcs
, nframes
, packet_payload
, net_period_up
, dont_htonl_floats
);
812 //driver loader-----------------------------------------------------------------------
818 SERVER_EXPORT jack_driver_desc_t
* driver_get_descriptor ()
820 jack_driver_desc_t
* desc
= ( jack_driver_desc_t
* ) calloc ( 1, sizeof ( jack_driver_desc_t
) );
821 jack_driver_param_desc_t
* params
;
823 strcpy ( desc
->name
, "netone" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
824 strcpy ( desc
->desc
, "netjack one slave backend component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
827 params
= ( jack_driver_param_desc_t
* ) calloc ( desc
->nparams
, sizeof ( jack_driver_param_desc_t
) );
830 strcpy (params
[i
].name
, "inchannels");
831 params
[i
].character
= 'i';
832 params
[i
].type
= JackDriverParamUInt
;
833 params
[i
].value
.ui
= 2U;
834 strcpy (params
[i
].short_desc
, "Number of capture channels (defaults to 2)");
835 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
838 strcpy (params
[i
].name
, "outchannels");
839 params
[i
].character
= 'o';
840 params
[i
].type
= JackDriverParamUInt
;
841 params
[i
].value
.ui
= 2U;
842 strcpy (params
[i
].short_desc
, "Number of playback channels (defaults to 2)");
843 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
846 strcpy (params
[i
].name
, "midi inchannels");
847 params
[i
].character
= 'I';
848 params
[i
].type
= JackDriverParamUInt
;
849 params
[i
].value
.ui
= 1U;
850 strcpy (params
[i
].short_desc
, "Number of midi capture channels (defaults to 1)");
851 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
854 strcpy (params
[i
].name
, "midi outchannels");
855 params
[i
].character
= 'O';
856 params
[i
].type
= JackDriverParamUInt
;
857 params
[i
].value
.ui
= 1U;
858 strcpy (params
[i
].short_desc
, "Number of midi playback channels (defaults to 1)");
859 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
862 strcpy (params
[i
].name
, "rate");
863 params
[i
].character
= 'r';
864 params
[i
].type
= JackDriverParamUInt
;
865 params
[i
].value
.ui
= 48000U;
866 strcpy (params
[i
].short_desc
, "Sample rate");
867 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
870 strcpy (params
[i
].name
, "period");
871 params
[i
].character
= 'p';
872 params
[i
].type
= JackDriverParamUInt
;
873 params
[i
].value
.ui
= 1024U;
874 strcpy (params
[i
].short_desc
, "Frames per period");
875 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
878 strcpy (params
[i
].name
, "listen-port");
879 params
[i
].character
= 'l';
880 params
[i
].type
= JackDriverParamUInt
;
881 params
[i
].value
.ui
= 3000U;
882 strcpy (params
[i
].short_desc
,
883 "The socket port we are listening on for sync packets");
884 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
887 strcpy (params
[i
].name
, "factor");
888 params
[i
].character
= 'f';
889 params
[i
].type
= JackDriverParamUInt
;
890 params
[i
].value
.ui
= 1U;
891 strcpy (params
[i
].short_desc
,
892 "Factor for sample rate reduction");
893 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
896 strcpy (params
[i
].name
, "upstream-factor");
897 params
[i
].character
= 'u';
898 params
[i
].type
= JackDriverParamUInt
;
899 params
[i
].value
.ui
= 0U;
900 strcpy (params
[i
].short_desc
,
901 "Factor for sample rate reduction on the upstream");
902 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
905 strcpy (params
[i
].name
, "celt");
906 params
[i
].character
= 'c';
907 params
[i
].type
= JackDriverParamUInt
;
908 params
[i
].value
.ui
= 0U;
909 strcpy (params
[i
].short_desc
,
910 "sets celt encoding and number of bytes per channel");
911 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
914 strcpy (params
[i
].name
, "bit-depth");
915 params
[i
].character
= 'b';
916 params
[i
].type
= JackDriverParamUInt
;
917 params
[i
].value
.ui
= 0U;
918 strcpy (params
[i
].short_desc
,
919 "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)");
920 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
923 strcpy (params
[i
].name
, "transport-sync");
924 params
[i
].character
= 't';
925 params
[i
].type
= JackDriverParamBool
;
926 params
[i
].value
.ui
= 1U;
927 strcpy (params
[i
].short_desc
,
928 "Whether to slave the transport to the master transport");
929 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
932 strcpy (params
[i
].name
, "autoconf");
933 params
[i
].character
= 'a';
934 params
[i
].type
= JackDriverParamBool
;
935 params
[i
].value
.ui
= 1U;
936 strcpy (params
[i
].short_desc
,
937 "Whether to use Autoconfig, or just start.");
938 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
941 strcpy (params
[i
].name
, "latency");
942 params
[i
].character
= 'L';
943 params
[i
].type
= JackDriverParamUInt
;
944 params
[i
].value
.ui
= 5U;
945 strcpy (params
[i
].short_desc
,
947 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
950 strcpy (params
[i
].name
, "redundancy");
951 params
[i
].character
= 'R';
952 params
[i
].type
= JackDriverParamUInt
;
953 params
[i
].value
.ui
= 1U;
954 strcpy (params
[i
].short_desc
,
955 "Send packets N times");
956 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
959 strcpy (params
[i
].name
, "no-htonl");
960 params
[i
].character
= 'H';
961 params
[i
].type
= JackDriverParamBool
;
962 params
[i
].value
.ui
= 0U;
963 strcpy (params
[i
].short_desc
,
964 "Dont convert samples to network byte order.");
965 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
968 strcpy (params
[i
].name
, "deadline");
969 params
[i
].character
= 'D';
970 params
[i
].type
= JackDriverParamBool
;
971 params
[i
].value
.ui
= 0U;
972 strcpy (params
[i
].short_desc
,
973 "always use deadline (recommended for internet connect)");
974 strcpy (params
[i
].long_desc
, params
[i
].short_desc
);
976 desc
->params
= params
;
981 SERVER_EXPORT
Jack::JackDriverClientInterface
* driver_initialize ( Jack::JackLockedEngine
* engine
, Jack::JackSynchro
* table
, const JSList
* params
)
983 jack_nframes_t sample_rate
= 48000;
984 jack_nframes_t resample_factor
= 1;
985 jack_nframes_t period_size
= 1024;
986 unsigned int capture_ports
= 2;
987 unsigned int playback_ports
= 2;
988 unsigned int capture_ports_midi
= 1;
989 unsigned int playback_ports_midi
= 1;
990 unsigned int listen_port
= 3000;
991 unsigned int resample_factor_up
= 0;
992 unsigned int bitdepth
= 0;
993 unsigned int handle_transport_sync
= 1;
994 unsigned int use_autoconfig
= 1;
995 unsigned int latency
= 5;
996 unsigned int redundancy
= 1;
997 unsigned int mtu
= 1400;
998 int dont_htonl_floats
= 0;
999 int always_deadline
= 0;
1000 const JSList
* node
;
1001 const jack_driver_param_t
* param
;
1005 for ( node
= params
; node
; node
= jack_slist_next ( node
) )
1007 param
= ( const jack_driver_param_t
* ) node
->data
;
1008 switch ( param
->character
)
1011 capture_ports
= param
->value
.ui
;
1015 playback_ports
= param
->value
.ui
;
1019 capture_ports_midi
= param
->value
.ui
;
1023 playback_ports_midi
= param
->value
.ui
;
1027 sample_rate
= param
->value
.ui
;
1031 period_size
= param
->value
.ui
;
1035 listen_port
= param
->value
.ui
;
1040 resample_factor
= param
->value
.ui
;
1042 jack_error( "not built with libsamplerate support\n" );
1049 resample_factor_up
= param
->value
.ui
;
1051 jack_error( "not built with libsamplerate support\n" );
1057 bitdepth
= param
->value
.ui
;
1062 bitdepth
= CELT_MODE
;
1063 resample_factor
= param
->value
.ui
;
1065 jack_error( "not built with celt support\n" );
1071 handle_transport_sync
= param
->value
.ui
;
1075 use_autoconfig
= param
->value
.ui
;
1079 latency
= param
->value
.ui
;
1083 redundancy
= param
->value
.ui
;
1087 dont_htonl_floats
= param
->value
.ui
;
1091 always_deadline
= param
->value
.ui
;
1099 Jack::JackDriverClientInterface
* driver
=
1100 new Jack::JackWaitThreadedDriver (
1101 new Jack::JackNetOneDriver ( "system", "net_pcm", engine
, table
, listen_port
, mtu
,
1102 capture_ports_midi
, playback_ports_midi
, capture_ports
, playback_ports
,
1103 sample_rate
, period_size
, resample_factor
,
1104 "net_pcm", handle_transport_sync
, bitdepth
, use_autoconfig
, latency
, redundancy
,
1105 dont_htonl_floats
, always_deadline
) );
1107 if ( driver
->Open ( period_size
, sample_rate
, 1, 1, capture_ports
, playback_ports
,
1108 0, "from_master_", "to_master_", 0, 0 ) == 0 )