Unused variable.
[jack2.git] / common / netjack.c
blobeb5f36b7374c0ac2d0d6bf371167dbf0442bbcf3
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 $
29 #include <math.h>
30 #include <stdio.h>
31 #include <memory.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <stdarg.h>
37 #include <jack/types.h>
38 #include "jack/jslist.h"
40 #include <sys/types.h>
42 #ifdef WIN32
43 #include <winsock.h>
44 #include <malloc.h>
45 #else
46 #include <sys/socket.h>
47 #include <netinet/in.h>
48 #endif
50 #include "netjack.h"
52 //#include "config.h"
54 #if HAVE_SAMPLERATE
55 #include <samplerate.h>
56 #endif
58 #if HAVE_CELT
59 #include <celt/celt.h>
60 #endif
62 #include "netjack.h"
63 #include "netjack_packet.h"
65 // JACK2
66 #include "jack/control.h"
68 #define MIN(x,y) ((x)<(y) ? (x) : (y))
70 static int sync_state = 1;
71 static jack_transport_state_t last_transport_state;
73 static int
74 net_driver_sync_cb(jack_transport_state_t state, jack_position_t *pos, void *data)
76 int retval = sync_state;
78 if (state == JackTransportStarting && last_transport_state != JackTransportStarting) {
79 retval = 0;
81 // if (state == JackTransportStarting)
82 // jack_info("Starting sync_state = %d", sync_state);
83 last_transport_state = state;
84 return retval;
87 int netjack_wait( netjack_driver_state_t *netj )
89 int we_have_the_expected_frame = 0;
90 jack_nframes_t next_frame_avail;
91 jack_time_t packet_recv_time_stamp;
92 jacknet_packet_header *pkthdr;
94 if( !netj->next_deadline_valid ) {
95 netj->next_deadline = jack_get_time() + netj->deadline_offset;
96 netj->next_deadline_valid = 1;
99 // Increment expected frame here.
101 if( netj->expected_framecnt_valid ) {
102 netj->expected_framecnt += 1;
103 } else {
104 // starting up.... lets look into the packetcache, and fetch the highest packet.
105 packet_cache_drain_socket( global_packcache, netj->sockfd );
106 if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail ) ) {
107 netj->expected_framecnt = next_frame_avail;
108 netj->expected_framecnt_valid = 1;
109 } else {
110 // no packets there... start normally.
111 netj->expected_framecnt = 0;
112 netj->expected_framecnt_valid = 1;
117 //jack_log( "expect %d", netj->expected_framecnt );
118 // Now check if required packet is already in the cache.
119 // then poll (have deadline calculated)
120 // then drain socket, rinse and repeat.
121 while(1) {
122 if( packet_cache_get_next_available_framecnt( global_packcache, netj->expected_framecnt, &next_frame_avail) ) {
123 if( next_frame_avail == netj->expected_framecnt ) {
124 we_have_the_expected_frame = 1;
125 if( !netj->always_deadline )
126 break;
129 if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) {
130 break;
133 packet_cache_drain_socket( global_packcache, netj->sockfd );
136 // check if we know who to send our packets too.
137 if (!netj->srcaddress_valid)
138 if( global_packcache->master_address_valid ) {
139 memcpy (&(netj->syncsource_address), &(global_packcache->master_address), sizeof( struct sockaddr_in ) );
140 netj->srcaddress_valid = 1;
143 // XXX: switching mode unconditionally is stupid.
144 // if we were running free perhaps we like to behave differently
145 // ie. fastforward one packet etc.
146 // well... this is the first packet we see. hmm.... dunno ;S
147 // it works... so...
148 netj->running_free = 0;
150 //if( !we_have_the_expected_frame )
151 // jack_error( "netxrun... %d", netj->expected_framecnt );
153 if( we_have_the_expected_frame ) {
155 jack_time_t now = jack_get_time();
156 if( now < netj->next_deadline )
157 netj->time_to_deadline = netj->next_deadline - now;
158 else
159 netj->time_to_deadline = 0;
161 packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp);
162 pkthdr = (jacknet_packet_header *) netj->rx_buf;
163 packet_header_ntoh(pkthdr);
164 netj->deadline_goodness = (int)pkthdr->sync_state;
165 netj->packet_data_valid = 1;
167 int want_deadline;
168 if( netj->jitter_val != 0 )
169 want_deadline = netj->jitter_val;
170 else if( netj->latency < 4 )
171 want_deadline = -netj->period_usecs/2;
172 else
173 want_deadline = (netj->period_usecs/4+10*(int)netj->period_usecs*netj->latency/100);
175 if( netj->deadline_goodness != MASTER_FREEWHEELS ) {
176 if( netj->deadline_goodness < want_deadline ) {
177 netj->deadline_offset -= netj->period_usecs/100;
178 //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
180 if( netj->deadline_goodness > want_deadline ) {
181 netj->deadline_offset += netj->period_usecs/100;
182 //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 );
185 if( netj->deadline_offset < (netj->period_usecs*70/100) ) {
186 jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" );
187 netj->deadline_offset = (netj->period_usecs*90/100);
190 netj->next_deadline = jack_get_time() + netj->deadline_offset;
191 } else {
192 netj->time_to_deadline = 0;
193 netj->next_deadline = jack_get_time() + netj->deadline_offset;
194 // bah... the packet is not there.
195 // either
196 // - it got lost.
197 // - its late
198 // - sync source is not sending anymore.
200 // lets check if we have the next packets, we will just run a cycle without data.
201 // in that case.
203 if( packet_cache_get_next_available_framecnt( global_packcache, netj->expected_framecnt, &next_frame_avail) )
205 jack_nframes_t offset = next_frame_avail - netj->expected_framecnt;
207 //XXX: hmm... i need to remember why resync_threshold wasnt right.
208 //if( offset < netj->resync_threshold )
209 if( offset < 10 ) {
210 // ok. dont do nothing. we will run without data.
211 // this seems to be one or 2 lost packets.
213 // this can also be reordered packet jitter.
214 // (maybe this is not happening in real live)
215 // but it happens in netem.
217 netj->packet_data_valid = 0;
219 // I also found this happening, when the packet queue, is too full.
220 // but wtf ? use a smaller latency. this link can handle that ;S
221 if( packet_cache_get_fill( global_packcache, netj->expected_framecnt ) > 80.0 )
222 netj->next_deadline -= netj->period_usecs/2;
225 } else {
226 // the diff is too high. but we have a packet in the future.
227 // lets resync.
228 netj->expected_framecnt = next_frame_avail;
229 packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL );
230 pkthdr = (jacknet_packet_header *) netj->rx_buf;
231 packet_header_ntoh(pkthdr);
232 //netj->deadline_goodness = 0;
233 netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset;
234 netj->next_deadline_valid = 0;
235 netj->packet_data_valid = 1;
238 } else {
239 // no packets in buffer.
240 netj->packet_data_valid = 0;
242 //printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets );
243 if( netj->num_lost_packets < 5 ) {
244 // ok. No Packet in queue. The packet was either lost,
245 // or we are running too fast.
247 // Adjusting the deadline unconditionally resulted in
248 // too many xruns on master.
249 // But we need to adjust for the case we are running too fast.
250 // So lets check if the last packet is there now.
252 // It would not be in the queue anymore, if it had been
253 // retrieved. This might break for redundancy, but
254 // i will make the packet cache drop redundant packets,
255 // that have already been retreived.
257 if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail) ) {
258 if( next_frame_avail == (netj->expected_framecnt - 1) ) {
259 // Ok. the last packet is there now.
260 // and it had not been retrieved.
262 // TODO: We are still dropping 2 packets.
263 // perhaps we can adjust the deadline
264 // when (num_packets lost == 0)
266 // This might still be too much.
267 netj->next_deadline += netj->period_usecs;
270 } else if( (netj->num_lost_packets <= 100) ) {
271 // lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast.
272 netj->next_deadline += netj->period_usecs*netj->latency/8;
273 } else {
275 // But now we can check for any new frame available.
277 if( packet_cache_get_highest_available_framecnt( global_packcache, &next_frame_avail) ) {
278 netj->expected_framecnt = next_frame_avail;
279 packet_cache_retreive_packet_pointer( global_packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL );
280 pkthdr = (jacknet_packet_header *) netj->rx_buf;
281 packet_header_ntoh(pkthdr);
282 netj->deadline_goodness = pkthdr->sync_state;
283 netj->next_deadline_valid = 0;
284 netj->packet_data_valid = 1;
285 netj->running_free = 0;
286 jack_info( "resync after freerun... %d", netj->expected_framecnt );
287 } else {
288 if( netj->num_lost_packets == 101 ) {
289 jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt );
292 netj->running_free = 1;
294 // when we really dont see packets.
295 // reset source address. and open possibility for new master.
296 // maybe dsl reconnect. Also restart of netsource without fix
297 // reply address changes port.
298 if (netj->num_lost_packets > 200 ) {
299 netj->srcaddress_valid = 0;
300 packet_cache_reset_master_address( global_packcache );
307 int retval = 0;
309 if( !netj->packet_data_valid ) {
310 netj->num_lost_packets += 1;
311 if( netj->num_lost_packets == 1 )
312 retval = netj->period_usecs;
313 } else {
314 if( (netj->num_lost_packets>1) && !netj->running_free )
315 retval = (netj->num_lost_packets-1) * netj->period_usecs;
317 netj->num_lost_packets = 0;
320 return retval;
323 void netjack_send_silence( netjack_driver_state_t *netj, int syncstate )
325 int tx_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up + sizeof(jacknet_packet_header);
326 unsigned int *packet_buf, *packet_bufX;
328 packet_buf = alloca( tx_size);
329 jacknet_packet_header *tx_pkthdr = (jacknet_packet_header *)packet_buf;
330 jacknet_packet_header *rx_pkthdr = (jacknet_packet_header *)netj->rx_buf;
332 //framecnt = rx_pkthdr->framecnt;
334 netj->reply_port = rx_pkthdr->reply_port;
336 // offset packet_bufX by the packetheader.
337 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
339 tx_pkthdr->sync_state = syncstate;
340 tx_pkthdr->framecnt = netj->expected_framecnt;
342 // memset 0 the payload.
343 int payload_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up;
344 memset(packet_bufX, 0, payload_size);
346 packet_header_hton(tx_pkthdr);
347 if (netj->srcaddress_valid)
349 int r;
350 if (netj->reply_port)
351 netj->syncsource_address.sin_port = htons(netj->reply_port);
353 for( r=0; r<netj->redundancy; r++ )
354 netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size,
355 0, (struct sockaddr*)&(netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu);
360 void netjack_attach( netjack_driver_state_t *netj )
362 //puts ("net_driver_attach");
363 jack_port_t * port;
364 char buf[32];
365 unsigned int chn;
366 int port_flags;
369 if (netj->handle_transport_sync)
370 jack_set_sync_callback(netj->client, (JackSyncCallback) net_driver_sync_cb, NULL);
372 port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
374 for (chn = 0; chn < netj->capture_channels_audio; chn++) {
375 snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
377 port = jack_port_register (netj->client, buf,
378 JACK_DEFAULT_AUDIO_TYPE,
379 port_flags, 0);
380 if (!port) {
381 jack_error ("NET: cannot register port for %s", buf);
382 break;
385 netj->capture_ports =
386 jack_slist_append (netj->capture_ports, port);
388 if( netj->bitdepth == CELT_MODE ) {
389 #if HAVE_CELT
390 #if HAVE_CELT_API_0_7
391 celt_int32 lookahead;
392 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL );
393 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) );
394 #else
395 celt_int32_t lookahead;
396 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
397 netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( celt_mode ) );
398 #endif
399 celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead );
400 netj->codec_latency = 2*lookahead;
401 #endif
402 } else {
403 #if HAVE_SAMPLERATE
404 netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL));
405 #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_7
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_encoder_create( celt_mode, 1, NULL ) );
444 #else
445 CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL );
446 netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) );
447 #endif
448 #endif
449 } else {
450 #if HAVE_SAMPLERATE
451 netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL));
452 #endif
455 for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) {
456 snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
458 port = jack_port_register (netj->client, buf,
459 JACK_DEFAULT_MIDI_TYPE,
460 port_flags, 0);
462 if (!port) {
463 jack_error ("NET: cannot register port for %s", buf);
464 break;
467 netj->playback_ports =
468 jack_slist_append (netj->playback_ports, port);
471 jack_activate (netj->client);
475 void netjack_detach( netjack_driver_state_t *netj )
477 JSList * node;
480 for (node = netj->capture_ports; node; node = jack_slist_next (node))
481 jack_port_unregister (netj->client,
482 ((jack_port_t *) node->data));
484 jack_slist_free (netj->capture_ports);
485 netj->capture_ports = NULL;
487 for (node = netj->playback_ports; node; node = jack_slist_next (node))
488 jack_port_unregister (netj->client,
489 ((jack_port_t *) node->data));
491 jack_slist_free (netj->playback_ports);
492 netj->playback_ports = NULL;
496 netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj,
497 jack_client_t * client,
498 const char *name,
499 unsigned int capture_ports,
500 unsigned int playback_ports,
501 unsigned int capture_ports_midi,
502 unsigned int playback_ports_midi,
503 jack_nframes_t sample_rate,
504 jack_nframes_t period_size,
505 unsigned int listen_port,
506 unsigned int transport_sync,
507 unsigned int resample_factor,
508 unsigned int resample_factor_up,
509 unsigned int bitdepth,
510 unsigned int use_autoconfig,
511 unsigned int latency,
512 unsigned int redundancy,
513 int dont_htonl_floats,
514 int always_deadline,
515 int jitter_val )
518 // Fill in netj values.
519 // might be subject to autoconfig...
520 // so dont calculate anything with them...
523 netj->sample_rate = sample_rate;
524 netj->period_size = period_size;
525 netj->dont_htonl_floats = dont_htonl_floats;
527 netj->listen_port = listen_port;
529 netj->capture_channels = capture_ports + capture_ports_midi;
530 netj->capture_channels_audio = capture_ports;
531 netj->capture_channels_midi = capture_ports_midi;
532 netj->capture_ports = NULL;
533 netj->playback_channels = playback_ports + playback_ports_midi;
534 netj->playback_channels_audio = playback_ports;
535 netj->playback_channels_midi = playback_ports_midi;
536 netj->playback_ports = NULL;
537 netj->codec_latency = 0;
539 netj->handle_transport_sync = transport_sync;
540 netj->mtu = 1400;
541 netj->latency = latency;
542 netj->redundancy = redundancy;
543 netj->use_autoconfig = use_autoconfig;
544 netj->always_deadline = always_deadline;
547 netj->client = client;
550 if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE))
552 jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth);
553 return NULL;
555 netj->bitdepth = bitdepth;
558 if (resample_factor_up == 0)
559 resample_factor_up = resample_factor;
561 netj->resample_factor = resample_factor;
562 netj->resample_factor_up = resample_factor_up;
565 return netj;
568 void netjack_release( netjack_driver_state_t *netj )
570 close( netj->sockfd );
571 close( netj->outsockfd );
573 packet_cache_free( global_packcache );
574 global_packcache = NULL;
578 netjack_startup( netjack_driver_state_t *netj )
580 int first_pack_len;
581 struct sockaddr_in address;
582 // Now open the socket, and wait for the first packet to arrive...
583 netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0);
584 #ifdef WIN32
585 if (netj->sockfd == INVALID_SOCKET)
586 #else
587 if (netj->sockfd == -1)
588 #endif
590 jack_info ("socket error");
591 return -1;
593 address.sin_family = AF_INET;
594 address.sin_port = htons(netj->listen_port);
595 address.sin_addr.s_addr = htonl(INADDR_ANY);
596 if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0)
598 jack_info("bind error");
599 return -1;
602 netj->outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
603 #ifdef WIN32
604 if (netj->outsockfd == INVALID_SOCKET)
605 #else
606 if (netj->outsockfd == -1)
607 #endif
609 jack_info ("socket error");
610 return -1;
612 netj->srcaddress_valid = 0;
613 if (netj->use_autoconfig)
615 jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header));
616 #ifdef WIN32
617 int address_size = sizeof( struct sockaddr_in );
618 #else
619 socklen_t address_size = sizeof (struct sockaddr_in);
620 #endif
621 //jack_info ("Waiting for an incoming packet !!!");
622 //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!");
624 while(1) {
625 first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size);
626 #ifdef WIN32
627 if( first_pack_len == -1 ) {
628 first_pack_len = sizeof(jacknet_packet_header);
629 break;
631 #else
632 if (first_pack_len == sizeof (jacknet_packet_header))
633 break;
634 #endif
636 netj->srcaddress_valid = 1;
638 if (first_pack_len == sizeof (jacknet_packet_header))
640 packet_header_ntoh (first_packet);
642 jack_info ("AutoConfig Override !!!");
643 if (netj->sample_rate != first_packet->sample_rate)
645 jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate);
646 netj->sample_rate = first_packet->sample_rate;
649 if (netj->period_size != first_packet->period_size)
651 jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size);
652 netj->period_size = first_packet->period_size;
654 if (netj->capture_channels_audio != first_packet->capture_channels_audio)
656 jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio);
657 netj->capture_channels_audio = first_packet->capture_channels_audio;
659 if (netj->capture_channels_midi != first_packet->capture_channels_midi)
661 jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi);
662 netj->capture_channels_midi = first_packet->capture_channels_midi;
664 if (netj->playback_channels_audio != first_packet->playback_channels_audio)
666 jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio);
667 netj->playback_channels_audio = first_packet->playback_channels_audio;
669 if (netj->playback_channels_midi != first_packet->playback_channels_midi)
671 jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi);
672 netj->playback_channels_midi = first_packet->playback_channels_midi;
675 netj->mtu = first_packet->mtu;
676 jack_info ("MTU is set to %d bytes", first_packet->mtu);
677 netj->latency = first_packet->latency;
680 netj->capture_channels = netj->capture_channels_audio + netj->capture_channels_midi;
681 netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi;
683 if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) {
684 jack_error( "autoconfig requests more than 100MB packet cache... bailing out" );
685 exit(1);
688 if( netj->playback_channels > 1000 ) {
689 jack_error( "autoconfig requests more than 1000 playback channels... bailing out" );
690 exit(1);
694 if( netj->mtu < (2*sizeof( jacknet_packet_header )) ) {
695 jack_error( "bullshit mtu requested by autoconfig" );
696 exit(1);
699 if( netj->sample_rate == 0 ) {
700 jack_error( "sample_rate 0 requested by autoconfig" );
701 exit(1);
704 // After possible Autoconfig: do all calculations...
705 netj->period_usecs =
706 (jack_time_t) floor ((((float) netj->period_size) / (float)netj->sample_rate)
707 * 1000000.0f);
709 if( netj->latency == 0 )
710 netj->deadline_offset = 50*netj->period_usecs;
711 else
712 netj->deadline_offset = netj->period_usecs + 10*netj->latency*netj->period_usecs/100;
714 if( netj->bitdepth == CELT_MODE ) {
715 // celt mode.
716 // TODO: this is a hack. But i dont want to change the packet header.
717 netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1);
718 netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1);
720 netj->net_period_down = netj->resample_factor;
721 netj->net_period_up = netj->resample_factor_up;
722 } else {
723 netj->net_period_down = (float) netj->period_size / (float) netj->resample_factor;
724 netj->net_period_up = (float) netj->period_size / (float) netj->resample_factor_up;
727 netj->rx_bufsize = sizeof (jacknet_packet_header) + netj->net_period_down * netj->capture_channels * get_sample_size (netj->bitdepth);
728 netj->pkt_buf = malloc (netj->rx_bufsize);
729 global_packcache = packet_cache_new (netj->latency + 50, netj->rx_bufsize, netj->mtu);
731 netj->expected_framecnt_valid = 0;
732 netj->num_lost_packets = 0;
733 netj->next_deadline_valid = 0;
734 netj->deadline_goodness = 0;
735 netj->time_to_deadline = 0;
737 // Special handling for latency=0
738 if( netj->latency == 0 )
739 netj->resync_threshold = 0;
740 else
741 netj->resync_threshold = MIN( 15, netj->latency-1 );
743 netj->running_free = 0;
745 return 0;