Merge branch 'master' into port_register_notification_defer
[jack2.git] / example-clients / netsource.c
blob32b06fc2eeeaaae070b2dfa74c4bf7af2e91bcfd
1 /*
2 NetJack Client
4 Copyright (C) 2008 Marc-Olivier Barre <marco@marcochapeau.org>
5 Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
6 Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /** @file netsource.c
26 * @brief This client connects a remote slave JACK to a local JACK server assumed to be the master
30 #include <stdio.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <signal.h>
37 #ifdef WIN32
38 #include <winsock2.h>
39 #define socklen_t int
40 #include <malloc.h>
41 #else
42 #include <netinet/in.h>
43 #include <netdb.h>
44 #include <sys/socket.h>
45 #endif
47 /* These two required by FreeBSD. */
48 #include <sys/types.h>
51 #include <jack/jack.h>
53 //#include <net_driver.h>
54 #include <netjack_packet.h>
55 #if HAVE_SAMPLERATE
56 #include <samplerate.h>
57 #endif
59 #if HAVE_CELT
60 #include <celt/celt.h>
61 #endif
63 #include <math.h>
65 JSList *capture_ports = NULL;
66 JSList *capture_srcs = NULL;
67 int capture_channels = 0;
68 int capture_channels_audio = 2;
69 int capture_channels_midi = 1;
70 JSList *playback_ports = NULL;
71 JSList *playback_srcs = NULL;
72 int playback_channels = 0;
73 int playback_channels_audio = 2;
74 int playback_channels_midi = 1;
75 int dont_htonl_floats = 0;
77 int latency = 5;
78 jack_nframes_t factor = 1;
79 int bitdepth = 0;
80 int mtu = 1400;
81 int reply_port = 0;
82 int bind_port = 0;
83 int redundancy = 1;
84 jack_client_t *client;
86 int state_connected = 0;
87 int state_latency = 0;
88 int state_netxruns = 0;
89 int state_currentframe = 0;
90 int state_recv_packet_queue_time = 0;
92 int quit=0;
95 int outsockfd;
96 int insockfd;
97 #ifdef WIN32
98 struct sockaddr_in destaddr;
99 struct sockaddr_in bindaddr;
100 #else
101 struct sockaddr destaddr;
102 struct sockaddr bindaddr;
103 #endif
105 int sync_state;
106 jack_transport_state_t last_transport_state;
108 int framecnt = 0;
110 int cont_miss = 0;
112 int freewheeling = 0;
115 * This Function allocates all the I/O Ports which are added the lists.
117 void
118 alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi)
121 int port_flags = JackPortIsOutput;
122 int chn;
123 jack_port_t *port;
124 char buf[32];
126 capture_ports = NULL;
127 /* Allocate audio capture channels */
128 for (chn = 0; chn < n_capture_audio; chn++)
130 snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
131 port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
132 if (!port)
134 printf( "jack_netsource: cannot register %s port\n", buf);
135 break;
137 if( bitdepth == 1000 ) {
138 #if HAVE_CELT
139 #if HAVE_CELT_API_0_7
140 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL );
141 capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) );
142 #else
143 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL );
144 capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
145 #endif
146 #endif
147 } else {
148 #if HAVE_SAMPLERATE
149 capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
150 #endif
152 capture_ports = jack_slist_append (capture_ports, port);
155 /* Allocate midi capture channels */
156 for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++)
158 snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
159 port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
160 if (!port)
162 printf ("jack_netsource: cannot register %s port\n", buf);
163 break;
165 capture_ports = jack_slist_append(capture_ports, port);
168 /* Allocate audio playback channels */
169 port_flags = JackPortIsInput;
170 playback_ports = NULL;
171 for (chn = 0; chn < n_playback_audio; chn++)
173 snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
174 port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
175 if (!port)
177 printf ("jack_netsource: cannot register %s port\n", buf);
178 break;
180 if( bitdepth == 1000 ) {
181 #if HAVE_CELT
182 #if HAVE_CELT_API_0_7
183 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL );
184 playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
185 #else
186 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL );
187 playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
188 #endif
189 #endif
190 } else {
191 #if HAVE_SAMPLERATE
192 playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
193 #endif
195 playback_ports = jack_slist_append (playback_ports, port);
198 /* Allocate midi playback channels */
199 for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++)
201 snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
202 port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
203 if (!port)
205 printf ("jack_netsource: cannot register %s port\n", buf);
206 break;
208 playback_ports = jack_slist_append (playback_ports, port);
213 * The Sync callback... sync state is set elsewhere...
214 * we will see if this is working correctly.
215 * i dont really believe in it yet.
218 sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
220 static int latency_count = 0;
221 int retval = sync_state;
223 if (latency_count) {
224 latency_count--;
225 retval = 0;
228 else if (state == JackTransportStarting && last_transport_state != JackTransportStarting)
230 retval = 0;
231 latency_count = latency - 1;
234 last_transport_state = state;
235 return retval;
238 void
239 freewheel_cb (int starting, void *arg)
241 freewheeling = starting;
244 int deadline_goodness=0;
246 * The process callback for this JACK application.
247 * It is called by JACK at the appropriate times.
250 process (jack_nframes_t nframes, void *arg)
252 jack_nframes_t net_period;
253 int rx_bufsize, tx_bufsize;
255 jack_default_audio_sample_t *buf;
256 jack_port_t *port;
257 JSList *node;
258 int chn;
259 int size, i;
260 const char *porttype;
261 int input_fd;
263 jack_position_t local_trans_pos;
265 uint32_t *packet_buf, *packet_bufX;
266 uint32_t *rx_packet_ptr;
267 jack_time_t packet_recv_timestamp;
269 if( bitdepth == 1000 )
270 net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ;
271 else
272 net_period = (float) nframes / (float) factor;
274 rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
275 tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header);
278 /* Allocate a buffer where both In and Out Buffer will fit */
279 packet_buf = alloca ((rx_bufsize > tx_bufsize) ? rx_bufsize : tx_bufsize);
281 jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf;
284 * for latency==0 we need to send out the packet before we wait on the reply.
285 * but this introduces a cycle of latency, when netsource is connected to itself.
286 * so we send out before read only in zero latency mode.
290 if( latency == 0 ) {
291 /* reset packet_bufX... */
292 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
294 /* ---------- Send ---------- */
295 render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
296 packet_bufX, net_period, dont_htonl_floats);
298 /* fill in packet hdr */
299 pkthdr->transport_state = jack_transport_query (client, &local_trans_pos);
300 pkthdr->transport_frame = local_trans_pos.frame;
301 pkthdr->framecnt = framecnt;
302 pkthdr->latency = latency;
303 pkthdr->reply_port = reply_port;
304 pkthdr->sample_rate = jack_get_sample_rate (client);
305 pkthdr->period_size = nframes;
307 /* playback for us is capture on the other side */
308 pkthdr->capture_channels_audio = playback_channels_audio;
309 pkthdr->playback_channels_audio = capture_channels_audio;
310 pkthdr->capture_channels_midi = playback_channels_midi;
311 pkthdr->playback_channels_midi = capture_channels_midi;
312 pkthdr->mtu = mtu;
313 if( freewheeling!= 0 )
314 pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
315 else
316 pkthdr->sync_state = (jack_nframes_t)deadline_goodness;
317 //printf("goodness=%d\n", deadline_goodness );
319 packet_header_hton (pkthdr);
320 if (cont_miss < 3*latency+5) {
321 int r;
322 for( r=0; r<redundancy; r++ )
323 netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
325 else if (cont_miss > 50+5*latency)
327 state_connected = 0;
328 packet_cache_reset_master_address( global_packcache );
329 //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
330 cont_miss = 0;
335 * ok... now the RECEIVE code.
339 /* reset packet_bufX... */
340 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
342 if( reply_port )
343 input_fd = insockfd;
344 else
345 input_fd = outsockfd;
347 // for latency == 0 we can poll.
348 if( (latency == 0) || (freewheeling!=0) ) {
349 jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client);
350 // Now loop until we get the right packet.
351 while(1) {
352 jack_nframes_t got_frame;
353 if ( ! netjack_poll_deadline( input_fd, deadline ) )
354 break;
356 packet_cache_drain_socket(global_packcache, input_fd);
358 if (packet_cache_get_next_available_framecnt( global_packcache, framecnt - latency, &got_frame ))
359 if( got_frame == (framecnt - latency) )
360 break;
362 } else {
363 // normally:
364 // only drain socket.
365 packet_cache_drain_socket(global_packcache, input_fd);
368 size = packet_cache_retreive_packet_pointer( global_packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp );
369 /* First alternative : we received what we expected. Render the data
370 * to the JACK ports so it can be played. */
371 if (size == rx_bufsize)
373 packet_buf = rx_packet_ptr;
374 pkthdr = (jacknet_packet_header *) packet_buf;
375 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
376 // calculate how much time there would have been, if this packet was sent at the deadline.
378 int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp);
379 packet_header_ntoh (pkthdr);
380 deadline_goodness = recv_time_offset - (int)pkthdr->latency;
381 //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset );
383 if (cont_miss)
385 //printf("Frame %d \tRecovered from dropouts\n", framecnt);
386 cont_miss = 0;
388 render_payload_to_jack_ports (bitdepth, packet_bufX, net_period,
389 capture_ports, capture_srcs, nframes, dont_htonl_floats);
391 state_currentframe = framecnt;
392 state_recv_packet_queue_time = recv_time_offset;
393 state_connected = 1;
394 sync_state = pkthdr->sync_state;
395 packet_cache_release_packet( global_packcache, framecnt - latency );
397 /* Second alternative : we've received something that's not
398 * as big as expected or we missed a packet. We render silence
399 * to the ouput ports */
400 else
402 jack_nframes_t latency_estimate;
403 if( packet_cache_find_latency( global_packcache, framecnt, &latency_estimate ) )
404 //if( (state_latency == 0) || (latency_estimate < state_latency) )
405 state_latency = latency_estimate;
407 // Set the counters up.
408 state_currentframe = framecnt;
409 //state_latency = framecnt - pkthdr->framecnt;
410 state_netxruns += 1;
412 //printf ("Frame %d \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size);
413 //printf ("Frame %d \tPacket missed or incomplete\n", framecnt);
414 cont_miss += 1;
415 chn = 0;
416 node = capture_ports;
417 while (node != NULL)
419 port = (jack_port_t *) node->data;
420 buf = jack_port_get_buffer (port, nframes);
421 porttype = jack_port_type (port);
422 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0)
423 for (i = 0; i < nframes; i++)
424 buf[i] = 0.0;
425 else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0)
426 jack_midi_clear_buffer (buf);
427 node = jack_slist_next (node);
428 chn++;
431 if( latency != 0 ) {
432 /* reset packet_bufX... */
433 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
435 /* ---------- Send ---------- */
436 render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
437 packet_bufX, net_period, dont_htonl_floats);
439 /* fill in packet hdr */
440 pkthdr->transport_state = jack_transport_query (client, &local_trans_pos);
441 pkthdr->transport_frame = local_trans_pos.frame;
442 pkthdr->framecnt = framecnt;
443 pkthdr->latency = latency;
444 pkthdr->reply_port = reply_port;
445 pkthdr->sample_rate = jack_get_sample_rate (client);
446 pkthdr->period_size = nframes;
448 /* playback for us is capture on the other side */
449 pkthdr->capture_channels_audio = playback_channels_audio;
450 pkthdr->playback_channels_audio = capture_channels_audio;
451 pkthdr->capture_channels_midi = playback_channels_midi;
452 pkthdr->playback_channels_midi = capture_channels_midi;
453 pkthdr->mtu = mtu;
454 if( freewheeling!= 0 )
455 pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
456 else
457 pkthdr->sync_state = (jack_nframes_t)deadline_goodness;
458 //printf("goodness=%d\n", deadline_goodness );
460 packet_header_hton (pkthdr);
461 if (cont_miss < 3*latency+5) {
462 int r;
463 for( r=0; r<redundancy; r++ )
464 netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
466 else if (cont_miss > 50+5*latency)
468 state_connected = 0;
469 packet_cache_reset_master_address( global_packcache );
470 //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
471 cont_miss = 0;
475 framecnt++;
476 return 0;
480 * This is the shutdown callback for this JACK application.
481 * It is called by JACK if the server ever shuts down or
482 * decides to disconnect the client.
485 void
486 jack_shutdown (void *arg)
488 exit (1);
491 void
492 init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port)
494 name->sin_family = AF_INET ;
495 name->sin_port = htons (port);
496 if (hostname)
498 struct hostent *hostinfo = gethostbyname (hostname);
499 if (hostinfo == NULL) {
500 fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
501 fflush( stderr );
503 #ifdef WIN32
504 name->sin_addr.s_addr = inet_addr( hostname );
505 #else
506 name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
507 #endif
509 else
510 name->sin_addr.s_addr = htonl (INADDR_ANY) ;
514 void
515 printUsage ()
517 fprintf (stderr, "usage: jack_netsource [options]\n"
518 "\n"
519 " -h this help text\n"
520 " -H <slave host> - Host name of the slave JACK\n"
521 " -o <num channels> - Number of audio playback channels\n"
522 " -i <num channels> - Number of audio capture channels\n"
523 " -O <num channels> - Number of midi playback channels\n"
524 " -I <num channels> - Number of midi capture channels\n"
525 " -n <periods> - Network latency in JACK periods\n"
526 " -p <port> - UDP port that the slave is listening on\n"
527 " -r <reply port> - UDP port that we are listening on\n"
528 " -B <bind port> - reply port, for use in NAT environments\n"
529 " -b <bitdepth> - Set transport to use 16bit or 8bit\n"
530 " -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n"
531 " -m <mtu> - Assume this mtu for the link\n"
532 " -R <N> - Redundancy: send out packets N times.\n"
533 " -e - skip host-to-network endianness conversion\n"
534 " -N <jack name> - Reports a different name to jack\n"
535 " -s <server name> - The name of the local jack server\n"
536 "\n");
539 void
540 sigterm_handler( int signal )
542 quit = 1;
546 main (int argc, char *argv[])
548 /* Some startup related basics */
549 char *client_name, *server_name = NULL, *peer_ip;
550 int peer_port = 3000;
551 jack_options_t options = JackNullOption;
552 jack_status_t status;
553 #ifdef WIN32
554 WSADATA wsa;
555 int rc = WSAStartup(MAKEWORD(2,0),&wsa);
556 #endif
557 /* Torben's famous state variables, aka "the reporting API" ! */
558 /* heh ? these are only the copies of them ;) */
559 int statecopy_connected, statecopy_latency, statecopy_netxruns;
560 jack_nframes_t net_period;
561 /* Argument parsing stuff */
562 extern char *optarg;
563 extern int optind, optopt;
564 int errflg=0, c;
566 if (argc < 3)
568 printUsage ();
569 return 1;
572 client_name = (char *) malloc (sizeof (char) * 10);
573 peer_ip = (char *) malloc (sizeof (char) * 10);
574 sprintf(client_name, "netjack");
575 sprintf(peer_ip, "localhost");
577 while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1)
579 switch (c)
581 case 'h':
582 printUsage();
583 exit (0);
584 break;
585 case 'H':
586 free(peer_ip);
587 peer_ip = (char *) malloc (sizeof (char) * strlen (optarg)+1);
588 strcpy (peer_ip, optarg);
589 break;
590 case 'o':
591 playback_channels_audio = atoi (optarg);
592 break;
593 case 'i':
594 capture_channels_audio = atoi (optarg);
595 break;
596 case 'O':
597 playback_channels_midi = atoi (optarg);
598 break;
599 case 'I':
600 capture_channels_midi = atoi (optarg);
601 break;
602 case 'n':
603 latency = atoi (optarg);
604 break;
605 case 'p':
606 peer_port = atoi (optarg);
607 break;
608 case 'r':
609 reply_port = atoi (optarg);
610 break;
611 case 'B':
612 bind_port = atoi (optarg);
613 break;
614 case 'f':
615 factor = atoi (optarg);
616 printf("This feature is deprecated and will be removed in future netjack versions. CELT offers a superiour way to conserve bandwidth");
617 break;
618 case 'b':
619 bitdepth = atoi (optarg);
620 break;
621 case 'c':
622 #if HAVE_CELT
623 bitdepth = 1000;
624 factor = atoi (optarg);
625 #else
626 printf( "not built with celt supprt\n" );
627 exit(10);
628 #endif
629 break;
630 case 'm':
631 mtu = atoi (optarg);
632 break;
633 case 'R':
634 redundancy = atoi (optarg);
635 break;
636 case 'e':
637 dont_htonl_floats = 1;
638 break;
639 case 'N':
640 free(client_name);
641 client_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
642 strcpy (client_name, optarg);
643 break;
644 case 's':
645 server_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
646 strcpy (server_name, optarg);
647 options |= JackServerName;
648 break;
649 case ':':
650 fprintf (stderr, "Option -%c requires an operand\n", optopt);
651 errflg++;
652 break;
653 case '?':
654 fprintf (stderr, "Unrecognized option: -%c\n", optopt);
655 errflg++;
658 if (errflg)
660 printUsage ();
661 exit (2);
664 capture_channels = capture_channels_audio + capture_channels_midi;
665 playback_channels = playback_channels_audio + playback_channels_midi;
667 outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
668 insockfd = socket (AF_INET, SOCK_DGRAM, 0);
670 if( (outsockfd == -1) || (insockfd == -1) ) {
671 fprintf (stderr, "cant open sockets\n" );
672 return 1;
675 init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
676 if(bind_port) {
677 init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port);
678 if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) {
679 fprintf (stderr, "bind failure\n" );
682 if(reply_port)
684 init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
685 if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) {
686 fprintf (stderr, "bind failure\n" );
690 /* try to become a client of the JACK server */
691 client = jack_client_open (client_name, options, &status, server_name);
692 if (client == NULL)
694 fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n"
695 "Is the JACK server running ?\n", status);
696 return 1;
699 /* Set up jack callbacks */
700 jack_set_process_callback (client, process, 0);
701 jack_set_sync_callback (client, sync_cb, 0);
702 jack_set_freewheel_callback (client, freewheel_cb, 0);
703 jack_on_shutdown (client, jack_shutdown, 0);
705 alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);
707 if( bitdepth == 1000 )
708 net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ;
709 else
710 net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor);
712 int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
713 global_packcache = packet_cache_new (latency + 50, rx_bufsize, mtu);
715 /* tell the JACK server that we are ready to roll */
716 if (jack_activate (client))
718 fprintf (stderr, "Cannot activate client");
719 return 1;
722 /* Now sleep forever... and evaluate the state_ vars */
724 signal( SIGTERM, sigterm_handler );
725 signal( SIGINT, sigterm_handler );
727 statecopy_connected = 2; // make it report unconnected on start.
728 statecopy_latency = state_latency;
729 statecopy_netxruns = state_netxruns;
731 while ( !quit )
733 #ifdef WIN32
734 Sleep (1000);
735 #else
736 sleep(1);
737 #endif
738 if (statecopy_connected != state_connected)
740 statecopy_connected = state_connected;
741 if (statecopy_connected)
743 state_netxruns = 1; // We want to reset the netxrun count on each new connection
744 printf ("Connected :-)\n");
746 else
747 printf ("Not Connected\n");
749 fflush(stdout);
752 if (statecopy_connected)
754 if (statecopy_netxruns != state_netxruns) {
755 statecopy_netxruns = state_netxruns;
756 printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n",
757 client_name,
758 state_currentframe,
759 statecopy_netxruns,
760 100*statecopy_netxruns/state_currentframe,
761 state_recv_packet_queue_time);
763 fflush(stdout);
766 else
768 if (statecopy_latency != state_latency)
770 statecopy_latency = state_latency;
771 if (statecopy_latency > 1)
772 printf ("current latency %d\n", statecopy_latency);
773 fflush(stdout);
778 jack_client_close (client);
779 packet_cache_free (global_packcache);
780 exit (0);