Fix warning: catching polymorphic type ‘class std::exception’ by value
[jack2.git] / common / netjack.c
blobf253b44deab3079d1d327f34cf05d409707b3a93
2 /* -*- mode: c; c-file-style: "linux"; -*- */
3 /*
4 NetJack Abstraction.
6 Copyright (C) 2018 Karl Linden <karl.j.linden@gmail.com>
7 Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
8 Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
9 Copyright (C) 2003 Robert Ham <rah@bash.sh>
10 Copyright (C) 2001 Paul Davis
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $
29 #include <alloca.h>
30 #include <math.h>
31 #include <stdio.h>
32 #include <memory.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <errno.h>
36 #include <stdarg.h>
38 #include <jack/types.h>
39 #include "jack/jslist.h"
41 #include <sys/types.h>
43 #ifdef WIN32
44 #include <winsock2.h>
45 #include <malloc.h>
46 #define socklen_t int
47 #else
48 #include <sys/socket.h>
49 #include <netinet/in.h>
50 #endif
52 #if defined(HAVE_CONFIG_H)
53 #include "config.h"
54 #endif
56 #if HAVE_SAMPLERATE
57 #include <samplerate.h>
58 #endif
60 #include "netjack.h"
61 #include "netjack_packet.h"
62 #include "JackError.h"
64 #define MIN(x,y) ((x)<(y) ? (x) : (y))
66 static int sync_state = 1;
67 static jack_transport_state_t last_transport_state;
69 static int
70 net_driver_sync_cb(jack_transport_state_t state, jack_position_t *pos, void *data)
72 int retval = sync_state;
74 if (state == JackTransportStarting && last_transport_state != JackTransportStarting) {
75 retval = 0;
77 // if (state == JackTransportStarting)
78 // jack_info("Starting sync_state = %d", sync_state);
79 last_transport_state = state;
80 return retval;
83 int netjack_wait( netjack_driver_state_t *netj )
85 int we_have_the_expected_frame = 0;
86 jack_nframes_t next_frame_avail;
87 jack_time_t packet_recv_time_stamp;
88 jacknet_packet_header *pkthdr;
90 if( !netj->next_deadline_valid ) {
91 netj->next_deadline = jack_get_time() + netj->period_usecs;
92 netj->next_deadline_valid = 1;
95 // Increment expected frame here.
97 if( netj->expected_framecnt_valid ) {
98 netj->expected_framecnt += 1;
99 } else {
100 // starting up.... lets look into the packetcache, and fetch the highest packet.
101 packet_cache_drain_socket( netj->packcache, netj->sockfd );
102 if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) {
103 netj->expected_framecnt = next_frame_avail;
104 netj->expected_framecnt_valid = 1;
105 } else {
106 // no packets there... start normally.
107 netj->expected_framecnt = 0;
108 netj->expected_framecnt_valid = 1;
112 //jack_log( "expect %d", netj->expected_framecnt );
113 // Now check if required packet is already in the cache.
114 // then poll (have deadline calculated)
115 // then drain socket, rinse and repeat.
116 while(1) {
117 if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) {
118 if( next_frame_avail == netj->expected_framecnt ) {
119 we_have_the_expected_frame = 1;
120 if( !netj->always_deadline )
121 break;
124 if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) {
125 break;
128 packet_cache_drain_socket( netj->packcache, netj->sockfd );
131 // check if we know who to send our packets too.
132 if (!netj->srcaddress_valid)
133 if( netj->packcache->master_address_valid ) {
134 memcpy (&(netj->syncsource_address), &(netj->packcache->master_address), sizeof( struct sockaddr_in ) );
135 netj->srcaddress_valid = 1;
138 // XXX: switching mode unconditionally is stupid.
139 // if we were running free perhaps we like to behave differently
140 // ie. fastforward one packet etc.
141 // well... this is the first packet we see. hmm.... dunno ;S
142 // it works... so...
143 netj->running_free = 0;
145 //if( !we_have_the_expected_frame )
146 // jack_error( "netxrun... %d", netj->expected_framecnt );
148 if( we_have_the_expected_frame ) {
150 jack_time_t now = jack_get_time();
151 if( now < netj->next_deadline )
152 netj->time_to_deadline = netj->next_deadline - now;
153 else
154 netj->time_to_deadline = 0;
156 packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp);
157 pkthdr = (jacknet_packet_header *) netj->rx_buf;
158 packet_header_ntoh(pkthdr);
159 netj->deadline_goodness = (int)pkthdr->sync_state;
160 netj->packet_data_valid = 1;
162 int want_deadline;
163 if( netj->jitter_val != 0 )
164 want_deadline = netj->jitter_val;
165 else if( netj->latency < 4 )
166 want_deadline = -netj->period_usecs / 2;
167 else
168 want_deadline = (netj->period_usecs / 4 + 10 * (int)netj->period_usecs * netj->latency / 100);
170 if( netj->deadline_goodness != MASTER_FREEWHEELS ) {
171 if( netj->deadline_goodness < want_deadline ) {
172 netj->next_deadline -= netj->period_usecs / 100;
173 //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
175 if( netj->deadline_goodness > want_deadline ) {
176 netj->next_deadline += netj->period_usecs / 100;
177 //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
180 // if( netj->next_deadline < (netj->period_usecs*70/100) ) {
181 // jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" );
182 // netj->deadline_offset = (netj->period_usecs*90/100);
183 // }
185 netj->next_deadline += netj->period_usecs;
186 } else {
187 netj->time_to_deadline = 0;
188 netj->next_deadline += netj->period_usecs;
189 // bah... the packet is not there.
190 // either
191 // - it got lost.
192 // - its late
193 // - sync source is not sending anymore.
195 // lets check if we have the next packets, we will just run a cycle without data.
196 // in that case.
198 if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) {
199 jack_nframes_t offset = next_frame_avail - netj->expected_framecnt;
201 //XXX: hmm... i need to remember why resync_threshold wasn't right.
202 //if( offset < netj->resync_threshold )
203 if( offset < 10 ) {
204 // ok. don't do nothing. we will run without data.
205 // this seems to be one or 2 lost packets.
207 // this can also be reordered packet jitter.
208 // (maybe this is not happening in real live)
209 // but it happens in netem.
211 netj->packet_data_valid = 0;
213 // I also found this happening, when the packet queue, is too full.
214 // but wtf ? use a smaller latency. this link can handle that ;S
215 if( packet_cache_get_fill( netj->packcache, netj->expected_framecnt ) > 80.0 )
216 netj->next_deadline -= netj->period_usecs / 2;
219 } else {
220 // the diff is too high. but we have a packet in the future.
221 // lets resync.
222 netj->expected_framecnt = next_frame_avail;
223 packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL );
224 pkthdr = (jacknet_packet_header *) netj->rx_buf;
225 packet_header_ntoh(pkthdr);
226 //netj->deadline_goodness = 0;
227 netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset;
228 netj->next_deadline_valid = 0;
229 netj->packet_data_valid = 1;
232 } else {
233 // no packets in buffer.
234 netj->packet_data_valid = 0;
236 //printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets );
237 if( netj->num_lost_packets < 5 ) {
238 // ok. No Packet in queue. The packet was either lost,
239 // or we are running too fast.
241 // Adjusting the deadline unconditionally resulted in
242 // too many xruns on master.
243 // But we need to adjust for the case we are running too fast.
244 // So lets check if the last packet is there now.
246 // It would not be in the queue anymore, if it had been
247 // retrieved. This might break for redundancy, but
248 // i will make the packet cache drop redundant packets,
249 // that have already been retrieved.
251 if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) {
252 if( next_frame_avail == (netj->expected_framecnt - 1) ) {
253 // Ok. the last packet is there now.
254 // and it had not been retrieved.
256 // TODO: We are still dropping 2 packets.
257 // perhaps we can adjust the deadline
258 // when (num_packets lost == 0)
260 // This might still be too much.
261 netj->next_deadline += netj->period_usecs;
264 } else if( (netj->num_lost_packets <= 100) ) {
265 // lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast.
266 netj->next_deadline += netj->period_usecs * netj->latency / 8;
267 } else {
269 // But now we can check for any new frame available.
271 if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) {
272 netj->expected_framecnt = next_frame_avail;
273 packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL );
274 pkthdr = (jacknet_packet_header *) netj->rx_buf;
275 packet_header_ntoh(pkthdr);
276 netj->deadline_goodness = pkthdr->sync_state;
277 netj->next_deadline_valid = 0;
278 netj->packet_data_valid = 1;
279 netj->running_free = 0;
280 jack_info( "resync after freerun... %d", netj->expected_framecnt );
281 } else {
282 if( netj->num_lost_packets == 101 ) {
283 jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt );
286 netj->running_free = 1;
288 // when we really don't see packets.
289 // reset source address. and open possibility for new master.
290 // maybe dsl reconnect. Also restart of netsource without fix
291 // reply address changes port.
292 if (netj->num_lost_packets > 200 ) {
293 netj->srcaddress_valid = 0;
294 packet_cache_reset_master_address( netj->packcache );
301 int retval = 0;
303 if( !netj->packet_data_valid ) {
304 netj->num_lost_packets += 1;
305 if( netj->num_lost_packets == 1 )
306 retval = netj->period_usecs;
307 } else {
308 if( (netj->num_lost_packets > 1) && !netj->running_free )
309 retval = (netj->num_lost_packets - 1) * netj->period_usecs;
311 netj->num_lost_packets = 0;
314 return retval;
317 void netjack_send_silence( netjack_driver_state_t *netj, int syncstate )
319 int tx_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up + sizeof(jacknet_packet_header);
320 unsigned int *packet_buf, *packet_bufX;
322 packet_buf = alloca( tx_size);
323 jacknet_packet_header *tx_pkthdr = (jacknet_packet_header *)packet_buf;
324 jacknet_packet_header *rx_pkthdr = (jacknet_packet_header *)netj->rx_buf;
326 //framecnt = rx_pkthdr->framecnt;
328 netj->reply_port = rx_pkthdr->reply_port;
330 // offset packet_bufX by the packetheader.
331 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
333 tx_pkthdr->sync_state = syncstate;
334 tx_pkthdr->framecnt = netj->expected_framecnt;
336 // memset 0 the payload.
337 int payload_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up;
338 memset(packet_bufX, 0, payload_size);
340 packet_header_hton(tx_pkthdr);
341 if (netj->srcaddress_valid) {
342 int r;
343 if (netj->reply_port)
344 netj->syncsource_address.sin_port = htons(netj->reply_port);
346 for( r = 0; r < netj->redundancy; r++ )
347 netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size,
348 0, (struct sockaddr*) & (netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu);
352 void netjack_attach( netjack_driver_state_t *netj )
354 //puts ("net_driver_attach");
355 jack_port_t * port;
356 char buf[32];
357 unsigned int chn;
358 int port_flags;
360 if( netj->bitdepth == CELT_MODE ) {
361 #if HAVE_CELT
362 #if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
363 celt_int32 lookahead;
364 netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
365 #else
366 celt_int32_t lookahead;
367 netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
368 #endif
369 celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead );
370 netj->codec_latency = 2 * lookahead;
371 #endif
373 if( netj->bitdepth == OPUS_MODE ) {
374 #if HAVE_OPUS
375 netj->opus_mode = opus_custom_mode_create(netj->sample_rate, netj->period_size, NULL);
376 #endif
379 if (netj->handle_transport_sync)
380 jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL);
382 port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
384 for (chn = 0; chn < netj->capture_channels_audio; chn++) {
385 snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
387 port = jack_port_register (netj->client, buf,
388 JACK_DEFAULT_AUDIO_TYPE,
389 port_flags, 0);
390 if (!port) {
391 jack_error ("NET: cannot register port for %s", buf);
392 break;
395 netj->capture_ports =
396 jack_slist_append (netj->capture_ports, port);
398 if( netj->bitdepth == CELT_MODE ) {
399 #if HAVE_CELT
400 #if HAVE_CELT_API_0_11
401 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) );
402 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
403 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) );
404 #else
405 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) );
406 #endif
407 #endif
408 } else if( netj->bitdepth == OPUS_MODE ) {
409 #if HAVE_OPUS
410 OpusCustomDecoder *decoder = opus_custom_decoder_create( netj->opus_mode, 1, NULL );
411 netj->capture_srcs = jack_slist_append(netj->capture_srcs, decoder );
412 #endif
413 } else {
414 #if HAVE_SAMPLERATE
415 netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL));
416 #endif
420 for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) {
421 snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
423 port = jack_port_register (netj->client, buf,
424 JACK_DEFAULT_MIDI_TYPE,
425 port_flags, 0);
426 if (!port) {
427 jack_error ("NET: cannot register port for %s", buf);
428 break;
431 netj->capture_ports =
432 jack_slist_append (netj->capture_ports, port);
435 port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
437 for (chn = 0; chn < netj->playback_channels_audio; chn++) {
438 snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
440 port = jack_port_register (netj->client, buf,
441 JACK_DEFAULT_AUDIO_TYPE,
442 port_flags, 0);
444 if (!port) {
445 jack_error ("NET: cannot register port for %s", buf);
446 break;
449 netj->playback_ports =
450 jack_slist_append (netj->playback_ports, port);
451 if( netj->bitdepth == CELT_MODE ) {
452 #if HAVE_CELT
453 #if HAVE_CELT_API_0_11
454 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
455 netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) );
456 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
457 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
458 netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
459 #else
460 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
461 netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) );
462 #endif
463 #endif
464 } else if( netj->bitdepth == OPUS_MODE ) {
465 #if HAVE_OPUS
466 const int kbps = netj->resample_factor;
467 jack_log( "OPUS %dkbps\n", kbps);
469 OpusCustomMode *opus_mode = opus_custom_mode_create( netj->sample_rate, netj->period_size, NULL ); // XXX free me in the end
470 OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, NULL );
471 opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
472 opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
473 opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
474 opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
475 netj->playback_srcs = jack_slist_append(netj->playback_srcs, oe );
476 #endif
477 } else {
478 #if HAVE_SAMPLERATE
479 netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL));
480 #endif
483 for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) {
484 snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
486 port = jack_port_register (netj->client, buf,
487 JACK_DEFAULT_MIDI_TYPE,
488 port_flags, 0);
490 if (!port) {
491 jack_error ("NET: cannot register port for %s", buf);
492 break;
495 netj->playback_ports =
496 jack_slist_append (netj->playback_ports, port);
499 jack_activate (netj->client);
503 void netjack_detach( netjack_driver_state_t *netj )
505 JSList * node;
507 for (node = netj->capture_ports; node; node = jack_slist_next (node))
508 jack_port_unregister (netj->client,
509 ((jack_port_t *) node->data));
511 jack_slist_free (netj->capture_ports);
512 netj->capture_ports = NULL;
514 for (node = netj->capture_srcs; node; node = jack_slist_next (node)) {
515 #if HAVE_CELT
516 if( netj->bitdepth == CELT_MODE ) {
517 CELTDecoder * decoder = node->data;
518 celt_decoder_destroy(decoder);
519 } else
520 #endif
521 #if HAVE_OPUS
522 if ( netj->bitdepth == OPUS_MODE ) {
523 OpusCustomDecoder * decoder = node->data;
524 opus_custom_decoder_destroy(decoder);
525 } else
526 #endif
528 #if HAVE_SAMPLERATE
529 SRC_STATE * src = node->data;
530 src_delete(src);
531 #endif
534 jack_slist_free (netj->capture_srcs);
535 netj->playback_srcs = NULL;
537 for (node = netj->playback_ports; node; node = jack_slist_next (node))
538 jack_port_unregister (netj->client,
539 ((jack_port_t *) node->data));
541 jack_slist_free (netj->playback_ports);
542 netj->playback_ports = NULL;
544 for (node = netj->playback_srcs; node; node = jack_slist_next (node)) {
545 #if HAVE_CELT
546 if( netj->bitdepth == CELT_MODE ) {
547 CELTEncoder * encoder = node->data;
548 celt_encoder_destroy(encoder);
549 } else
550 #endif
551 #if HAVE_OPUS
552 if ( netj->bitdepth == OPUS_MODE ) {
553 OpusCustomEncoder * encoder = node->data;
554 opus_custom_encoder_destroy(encoder);
555 } else
556 #endif
558 #if HAVE_SAMPLERATE
559 SRC_STATE * src = node->data;
560 src_delete(src);
561 #endif
564 jack_slist_free (netj->playback_srcs);
565 netj->playback_srcs = NULL;
567 #if HAVE_CELT
568 if( netj->bitdepth == CELT_MODE )
569 celt_mode_destroy(netj->celt_mode);
570 #endif
571 #if HAVE_OPUS
572 if( netj->bitdepth == OPUS_MODE )
573 opus_custom_mode_destroy(netj->opus_mode);
574 #endif
578 netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
579 jack_client_t * client,
580 const char *name,
581 unsigned int capture_ports,
582 unsigned int playback_ports,
583 unsigned int capture_ports_midi,
584 unsigned int playback_ports_midi,
585 jack_nframes_t sample_rate,
586 jack_nframes_t period_size,
587 unsigned int listen_port,
588 unsigned int transport_sync,
589 unsigned int resample_factor,
590 unsigned int resample_factor_up,
591 unsigned int bitdepth,
592 unsigned int use_autoconfig,
593 unsigned int latency,
594 unsigned int redundancy,
595 int dont_htonl_floats,
596 int always_deadline,
597 int jitter_val )
600 // Fill in netj values.
601 // might be subject to autoconfig...
602 // so don't calculate anything with them...
604 netj->sample_rate = sample_rate;
605 netj->period_size = period_size;
606 netj->dont_htonl_floats = dont_htonl_floats;
608 netj->listen_port = listen_port;
610 netj->capture_channels = capture_ports + capture_ports_midi;
611 netj->capture_channels_audio = capture_ports;
612 netj->capture_channels_midi = capture_ports_midi;
613 netj->capture_ports = NULL;
614 netj->playback_channels = playback_ports + playback_ports_midi;
615 netj->playback_channels_audio = playback_ports;
616 netj->playback_channels_midi = playback_ports_midi;
617 netj->playback_ports = NULL;
618 netj->codec_latency = 0;
620 netj->handle_transport_sync = transport_sync;
621 netj->mtu = 1400;
622 netj->latency = latency;
623 netj->redundancy = redundancy;
624 netj->use_autoconfig = use_autoconfig;
625 netj->always_deadline = always_deadline;
627 netj->client = client;
629 if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE) && (bitdepth != OPUS_MODE)) {
630 jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth);
631 return NULL;
633 netj->bitdepth = bitdepth;
635 if (resample_factor_up == 0) {
636 resample_factor_up = resample_factor;
639 netj->resample_factor = resample_factor;
640 netj->resample_factor_up = resample_factor_up;
642 netj->jitter_val = jitter_val;
644 netj->playback_srcs = NULL;
645 netj->capture_srcs = NULL;
647 return netj;
650 void netjack_release( netjack_driver_state_t *netj )
652 close( netj->sockfd );
653 close( netj->outsockfd );
655 packet_cache_free( netj->packcache );
656 netj->packcache = NULL;
660 netjack_startup( netjack_driver_state_t *netj )
662 int first_pack_len;
663 struct sockaddr_in address;
664 // Now open the socket, and wait for the first packet to arrive...
665 netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0);
666 #ifdef WIN32
667 if (netj->sockfd == INVALID_SOCKET)
668 #else
669 if (netj->sockfd == -1)
670 #endif
672 jack_info ("socket error");
673 return -1;
675 address.sin_family = AF_INET;
676 address.sin_port = htons(netj->listen_port);
677 address.sin_addr.s_addr = htonl(INADDR_ANY);
678 if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0) {
679 jack_info("bind error");
680 return -1;
683 netj->outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
684 #ifdef WIN32
685 if (netj->outsockfd == INVALID_SOCKET)
686 #else
687 if (netj->outsockfd == -1)
688 #endif
690 jack_info ("socket error");
691 return -1;
693 netj->srcaddress_valid = 0;
694 if (netj->use_autoconfig) {
695 jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header));
696 #ifdef WIN32
697 int address_size = sizeof( struct sockaddr_in );
698 #else
699 socklen_t address_size = sizeof (struct sockaddr_in);
700 #endif
701 //jack_info ("Waiting for an incoming packet !!!");
702 //jack_info ("*** IMPORTANT *** Don't connect a client to jackd until the driver is attached to a clock source !!!");
704 while(1) {
705 if( ! netjack_poll( netj->sockfd, 1000 ) ) {
706 jack_info ("Waiting aborted");
707 return -1;
709 first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size);
710 #ifdef WIN32
711 if( first_pack_len == -1 ) {
712 first_pack_len = sizeof(jacknet_packet_header);
713 break;
715 #else
716 if (first_pack_len == sizeof (jacknet_packet_header))
717 break;
718 #endif
720 netj->srcaddress_valid = 1;
722 if (first_pack_len == sizeof (jacknet_packet_header)) {
723 packet_header_ntoh (first_packet);
725 jack_info ("AutoConfig Override !!!");
726 if (netj->sample_rate != first_packet->sample_rate) {
727 jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate);
728 netj->sample_rate = first_packet->sample_rate;
731 if (netj->period_size != first_packet->period_size) {
732 jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size);
733 netj->period_size = first_packet->period_size;
735 if (netj->capture_channels_audio != first_packet->capture_channels_audio) {
736 jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio);
737 netj->capture_channels_audio = first_packet->capture_channels_audio;
739 if (netj->capture_channels_midi != first_packet->capture_channels_midi) {
740 jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi);
741 netj->capture_channels_midi = first_packet->capture_channels_midi;
743 if (netj->playback_channels_audio != first_packet->playback_channels_audio) {
744 jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio);
745 netj->playback_channels_audio = first_packet->playback_channels_audio;
747 if (netj->playback_channels_midi != first_packet->playback_channels_midi) {
748 jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi);
749 netj->playback_channels_midi = first_packet->playback_channels_midi;
752 netj->mtu = first_packet->mtu;
753 jack_info ("MTU is set to %d bytes", first_packet->mtu);
754 netj->latency = first_packet->latency;
757 netj->capture_channels = netj->capture_channels_audio + netj->capture_channels_midi;
758 netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi;
760 if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) {
761 jack_error( "autoconfig requests more than 100MB packet cache... bailing out" );
762 exit(1);
765 if( netj->playback_channels > 1000 ) {
766 jack_error( "autoconfig requests more than 1000 playback channels... bailing out" );
767 exit(1);
771 if( netj->mtu < (2 * sizeof( jacknet_packet_header )) ) {
772 jack_error( "bullshit mtu requested by autoconfig" );
773 exit(1);
776 if( netj->sample_rate == 0 ) {
777 jack_error( "sample_rate 0 requested by autoconfig" );
778 exit(1);
781 // After possible Autoconfig: do all calculations...
782 netj->period_usecs =
783 (jack_time_t) floor ((((float) netj->period_size) / (float)netj->sample_rate)
784 * 1000000.0f);
786 if( netj->latency == 0 )
787 netj->deadline_offset = 50 * netj->period_usecs;
788 else
789 netj->deadline_offset = netj->period_usecs + 10 * netj->latency * netj->period_usecs / 100;
791 if( netj->bitdepth == CELT_MODE ) {
792 // celt mode.
793 // TODO: this is a hack. But i don't want to change the packet header.
794 netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
795 netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
797 netj->net_period_down = netj->resample_factor;
798 netj->net_period_up = netj->resample_factor_up;
799 } else if( netj->bitdepth == OPUS_MODE ) {
800 // Opus mode.
801 // TODO: this is a hack. But i don't want to change the packet header, either
802 netj->net_period_down = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
803 netj->net_period_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
804 } else {
805 netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor;
806 netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up;
809 netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth);
810 netj->packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu);
812 netj->expected_framecnt_valid = 0;
813 netj->num_lost_packets = 0;
814 netj->next_deadline_valid = 0;
815 netj->deadline_goodness = 0;
816 netj->time_to_deadline = 0;
818 // Special handling for latency=0
819 if( netj->latency == 0 )
820 netj->resync_threshold = 0;
821 else
822 netj->resync_threshold = MIN( 15, netj->latency - 1 );
824 netj->running_free = 0;
826 return 0;