Correct netjack2 components help.
[jack2.git] / common / netjack.c
blob74cdc5df4e60970910a6df90b2f20ec88072c487
2 /* -*- mode: c; c-file-style: "linux"; -*- */
3 /*
4 NetJack Abstraction.
6 Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
7 Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
8 Copyright (C) 2003 Robert Ham <rah@bash.sh>
9 Copyright (C) 2001 Paul Davis
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $
28 #include <math.h>
29 #include <stdio.h>
30 #include <memory.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <stdarg.h>
36 #include <jack/types.h>
37 #include "jack/jslist.h"
39 #include <sys/types.h>
41 #ifdef WIN32
42 #include <winsock.h>
43 #include <malloc.h>
44 #define socklen_t int
45 #else
46 #include <sys/socket.h>
47 #include <netinet/in.h>
48 #endif
50 #if defined(HAVE_CONFIG_H)
51 #include "config.h"
52 #endif
54 #if HAVE_SAMPLERATE
55 #include <samplerate.h>
56 #endif
58 #include "netjack.h"
59 #include "netjack_packet.h"
60 #include "JackError.h"
62 #define MIN(x,y) ((x)<(y) ? (x) : (y))
64 static int sync_state = 1;
65 static jack_transport_state_t last_transport_state;
67 static int
68 net_driver_sync_cb(jack_transport_state_t state, jack_position_t *pos, void *data)
70 int retval = sync_state;
72 if (state == JackTransportStarting && last_transport_state != JackTransportStarting) {
73 retval = 0;
75 // if (state == JackTransportStarting)
76 // jack_info("Starting sync_state = %d", sync_state);
77 last_transport_state = state;
78 return retval;
81 int netjack_wait( netjack_driver_state_t *netj )
83 int we_have_the_expected_frame = 0;
84 jack_nframes_t next_frame_avail;
85 jack_time_t packet_recv_time_stamp;
86 jacknet_packet_header *pkthdr;
88 if( !netj->next_deadline_valid ) {
89 netj->next_deadline = jack_get_time() + netj->period_usecs;
90 netj->next_deadline_valid = 1;
93 // Increment expected frame here.
95 if( netj->expected_framecnt_valid ) {
96 netj->expected_framecnt += 1;
97 } else {
98 // starting up.... lets look into the packetcache, and fetch the highest packet.
99 packet_cache_drain_socket( netj->packcache, netj->sockfd );
100 if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) {
101 netj->expected_framecnt = next_frame_avail;
102 netj->expected_framecnt_valid = 1;
103 } else {
104 // no packets there... start normally.
105 netj->expected_framecnt = 0;
106 netj->expected_framecnt_valid = 1;
110 //jack_log( "expect %d", netj->expected_framecnt );
111 // Now check if required packet is already in the cache.
112 // then poll (have deadline calculated)
113 // then drain socket, rinse and repeat.
114 while(1) {
115 if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) {
116 if( next_frame_avail == netj->expected_framecnt ) {
117 we_have_the_expected_frame = 1;
118 if( !netj->always_deadline )
119 break;
122 if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) {
123 break;
126 packet_cache_drain_socket( netj->packcache, netj->sockfd );
129 // check if we know who to send our packets too.
130 if (!netj->srcaddress_valid)
131 if( netj->packcache->master_address_valid ) {
132 memcpy (&(netj->syncsource_address), &(netj->packcache->master_address), sizeof( struct sockaddr_in ) );
133 netj->srcaddress_valid = 1;
136 // XXX: switching mode unconditionally is stupid.
137 // if we were running free perhaps we like to behave differently
138 // ie. fastforward one packet etc.
139 // well... this is the first packet we see. hmm.... dunno ;S
140 // it works... so...
141 netj->running_free = 0;
143 //if( !we_have_the_expected_frame )
144 // jack_error( "netxrun... %d", netj->expected_framecnt );
146 if( we_have_the_expected_frame ) {
148 jack_time_t now = jack_get_time();
149 if( now < netj->next_deadline )
150 netj->time_to_deadline = netj->next_deadline - now;
151 else
152 netj->time_to_deadline = 0;
154 packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp);
155 pkthdr = (jacknet_packet_header *) netj->rx_buf;
156 packet_header_ntoh(pkthdr);
157 netj->deadline_goodness = (int)pkthdr->sync_state;
158 netj->packet_data_valid = 1;
160 int want_deadline;
161 if( netj->jitter_val != 0 )
162 want_deadline = netj->jitter_val;
163 else if( netj->latency < 4 )
164 want_deadline = -netj->period_usecs / 2;
165 else
166 want_deadline = (netj->period_usecs / 4 + 10 * (int)netj->period_usecs * netj->latency / 100);
168 if( netj->deadline_goodness != MASTER_FREEWHEELS ) {
169 if( netj->deadline_goodness < want_deadline ) {
170 netj->next_deadline -= netj->period_usecs / 100;
171 //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
173 if( netj->deadline_goodness > want_deadline ) {
174 netj->next_deadline += netj->period_usecs / 100;
175 //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
178 // if( netj->next_deadline < (netj->period_usecs*70/100) ) {
179 // jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" );
180 // netj->deadline_offset = (netj->period_usecs*90/100);
181 // }
183 netj->next_deadline += netj->period_usecs;
184 } else {
185 netj->time_to_deadline = 0;
186 netj->next_deadline += netj->period_usecs;
187 // bah... the packet is not there.
188 // either
189 // - it got lost.
190 // - its late
191 // - sync source is not sending anymore.
193 // lets check if we have the next packets, we will just run a cycle without data.
194 // in that case.
196 if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) {
197 jack_nframes_t offset = next_frame_avail - netj->expected_framecnt;
199 //XXX: hmm... i need to remember why resync_threshold wasnt right.
200 //if( offset < netj->resync_threshold )
201 if( offset < 10 ) {
202 // ok. dont do nothing. we will run without data.
203 // this seems to be one or 2 lost packets.
205 // this can also be reordered packet jitter.
206 // (maybe this is not happening in real live)
207 // but it happens in netem.
209 netj->packet_data_valid = 0;
211 // I also found this happening, when the packet queue, is too full.
212 // but wtf ? use a smaller latency. this link can handle that ;S
213 if( packet_cache_get_fill( netj->packcache, netj->expected_framecnt ) > 80.0 )
214 netj->next_deadline -= netj->period_usecs / 2;
217 } else {
218 // the diff is too high. but we have a packet in the future.
219 // lets resync.
220 netj->expected_framecnt = next_frame_avail;
221 packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL );
222 pkthdr = (jacknet_packet_header *) netj->rx_buf;
223 packet_header_ntoh(pkthdr);
224 //netj->deadline_goodness = 0;
225 netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset;
226 netj->next_deadline_valid = 0;
227 netj->packet_data_valid = 1;
230 } else {
231 // no packets in buffer.
232 netj->packet_data_valid = 0;
234 //printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets );
235 if( netj->num_lost_packets < 5 ) {
236 // ok. No Packet in queue. The packet was either lost,
237 // or we are running too fast.
239 // Adjusting the deadline unconditionally resulted in
240 // too many xruns on master.
241 // But we need to adjust for the case we are running too fast.
242 // So lets check if the last packet is there now.
244 // It would not be in the queue anymore, if it had been
245 // retrieved. This might break for redundancy, but
246 // i will make the packet cache drop redundant packets,
247 // that have already been retreived.
249 if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) {
250 if( next_frame_avail == (netj->expected_framecnt - 1) ) {
251 // Ok. the last packet is there now.
252 // and it had not been retrieved.
254 // TODO: We are still dropping 2 packets.
255 // perhaps we can adjust the deadline
256 // when (num_packets lost == 0)
258 // This might still be too much.
259 netj->next_deadline += netj->period_usecs;
262 } else if( (netj->num_lost_packets <= 100) ) {
263 // lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast.
264 netj->next_deadline += netj->period_usecs * netj->latency / 8;
265 } else {
267 // But now we can check for any new frame available.
269 if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) {
270 netj->expected_framecnt = next_frame_avail;
271 packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL );
272 pkthdr = (jacknet_packet_header *) netj->rx_buf;
273 packet_header_ntoh(pkthdr);
274 netj->deadline_goodness = pkthdr->sync_state;
275 netj->next_deadline_valid = 0;
276 netj->packet_data_valid = 1;
277 netj->running_free = 0;
278 jack_info( "resync after freerun... %d", netj->expected_framecnt );
279 } else {
280 if( netj->num_lost_packets == 101 ) {
281 jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt );
284 netj->running_free = 1;
286 // when we really dont see packets.
287 // reset source address. and open possibility for new master.
288 // maybe dsl reconnect. Also restart of netsource without fix
289 // reply address changes port.
290 if (netj->num_lost_packets > 200 ) {
291 netj->srcaddress_valid = 0;
292 packet_cache_reset_master_address( netj->packcache );
299 int retval = 0;
301 if( !netj->packet_data_valid ) {
302 netj->num_lost_packets += 1;
303 if( netj->num_lost_packets == 1 )
304 retval = netj->period_usecs;
305 } else {
306 if( (netj->num_lost_packets > 1) && !netj->running_free )
307 retval = (netj->num_lost_packets - 1) * netj->period_usecs;
309 netj->num_lost_packets = 0;
312 return retval;
315 void netjack_send_silence( netjack_driver_state_t *netj, int syncstate )
317 int tx_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up + sizeof(jacknet_packet_header);
318 unsigned int *packet_buf, *packet_bufX;
320 packet_buf = alloca( tx_size);
321 jacknet_packet_header *tx_pkthdr = (jacknet_packet_header *)packet_buf;
322 jacknet_packet_header *rx_pkthdr = (jacknet_packet_header *)netj->rx_buf;
324 //framecnt = rx_pkthdr->framecnt;
326 netj->reply_port = rx_pkthdr->reply_port;
328 // offset packet_bufX by the packetheader.
329 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
331 tx_pkthdr->sync_state = syncstate;
332 tx_pkthdr->framecnt = netj->expected_framecnt;
334 // memset 0 the payload.
335 int payload_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up;
336 memset(packet_bufX, 0, payload_size);
338 packet_header_hton(tx_pkthdr);
339 if (netj->srcaddress_valid) {
340 int r;
341 if (netj->reply_port)
342 netj->syncsource_address.sin_port = htons(netj->reply_port);
344 for( r = 0; r < netj->redundancy; r++ )
345 netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size,
346 0, (struct sockaddr*) & (netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu);
350 void netjack_attach( netjack_driver_state_t *netj )
352 //puts ("net_driver_attach");
353 jack_port_t * port;
354 char buf[32];
355 unsigned int chn;
356 int port_flags;
358 if( netj->bitdepth == CELT_MODE ) {
359 #if HAVE_CELT
360 #if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11
361 celt_int32 lookahead;
362 netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
363 #else
364 celt_int32_t lookahead;
365 netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
366 #endif
367 celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead );
368 netj->codec_latency = 2 * lookahead;
369 #endif
372 if (netj->handle_transport_sync)
373 jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL);
375 port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
377 for (chn = 0; chn < netj->capture_channels_audio; chn++) {
378 snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
380 port = jack_port_register (netj->client, buf,
381 JACK_DEFAULT_AUDIO_TYPE,
382 port_flags, 0);
383 if (!port) {
384 jack_error ("NET: cannot register port for %s", buf);
385 break;
388 netj->capture_ports =
389 jack_slist_append (netj->capture_ports, port);
391 if( netj->bitdepth == CELT_MODE ) {
392 #if HAVE_CELT
393 #if HAVE_CELT_API_0_11
394 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) );
395 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
396 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) );
397 #else
398 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) );
399 #endif
400 #endif
401 } else {
402 #if HAVE_SAMPLERATE
403 netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL));
404 #endif
408 for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) {
409 snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
411 port = jack_port_register (netj->client, buf,
412 JACK_DEFAULT_MIDI_TYPE,
413 port_flags, 0);
414 if (!port) {
415 jack_error ("NET: cannot register port for %s", buf);
416 break;
419 netj->capture_ports =
420 jack_slist_append (netj->capture_ports, port);
423 port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
425 for (chn = 0; chn < netj->playback_channels_audio; chn++) {
426 snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
428 port = jack_port_register (netj->client, buf,
429 JACK_DEFAULT_AUDIO_TYPE,
430 port_flags, 0);
432 if (!port) {
433 jack_error ("NET: cannot register port for %s", buf);
434 break;
437 netj->playback_ports =
438 jack_slist_append (netj->playback_ports, port);
439 if( netj->bitdepth == CELT_MODE ) {
440 #if HAVE_CELT
441 #if HAVE_CELT_API_0_11
442 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
443 netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) );
444 #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
445 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
446 netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
447 #else
448 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
449 netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) );
450 #endif
451 #endif
452 } else {
453 #if HAVE_SAMPLERATE
454 netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL));
455 #endif
458 for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) {
459 snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
461 port = jack_port_register (netj->client, buf,
462 JACK_DEFAULT_MIDI_TYPE,
463 port_flags, 0);
465 if (!port) {
466 jack_error ("NET: cannot register port for %s", buf);
467 break;
470 netj->playback_ports =
471 jack_slist_append (netj->playback_ports, port);
474 jack_activate (netj->client);
478 void netjack_detach( netjack_driver_state_t *netj )
480 JSList * node;
482 for (node = netj->capture_ports; node; node = jack_slist_next (node))
483 jack_port_unregister (netj->client,
484 ((jack_port_t *) node->data));
486 jack_slist_free (netj->capture_ports);
487 netj->capture_ports = NULL;
489 for (node = netj->capture_srcs; node; node = jack_slist_next (node)) {
490 #if HAVE_CELT
491 if( netj->bitdepth == CELT_MODE ) {
492 CELTDecoder * decoder = node->data;
493 celt_decoder_destroy(decoder);
494 } else
495 #endif
497 #if HAVE_SAMPLERATE
498 SRC_STATE * src = node->data;
499 src_delete(src);
500 #endif
503 jack_slist_free (netj->capture_srcs);
504 netj->playback_srcs = NULL;
506 for (node = netj->playback_ports; node; node = jack_slist_next (node))
507 jack_port_unregister (netj->client,
508 ((jack_port_t *) node->data));
510 jack_slist_free (netj->playback_ports);
511 netj->playback_ports = NULL;
513 for (node = netj->playback_srcs; node; node = jack_slist_next (node)) {
514 #if HAVE_CELT
515 if( netj->bitdepth == CELT_MODE ) {
516 CELTEncoder * encoder = node->data;
517 celt_encoder_destroy(encoder);
518 } else
519 #endif
521 #if HAVE_SAMPLERATE
522 SRC_STATE * src = node->data;
523 src_delete(src);
524 #endif
527 jack_slist_free (netj->playback_srcs);
528 netj->playback_srcs = NULL;
530 #if HAVE_CELT
531 if( netj->bitdepth == CELT_MODE )
532 celt_mode_destroy(netj->celt_mode);
533 #endif
537 netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
538 jack_client_t * client,
539 const char *name,
540 unsigned int capture_ports,
541 unsigned int playback_ports,
542 unsigned int capture_ports_midi,
543 unsigned int playback_ports_midi,
544 jack_nframes_t sample_rate,
545 jack_nframes_t period_size,
546 unsigned int listen_port,
547 unsigned int transport_sync,
548 unsigned int resample_factor,
549 unsigned int resample_factor_up,
550 unsigned int bitdepth,
551 unsigned int use_autoconfig,
552 unsigned int latency,
553 unsigned int redundancy,
554 int dont_htonl_floats,
555 int always_deadline,
556 int jitter_val )
559 // Fill in netj values.
560 // might be subject to autoconfig...
561 // so dont calculate anything with them...
564 netj->sample_rate = sample_rate;
565 netj->period_size = period_size;
566 netj->dont_htonl_floats = dont_htonl_floats;
568 netj->listen_port = listen_port;
570 netj->capture_channels = capture_ports + capture_ports_midi;
571 netj->capture_channels_audio = capture_ports;
572 netj->capture_channels_midi = capture_ports_midi;
573 netj->capture_ports = NULL;
574 netj->playback_channels = playback_ports + playback_ports_midi;
575 netj->playback_channels_audio = playback_ports;
576 netj->playback_channels_midi = playback_ports_midi;
577 netj->playback_ports = NULL;
578 netj->codec_latency = 0;
580 netj->handle_transport_sync = transport_sync;
581 netj->mtu = 1400;
582 netj->latency = latency;
583 netj->redundancy = redundancy;
584 netj->use_autoconfig = use_autoconfig;
585 netj->always_deadline = always_deadline;
588 netj->client = client;
591 if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE)) {
592 jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth);
593 return NULL;
595 netj->bitdepth = bitdepth;
598 if (resample_factor_up == 0)
599 resample_factor_up = resample_factor;
601 netj->resample_factor = resample_factor;
602 netj->resample_factor_up = resample_factor_up;
604 netj->jitter_val = jitter_val;
606 return netj;
609 void netjack_release( netjack_driver_state_t *netj )
611 close( netj->sockfd );
612 close( netj->outsockfd );
614 packet_cache_free( netj->packcache );
615 netj->packcache = NULL;
619 netjack_startup( netjack_driver_state_t *netj )
621 int first_pack_len;
622 struct sockaddr_in address;
623 // Now open the socket, and wait for the first packet to arrive...
624 netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0);
625 #ifdef WIN32
626 if (netj->sockfd == INVALID_SOCKET)
627 #else
628 if (netj->sockfd == -1)
629 #endif
631 jack_info ("socket error");
632 return -1;
634 address.sin_family = AF_INET;
635 address.sin_port = htons(netj->listen_port);
636 address.sin_addr.s_addr = htonl(INADDR_ANY);
637 if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0) {
638 jack_info("bind error");
639 return -1;
642 netj->outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
643 #ifdef WIN32
644 if (netj->outsockfd == INVALID_SOCKET)
645 #else
646 if (netj->outsockfd == -1)
647 #endif
649 jack_info ("socket error");
650 return -1;
652 netj->srcaddress_valid = 0;
653 if (netj->use_autoconfig) {
654 jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header));
655 #ifdef WIN32
656 int address_size = sizeof( struct sockaddr_in );
657 #else
658 socklen_t address_size = sizeof (struct sockaddr_in);
659 #endif
660 //jack_info ("Waiting for an incoming packet !!!");
661 //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!");
663 while(1) {
664 if( ! netjack_poll( netj->sockfd, 1000 ) ) {
665 jack_info ("Waiting aborted");
666 return -1;
668 first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size);
669 #ifdef WIN32
670 if( first_pack_len == -1 ) {
671 first_pack_len = sizeof(jacknet_packet_header);
672 break;
674 #else
675 if (first_pack_len == sizeof (jacknet_packet_header))
676 break;
677 #endif
679 netj->srcaddress_valid = 1;
681 if (first_pack_len == sizeof (jacknet_packet_header)) {
682 packet_header_ntoh (first_packet);
684 jack_info ("AutoConfig Override !!!");
685 if (netj->sample_rate != first_packet->sample_rate) {
686 jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate);
687 netj->sample_rate = first_packet->sample_rate;
690 if (netj->period_size != first_packet->period_size) {
691 jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size);
692 netj->period_size = first_packet->period_size;
694 if (netj->capture_channels_audio != first_packet->capture_channels_audio) {
695 jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio);
696 netj->capture_channels_audio = first_packet->capture_channels_audio;
698 if (netj->capture_channels_midi != first_packet->capture_channels_midi) {
699 jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi);
700 netj->capture_channels_midi = first_packet->capture_channels_midi;
702 if (netj->playback_channels_audio != first_packet->playback_channels_audio) {
703 jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio);
704 netj->playback_channels_audio = first_packet->playback_channels_audio;
706 if (netj->playback_channels_midi != first_packet->playback_channels_midi) {
707 jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi);
708 netj->playback_channels_midi = first_packet->playback_channels_midi;
711 netj->mtu = first_packet->mtu;
712 jack_info ("MTU is set to %d bytes", first_packet->mtu);
713 netj->latency = first_packet->latency;
716 netj->capture_channels = netj->capture_channels_audio + netj->capture_channels_midi;
717 netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi;
719 if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) {
720 jack_error( "autoconfig requests more than 100MB packet cache... bailing out" );
721 exit(1);
724 if( netj->playback_channels > 1000 ) {
725 jack_error( "autoconfig requests more than 1000 playback channels... bailing out" );
726 exit(1);
730 if( netj->mtu < (2 * sizeof( jacknet_packet_header )) ) {
731 jack_error( "bullshit mtu requested by autoconfig" );
732 exit(1);
735 if( netj->sample_rate == 0 ) {
736 jack_error( "sample_rate 0 requested by autoconfig" );
737 exit(1);
740 // After possible Autoconfig: do all calculations...
741 netj->period_usecs =
742 (jack_time_t) floor ((((float) netj->period_size) / (float)netj->sample_rate)
743 * 1000000.0f);
745 if( netj->latency == 0 )
746 netj->deadline_offset = 50 * netj->period_usecs;
747 else
748 netj->deadline_offset = netj->period_usecs + 10 * netj->latency * netj->period_usecs / 100;
750 if( netj->bitdepth == CELT_MODE ) {
751 // celt mode.
752 // TODO: this is a hack. But i dont want to change the packet header.
753 netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
754 netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1);
756 netj->net_period_down = netj->resample_factor;
757 netj->net_period_up = netj->resample_factor_up;
758 } else {
759 netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor;
760 netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up;
763 netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth);
764 netj->packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu);
766 netj->expected_framecnt_valid = 0;
767 netj->num_lost_packets = 0;
768 netj->next_deadline_valid = 0;
769 netj->deadline_goodness = 0;
770 netj->time_to_deadline = 0;
772 // Special handling for latency=0
773 if( netj->latency == 0 )
774 netj->resync_threshold = 0;
775 else
776 netj->resync_threshold = MIN( 15, netj->latency - 1 );
778 netj->running_free = 0;
780 return 0;