Cleanup thread code.
[jack2.git] / common / JackNetOneDriver.cpp
blob1fdfa5cde8834eea052d9ff0dcb42b86ab1c6b14
1 /*
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.
20 #define HAVE_CELT 1
22 #ifdef WIN32
23 #include <malloc.h>
24 #endif
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"
33 #include "netjack.h"
34 #include "netjack_packet.h"
36 #if HAVE_SAMPLERATE
37 #include "samplerate.h"
38 #endif
40 #if HAVE_CELT
41 #include "celt/celt.h"
42 #endif
44 #define MIN(x,y) ((x)<(y) ? (x) : (y))
46 using namespace std;
48 namespace Jack
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 );
59 #ifdef WIN32
60 WSADATA wsa;
61 int rc = WSAStartup(MAKEWORD(2,0),&wsa);
62 #endif
64 netjack_init( & (this->netj),
65 NULL, // client
66 name,
67 capture_ports,
68 playback_ports,
69 midi_input_ports,
70 midi_output_ports,
71 sample_rate,
72 period_size,
73 port,
74 transport_sync,
75 resample_factor,
77 bitdepth,
78 use_autoconfig,
79 latency,
80 redundancy,
81 dont_htonl_floats,
82 always_deadline);
85 JackNetOneDriver::~JackNetOneDriver()
87 // No destructor yet.
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,
97 samplerate,
98 capturing,
99 playing,
100 inchannels,
101 outchannels,
102 monitor,
103 capture_driver_name,
104 playback_driver_name,
105 capture_latency,
106 playback_latency ) == 0 )
108 fEngineControl->fPeriod = 0;
109 fEngineControl->fComputation = 500 * 1000;
110 fEngineControl->fConstraint = 500 * 1000;
111 return 0;
113 else
115 jack_error( "open fail\n" );
116 return -1;
120 int JackNetOneDriver::Close()
122 FreePorts();
123 netjack_release( &netj );
124 return JackDriver::Close();
127 int JackNetOneDriver::Attach()
129 return 0;
132 int JackNetOneDriver::Detach()
134 return 0;
137 int JackNetOneDriver::AllocPorts()
139 jack_port_id_t port_id;
140 char buf[64];
141 unsigned int chn;
142 int port_flags;
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 );
157 return -1;
159 //port = fGraphManager->GetPort ( port_id );
161 netj.capture_ports =
162 jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_id);
164 if( netj.bitdepth == CELT_MODE ) {
165 #if HAVE_CELT
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 ) );
170 #else
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 ) );
174 #endif
175 celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead );
176 netj.codec_latency = 2*lookahead;
177 #endif
178 } else {
179 #if HAVE_SAMPLERATE
180 netj.capture_srcs = jack_slist_append(netj.capture_srcs, (void *)src_new(SRC_LINEAR, 1, NULL));
181 #endif
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 );
191 return -1;
193 //port = fGraphManager->GetPort ( port_id );
195 netj.capture_ports =
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 );
208 return -1;
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 ) {
216 #if HAVE_CELT
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 ) );
220 #else
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 ) );
223 #endif
224 #endif
225 } else {
226 #if HAVE_SAMPLERATE
227 netj.playback_srcs = jack_slist_append(netj.playback_srcs, (void *)src_new(SRC_LINEAR, 1, NULL));
228 #endif
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 );
238 return -1;
240 //port = fGraphManager->GetPort ( port_id );
242 netj.playback_ports =
243 jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_id);
245 return 0;
248 //init and restart--------------------------------------------------------------------
249 bool JackNetOneDriver::Initialize()
251 jack_log ( "JackNetOneDriver::Init()" );
253 if( global_packcache != NULL ) {
254 FreePorts();
255 netjack_release( &netj );
258 //display some additional infos
259 jack_info ( "NetOne driver started" );
260 if( netjack_startup( &netj ) ) {
261 return false;
264 //register jack ports
265 if ( AllocPorts() != 0 )
267 jack_error ( "Can't allocate ports." );
268 return false;
272 //monitor
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 );
282 return true;
286 //jack ports and buffers--------------------------------------------------------------
288 //driver processes--------------------------------------------------------------------
289 int JackNetOneDriver::Read()
291 int delay;
292 delay = netjack_wait( &netj );
293 if( delay ) {
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 );
312 return 0;
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;
326 else
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) {
331 #if 1
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;
347 netj.sync_state = 0;
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;
361 netj.sync_state = 0;
362 jack_info("starting locate to %d", compensated_tranport_pos );
364 break;
365 case JackTransportStopped:
366 netj.sync_state = 1;
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 );
378 break;
379 case JackTransportRolling:
380 netj.sync_state = 1;
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);
384 // }
385 if (local_trans_state != JackTransportRolling)
386 fEngineControl->fTransport.SetState ( JackTransportRolling );
388 break;
390 case JackTransportLooping:
391 break;
393 #endif
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 );
398 return 0;
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 ) {
413 return 0;
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)
430 unsigned int r;
432 #ifdef __APPLE__
433 static const int flag = 0;
434 #else
435 static const int flag = 0;
436 #endif
438 if (netj.reply_port)
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);
445 return 0;
448 void
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 ) {
473 #if HAVE_CELT
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;
493 #endif
494 } else {
495 #if HAVE_SAMPLERATE
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 );
502 src_delete( state );
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 );
512 src_delete( state );
514 netj.capture_srcs = NULL;
515 #endif
518 //Render functions--------------------------------------------------------------------
520 // render functions for float
521 void
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)
524 uint32_t chn = 0;
525 JSList *node = capture_ports;
526 #if HAVE_SAMPLERATE
527 JSList *src_node = capture_srcs;
528 #endif
530 uint32_t *packet_bufX = (uint32_t *)packet_payload;
532 if( !packet_payload )
533 return;
535 while (node != NULL)
537 unsigned int i;
538 int_float_t val;
539 #if HAVE_SAMPLERATE
540 SRC_DATA src;
541 #endif
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)
553 #if HAVE_SAMPLERATE
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;
566 src.data_out = buf;
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);
576 else
577 #endif
579 if( dont_htonl_floats )
581 memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t));
583 else
585 for (i = 0; i < net_period_down; i++)
587 val.i = packet_bufX[i];
588 val.i = ntohl (val.i);
589 buf[i] = val.f;
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);
604 chn++;
608 void
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 )
611 uint32_t chn = 0;
612 JSList *node = playback_ports;
613 #if HAVE_SAMPLERATE
614 JSList *src_node = playback_srcs;
615 #endif
617 uint32_t *packet_bufX = (uint32_t *) packet_payload;
619 while (node != NULL)
621 #if HAVE_SAMPLERATE
622 SRC_DATA src;
623 #endif
624 unsigned int i;
625 int_float_t val;
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
638 #if HAVE_SAMPLERATE
639 if (net_period_up != nframes) {
640 SRC_STATE *src_state = (SRC_STATE *) src_node->data;
641 src.data_in = buf;
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);
659 else
660 #endif
662 if( dont_htonl_floats )
664 memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) );
666 else
668 for (i = 0; i < net_period_up; i++)
670 val.f = buf[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);
687 chn++;
691 #if HAVE_CELT
692 // render functions for celt.
693 void
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)
696 uint32_t chn = 0;
697 JSList *node = capture_ports;
698 JSList *src_node = capture_srcs;
700 unsigned char *packet_bufX = (unsigned char *)packet_payload;
702 while (node != NULL)
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 );
720 else
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;
731 if( packet_payload )
732 decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf);
734 packet_bufX = (packet_bufX + net_period_down);
735 node = jack_slist_next (node);
736 chn++;
740 void
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)
743 uint32_t chn = 0;
744 JSList *node = playback_ports;
745 JSList *src_node = playback_srcs;
747 unsigned char *packet_bufX = (unsigned char *)packet_payload;
749 while (node != NULL)
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.
763 int encoded_bytes;
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);
782 chn++;
786 #endif
787 /* Wrapper functions with bitdepth argument... */
788 void
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)
791 #if HAVE_CELT
792 if (bitdepth == CELT_MODE)
793 render_payload_to_jack_ports_celt (packet_payload, net_period_down, capture_ports, capture_srcs, nframes);
794 else
795 #endif
796 render_payload_to_jack_ports_float (packet_payload, net_period_down, capture_ports, capture_srcs, nframes, dont_htonl_floats);
799 void
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)
802 #if HAVE_CELT
803 if (bitdepth == CELT_MODE)
804 render_jack_ports_to_payload_celt (playback_ports, playback_srcs, nframes, packet_payload, net_period_up);
805 else
806 #endif
807 render_jack_ports_to_payload_float (playback_ports, playback_srcs, nframes, packet_payload, net_period_up, dont_htonl_floats);
812 //driver loader-----------------------------------------------------------------------
814 #ifdef __cplusplus
815 extern "C"
817 #endif
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
826 desc->nparams = 17;
827 params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) );
829 int i = 0;
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);
837 i++;
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);
845 i++;
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);
853 i++;
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);
861 i++;
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);
869 i++;
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);
877 i++;
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);
886 i++;
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);
895 i++;
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);
904 i++;
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);
913 i++;
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);
922 i++;
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);
931 i++;
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);
940 i++;
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,
946 "Latency setting");
947 strcpy (params[i].long_desc, params[i].short_desc);
949 i++;
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);
958 i++;
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);
967 i++;
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;
978 return desc;
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 )
1010 case 'i':
1011 capture_ports = param->value.ui;
1012 break;
1014 case 'o':
1015 playback_ports = param->value.ui;
1016 break;
1018 case 'I':
1019 capture_ports_midi = param->value.ui;
1020 break;
1022 case 'O':
1023 playback_ports_midi = param->value.ui;
1024 break;
1026 case 'r':
1027 sample_rate = param->value.ui;
1028 break;
1030 case 'p':
1031 period_size = param->value.ui;
1032 break;
1034 case 'l':
1035 listen_port = param->value.ui;
1036 break;
1038 case 'f':
1039 #if HAVE_SAMPLERATE
1040 resample_factor = param->value.ui;
1041 #else
1042 jack_error( "not built with libsamplerate support\n" );
1043 exit(10);
1044 #endif
1045 break;
1047 case 'u':
1048 #if HAVE_SAMPLERATE
1049 resample_factor_up = param->value.ui;
1050 #else
1051 jack_error( "not built with libsamplerate support\n" );
1052 exit(10);
1053 #endif
1054 break;
1056 case 'b':
1057 bitdepth = param->value.ui;
1058 break;
1060 case 'c':
1061 #if HAVE_CELT
1062 bitdepth = CELT_MODE;
1063 resample_factor = param->value.ui;
1064 #else
1065 jack_error( "not built with celt support\n" );
1066 exit(10);
1067 #endif
1068 break;
1070 case 't':
1071 handle_transport_sync = param->value.ui;
1072 break;
1074 case 'a':
1075 use_autoconfig = param->value.ui;
1076 break;
1078 case 'L':
1079 latency = param->value.ui;
1080 break;
1082 case 'R':
1083 redundancy = param->value.ui;
1084 break;
1086 case 'H':
1087 dont_htonl_floats = param->value.ui;
1088 break;
1090 case 'D':
1091 always_deadline = param->value.ui;
1092 break;
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 )
1110 return driver;
1112 else
1114 delete driver;
1115 return NULL;
1119 catch ( ... )
1121 return NULL;
1125 #ifdef __cplusplus
1127 #endif