Use C++ isostream in JackEngineProfiling class.
[jack2.git] / example-clients / netsource.c
blobed4c1af0527efe4b8e0d33f81caebe6a05e4ab2a
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 #include <malloc.h>
40 #else
41 #include <netinet/in.h>
42 #include <netdb.h>
43 #include <sys/socket.h>
44 #endif
46 /* These two required by FreeBSD. */
47 #include <sys/types.h>
50 #include <jack/jack.h>
52 //#include <net_driver.h>
53 #include <netjack_packet.h>
54 #if HAVE_SAMPLERATE
55 #include <samplerate.h>
56 #endif
58 #if HAVE_CELT
59 #include <celt/celt.h>
60 #endif
62 #include <math.h>
64 JSList *capture_ports = NULL;
65 JSList *capture_srcs = NULL;
66 int capture_channels = 0;
67 int capture_channels_audio = 2;
68 int capture_channels_midi = 1;
69 JSList *playback_ports = NULL;
70 JSList *playback_srcs = NULL;
71 int playback_channels = 0;
72 int playback_channels_audio = 2;
73 int playback_channels_midi = 1;
74 int dont_htonl_floats = 0;
76 int latency = 5;
77 jack_nframes_t factor = 1;
78 int bitdepth = 0;
79 int mtu = 1400;
80 int reply_port = 0;
81 int bind_port = 0;
82 int redundancy = 1;
83 jack_client_t *client;
85 int state_connected = 0;
86 int state_latency = 0;
87 int state_netxruns = 0;
88 int state_currentframe = 0;
89 int state_recv_packet_queue_time = 0;
91 int quit=0;
94 int outsockfd;
95 int insockfd;
96 #ifdef WIN32
97 struct sockaddr_in destaddr;
98 struct sockaddr_in bindaddr;
99 #else
100 struct sockaddr destaddr;
101 struct sockaddr bindaddr;
102 #endif
104 int sync_state;
105 jack_transport_state_t last_transport_state;
107 int framecnt = 0;
109 int cont_miss = 0;
111 int freewheeling = 0;
114 * This Function allocates all the I/O Ports which are added the lists.
116 void
117 alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi)
120 int port_flags = JackPortIsOutput;
121 int chn;
122 jack_port_t *port;
123 char buf[32];
125 capture_ports = NULL;
126 /* Allocate audio capture channels */
127 for (chn = 0; chn < n_capture_audio; chn++)
129 snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
130 port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
131 if (!port)
133 printf( "jack_netsource: cannot register %s port\n", buf);
134 break;
136 if( bitdepth == 1000 ) {
137 #if HAVE_CELT
138 #if HAVE_CELT_API_0_7
139 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL );
140 capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) );
141 #else
142 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL );
143 capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
144 #endif
145 #endif
146 } else {
147 #if HAVE_SAMPLERATE
148 capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
149 #endif
151 capture_ports = jack_slist_append (capture_ports, port);
154 /* Allocate midi capture channels */
155 for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++)
157 snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
158 port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
159 if (!port)
161 printf ("jack_netsource: cannot register %s port\n", buf);
162 break;
164 capture_ports = jack_slist_append(capture_ports, port);
167 /* Allocate audio playback channels */
168 port_flags = JackPortIsInput;
169 playback_ports = NULL;
170 for (chn = 0; chn < n_playback_audio; chn++)
172 snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
173 port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
174 if (!port)
176 printf ("jack_netsource: cannot register %s port\n", buf);
177 break;
179 if( bitdepth == 1000 ) {
180 #if HAVE_CELT
181 #if HAVE_CELT_API_0_7
182 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL );
183 playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
184 #else
185 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL );
186 playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
187 #endif
188 #endif
189 } else {
190 #if HAVE_SAMPLERATE
191 playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
192 #endif
194 playback_ports = jack_slist_append (playback_ports, port);
197 /* Allocate midi playback channels */
198 for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++)
200 snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
201 port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
202 if (!port)
204 printf ("jack_netsource: cannot register %s port\n", buf);
205 break;
207 playback_ports = jack_slist_append (playback_ports, port);
212 * The Sync callback... sync state is set elsewhere...
213 * we will see if this is working correctly.
214 * i dont really believe in it yet.
217 sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
219 static int latency_count = 0;
220 int retval = sync_state;
222 if (latency_count) {
223 latency_count--;
224 retval = 0;
227 else if (state == JackTransportStarting && last_transport_state != JackTransportStarting)
229 retval = 0;
230 latency_count = latency - 1;
233 last_transport_state = state;
234 return retval;
237 void
238 freewheel_cb (int starting, void *arg)
240 freewheeling = starting;
243 int deadline_goodness=0;
245 * The process callback for this JACK application.
246 * It is called by JACK at the appropriate times.
249 process (jack_nframes_t nframes, void *arg)
251 jack_nframes_t net_period;
252 int rx_bufsize, tx_bufsize;
254 jack_default_audio_sample_t *buf;
255 jack_port_t *port;
256 JSList *node;
257 int chn;
258 int size, i;
259 const char *porttype;
260 int input_fd;
262 jack_position_t local_trans_pos;
264 uint32_t *packet_buf, *packet_bufX;
265 uint32_t *rx_packet_ptr;
266 jack_time_t packet_recv_timestamp;
268 if( bitdepth == 1000 )
269 net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ;
270 else
271 net_period = (float) nframes / (float) factor;
273 rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
274 tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header);
277 /* Allocate a buffer where both In and Out Buffer will fit */
278 packet_buf = alloca ((rx_bufsize > tx_bufsize) ? rx_bufsize : tx_bufsize);
280 jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf;
283 * for latency==0 we need to send out the packet before we wait on the reply.
284 * but this introduces a cycle of latency, when netsource is connected to itself.
285 * so we send out before read only in zero latency mode.
289 if( latency == 0 ) {
290 /* reset packet_bufX... */
291 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
293 /* ---------- Send ---------- */
294 render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
295 packet_bufX, net_period, dont_htonl_floats);
297 /* fill in packet hdr */
298 pkthdr->transport_state = jack_transport_query (client, &local_trans_pos);
299 pkthdr->transport_frame = local_trans_pos.frame;
300 pkthdr->framecnt = framecnt;
301 pkthdr->latency = latency;
302 pkthdr->reply_port = reply_port;
303 pkthdr->sample_rate = jack_get_sample_rate (client);
304 pkthdr->period_size = nframes;
306 /* playback for us is capture on the other side */
307 pkthdr->capture_channels_audio = playback_channels_audio;
308 pkthdr->playback_channels_audio = capture_channels_audio;
309 pkthdr->capture_channels_midi = playback_channels_midi;
310 pkthdr->playback_channels_midi = capture_channels_midi;
311 pkthdr->mtu = mtu;
312 if( freewheeling!= 0 )
313 pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
314 else
315 pkthdr->sync_state = (jack_nframes_t)deadline_goodness;
316 //printf("goodness=%d\n", deadline_goodness );
318 packet_header_hton (pkthdr);
319 if (cont_miss < 3*latency+5) {
320 int r;
321 for( r=0; r<redundancy; r++ )
322 netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
324 else if (cont_miss > 50+5*latency)
326 state_connected = 0;
327 packet_cache_reset_master_address( global_packcache );
328 //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
329 cont_miss = 0;
334 * ok... now the RECEIVE code.
338 /* reset packet_bufX... */
339 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
341 if( reply_port )
342 input_fd = insockfd;
343 else
344 input_fd = outsockfd;
346 // for latency == 0 we can poll.
347 if( (latency == 0) || (freewheeling!=0) ) {
348 jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client);
349 // Now loop until we get the right packet.
350 while(1) {
351 jack_nframes_t got_frame;
352 if ( ! netjack_poll_deadline( input_fd, deadline ) )
353 break;
355 packet_cache_drain_socket(global_packcache, input_fd);
357 if (packet_cache_get_next_available_framecnt( global_packcache, framecnt - latency, &got_frame ))
358 if( got_frame == (framecnt - latency) )
359 break;
361 } else {
362 // normally:
363 // only drain socket.
364 packet_cache_drain_socket(global_packcache, input_fd);
367 size = packet_cache_retreive_packet_pointer( global_packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp );
368 /* First alternative : we received what we expected. Render the data
369 * to the JACK ports so it can be played. */
370 if (size == rx_bufsize)
372 packet_buf = rx_packet_ptr;
373 pkthdr = (jacknet_packet_header *) packet_buf;
374 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
375 // calculate how much time there would have been, if this packet was sent at the deadline.
377 int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp);
378 packet_header_ntoh (pkthdr);
379 deadline_goodness = recv_time_offset - (int)pkthdr->latency;
380 //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset );
382 if (cont_miss)
384 //printf("Frame %d \tRecovered from dropouts\n", framecnt);
385 cont_miss = 0;
387 render_payload_to_jack_ports (bitdepth, packet_bufX, net_period,
388 capture_ports, capture_srcs, nframes, dont_htonl_floats);
390 state_currentframe = framecnt;
391 state_recv_packet_queue_time = recv_time_offset;
392 state_connected = 1;
393 sync_state = pkthdr->sync_state;
394 packet_cache_release_packet( global_packcache, framecnt - latency );
396 /* Second alternative : we've received something that's not
397 * as big as expected or we missed a packet. We render silence
398 * to the ouput ports */
399 else
401 jack_nframes_t latency_estimate;
402 if( packet_cache_find_latency( global_packcache, framecnt, &latency_estimate ) )
403 //if( (state_latency == 0) || (latency_estimate < state_latency) )
404 state_latency = latency_estimate;
406 // Set the counters up.
407 state_currentframe = framecnt;
408 //state_latency = framecnt - pkthdr->framecnt;
409 state_netxruns += 1;
411 //printf ("Frame %d \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size);
412 //printf ("Frame %d \tPacket missed or incomplete\n", framecnt);
413 cont_miss += 1;
414 chn = 0;
415 node = capture_ports;
416 while (node != NULL)
418 port = (jack_port_t *) node->data;
419 buf = jack_port_get_buffer (port, nframes);
420 porttype = jack_port_type (port);
421 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0)
422 for (i = 0; i < nframes; i++)
423 buf[i] = 0.0;
424 else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0)
425 jack_midi_clear_buffer (buf);
426 node = jack_slist_next (node);
427 chn++;
430 if( latency != 0 ) {
431 /* reset packet_bufX... */
432 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
434 /* ---------- Send ---------- */
435 render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
436 packet_bufX, net_period, dont_htonl_floats);
438 /* fill in packet hdr */
439 pkthdr->transport_state = jack_transport_query (client, &local_trans_pos);
440 pkthdr->transport_frame = local_trans_pos.frame;
441 pkthdr->framecnt = framecnt;
442 pkthdr->latency = latency;
443 pkthdr->reply_port = reply_port;
444 pkthdr->sample_rate = jack_get_sample_rate (client);
445 pkthdr->period_size = nframes;
447 /* playback for us is capture on the other side */
448 pkthdr->capture_channels_audio = playback_channels_audio;
449 pkthdr->playback_channels_audio = capture_channels_audio;
450 pkthdr->capture_channels_midi = playback_channels_midi;
451 pkthdr->playback_channels_midi = capture_channels_midi;
452 pkthdr->mtu = mtu;
453 if( freewheeling!= 0 )
454 pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
455 else
456 pkthdr->sync_state = (jack_nframes_t)deadline_goodness;
457 //printf("goodness=%d\n", deadline_goodness );
459 packet_header_hton (pkthdr);
460 if (cont_miss < 3*latency+5) {
461 int r;
462 for( r=0; r<redundancy; r++ )
463 netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
465 else if (cont_miss > 50+5*latency)
467 state_connected = 0;
468 packet_cache_reset_master_address( global_packcache );
469 //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
470 cont_miss = 0;
474 framecnt++;
475 return 0;
479 * This is the shutdown callback for this JACK application.
480 * It is called by JACK if the server ever shuts down or
481 * decides to disconnect the client.
484 void
485 jack_shutdown (void *arg)
487 exit (1);
490 void
491 init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port)
493 name->sin_family = AF_INET ;
494 name->sin_port = htons (port);
495 if (hostname)
497 struct hostent *hostinfo = gethostbyname (hostname);
498 if (hostinfo == NULL) {
499 fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
500 fflush( stderr );
502 #ifdef WIN32
503 name->sin_addr.s_addr = inet_addr( hostname );
504 #else
505 name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
506 #endif
508 else
509 name->sin_addr.s_addr = htonl (INADDR_ANY) ;
513 void
514 printUsage ()
516 fprintf (stderr, "usage: jack_netsource [options]\n"
517 "\n"
518 " -h this help text\n"
519 " -H <slave host> - Host name of the slave JACK\n"
520 " -o <num channels> - Number of audio playback channels\n"
521 " -i <num channels> - Number of audio capture channels\n"
522 " -O <num channels> - Number of midi playback channels\n"
523 " -I <num channels> - Number of midi capture channels\n"
524 " -n <periods> - Network latency in JACK periods\n"
525 " -p <port> - UDP port that the slave is listening on\n"
526 " -r <reply port> - UDP port that we are listening on\n"
527 " -B <bind port> - reply port, for use in NAT environments\n"
528 " -b <bitdepth> - Set transport to use 16bit or 8bit\n"
529 " -c <kbits> - Use CELT encoding with <kbits> kbits per channel\n"
530 " -m <mtu> - Assume this mtu for the link\n"
531 " -R <N> - Redundancy: send out packets N times.\n"
532 " -e - skip host-to-network endianness conversion\n"
533 " -N <jack name> - Reports a different name to jack\n"
534 " -s <server name> - The name of the local jack server\n"
535 "\n");
538 void
539 sigterm_handler( int signal )
541 quit = 1;
545 main (int argc, char *argv[])
547 /* Some startup related basics */
548 char *client_name, *server_name = NULL, *peer_ip;
549 int peer_port = 3000;
550 jack_options_t options = JackNullOption;
551 jack_status_t status;
552 #ifdef WIN32
553 WSADATA wsa;
554 int rc = WSAStartup(MAKEWORD(2,0),&wsa);
555 #endif
556 /* Torben's famous state variables, aka "the reporting API" ! */
557 /* heh ? these are only the copies of them ;) */
558 int statecopy_connected, statecopy_latency, statecopy_netxruns;
559 jack_nframes_t net_period;
560 /* Argument parsing stuff */
561 extern char *optarg;
562 extern int optind, optopt;
563 int errflg=0, c;
565 if (argc < 3)
567 printUsage ();
568 return 1;
571 client_name = (char *) malloc (sizeof (char) * 10);
572 peer_ip = (char *) malloc (sizeof (char) * 10);
573 sprintf(client_name, "netjack");
574 sprintf(peer_ip, "localhost");
576 while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1)
578 switch (c)
580 case 'h':
581 printUsage();
582 exit (0);
583 break;
584 case 'H':
585 free(peer_ip);
586 peer_ip = (char *) malloc (sizeof (char) * strlen (optarg)+1);
587 strcpy (peer_ip, optarg);
588 break;
589 case 'o':
590 playback_channels_audio = atoi (optarg);
591 break;
592 case 'i':
593 capture_channels_audio = atoi (optarg);
594 break;
595 case 'O':
596 playback_channels_midi = atoi (optarg);
597 break;
598 case 'I':
599 capture_channels_midi = atoi (optarg);
600 break;
601 case 'n':
602 latency = atoi (optarg);
603 break;
604 case 'p':
605 peer_port = atoi (optarg);
606 break;
607 case 'r':
608 reply_port = atoi (optarg);
609 break;
610 case 'B':
611 bind_port = atoi (optarg);
612 break;
613 case 'f':
614 factor = atoi (optarg);
615 printf("This feature is deprecated and will be removed in future netjack versions. CELT offers a superiour way to conserve bandwidth");
616 break;
617 case 'b':
618 bitdepth = atoi (optarg);
619 break;
620 case 'c':
621 #if HAVE_CELT
622 bitdepth = 1000;
623 factor = atoi (optarg);
624 #else
625 printf( "not built with celt supprt\n" );
626 exit(10);
627 #endif
628 break;
629 case 'm':
630 mtu = atoi (optarg);
631 break;
632 case 'R':
633 redundancy = atoi (optarg);
634 break;
635 case 'e':
636 dont_htonl_floats = 1;
637 break;
638 case 'N':
639 free(client_name);
640 client_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
641 strcpy (client_name, optarg);
642 break;
643 case 's':
644 server_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
645 strcpy (server_name, optarg);
646 options |= JackServerName;
647 break;
648 case ':':
649 fprintf (stderr, "Option -%c requires an operand\n", optopt);
650 errflg++;
651 break;
652 case '?':
653 fprintf (stderr, "Unrecognized option: -%c\n", optopt);
654 errflg++;
657 if (errflg)
659 printUsage ();
660 exit (2);
663 capture_channels = capture_channels_audio + capture_channels_midi;
664 playback_channels = playback_channels_audio + playback_channels_midi;
666 outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
667 insockfd = socket (AF_INET, SOCK_DGRAM, 0);
669 if( (outsockfd == -1) || (insockfd == -1) ) {
670 fprintf (stderr, "cant open sockets\n" );
671 return 1;
674 init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
675 if(bind_port) {
676 init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port);
677 if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) {
678 fprintf (stderr, "bind failure\n" );
681 if(reply_port)
683 init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
684 if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) {
685 fprintf (stderr, "bind failure\n" );
689 /* try to become a client of the JACK server */
690 client = jack_client_open (client_name, options, &status, server_name);
691 if (client == NULL)
693 fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n"
694 "Is the JACK server running ?\n", status);
695 return 1;
698 /* Set up jack callbacks */
699 jack_set_process_callback (client, process, 0);
700 jack_set_sync_callback (client, sync_cb, 0);
701 jack_set_freewheel_callback (client, freewheel_cb, 0);
702 jack_on_shutdown (client, jack_shutdown, 0);
704 alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);
706 if( bitdepth == 1000 )
707 net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ;
708 else
709 net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor);
711 int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
712 global_packcache = packet_cache_new (latency + 50, rx_bufsize, mtu);
714 /* tell the JACK server that we are ready to roll */
715 if (jack_activate (client))
717 fprintf (stderr, "Cannot activate client");
718 return 1;
721 /* Now sleep forever... and evaluate the state_ vars */
723 signal( SIGTERM, sigterm_handler );
724 signal( SIGINT, sigterm_handler );
726 statecopy_connected = 2; // make it report unconnected on start.
727 statecopy_latency = state_latency;
728 statecopy_netxruns = state_netxruns;
730 while ( !quit )
732 #ifdef WIN32
733 Sleep (1000);
734 #else
735 sleep(1);
736 #endif
737 if (statecopy_connected != state_connected)
739 statecopy_connected = state_connected;
740 if (statecopy_connected)
742 state_netxruns = 1; // We want to reset the netxrun count on each new connection
743 printf ("Connected :-)\n");
745 else
746 printf ("Not Connected\n");
748 fflush(stdout);
751 if (statecopy_connected)
753 if (statecopy_netxruns != state_netxruns) {
754 statecopy_netxruns = state_netxruns;
755 printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n",
756 client_name,
757 state_currentframe,
758 statecopy_netxruns,
759 100*statecopy_netxruns/state_currentframe,
760 state_recv_packet_queue_time);
762 fflush(stdout);
765 else
767 if (statecopy_latency != state_latency)
769 statecopy_latency = state_latency;
770 if (statecopy_latency > 1)
771 printf ("current latency %d\n", statecopy_latency);
772 fflush(stdout);
777 jack_client_close (client);
778 packet_cache_free (global_packcache);
779 exit (0);