Lock/Unlock shared memory segments (to test...).
[jack2.git] / example-clients / netsource.c
blobf79ac8da6369d95618633903e83173e4865a854d
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>
36 #ifdef WIN32
37 #include <winsock2.h>
38 #include <malloc.h>
39 #else
40 #include <netinet/in.h>
41 #include <netdb.h>
42 #include <sys/socket.h>
43 #endif
45 /* These two required by FreeBSD. */
46 #include <sys/types.h>
48 #if HAVE_ALLOCA_H
49 #include <alloca.h>
50 #endif
52 #include <jack/jack.h>
54 //#include <net_driver.h>
55 #include <netjack_packet.h>
56 #if HAVE_SAMPLERATE
57 #include <samplerate.h>
58 #endif
60 #if HAVE_CELT
61 #include <celt/celt.h>
62 #endif
64 #include <math.h>
66 JSList *capture_ports = NULL;
67 JSList *capture_srcs = NULL;
68 int capture_channels = 0;
69 int capture_channels_audio = 2;
70 int capture_channels_midi = 1;
71 JSList *playback_ports = NULL;
72 JSList *playback_srcs = NULL;
73 int playback_channels = 0;
74 int playback_channels_audio = 2;
75 int playback_channels_midi = 1;
76 int dont_htonl_floats = 0;
78 int latency = 5;
79 jack_nframes_t factor = 1;
80 int bitdepth = 0;
81 int mtu = 1400;
82 int reply_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;
93 int outsockfd;
94 int insockfd;
95 #ifdef WIN32
96 struct sockaddr_in destaddr;
97 struct sockaddr_in bindaddr;
98 #else
99 struct sockaddr destaddr;
100 struct sockaddr bindaddr;
101 #endif
103 int sync_state;
104 jack_transport_state_t last_transport_state;
106 int framecnt = 0;
108 int cont_miss = 0;
110 int freewheeling = 0;
113 * This Function allocates all the I/O Ports which are added the lists.
115 void
116 alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi)
119 int port_flags = JackPortIsOutput;
120 int chn;
121 jack_port_t *port;
122 char buf[32];
124 capture_ports = NULL;
125 /* Allocate audio capture channels */
126 for (chn = 0; chn < n_capture_audio; chn++)
128 snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
129 port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
130 if (!port)
132 printf( "jack_netsource: cannot register %s port\n", buf);
133 break;
135 if( bitdepth == 1000 ) {
136 #if HAVE_CELT
137 #if HAVE_CELT_API_0_7
138 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL );
139 capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) );
140 #else
141 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL );
142 capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
143 #endif
144 #endif
145 } else {
146 #if HAVE_SAMPLERATE
147 capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
148 #endif
150 capture_ports = jack_slist_append (capture_ports, port);
153 /* Allocate midi capture channels */
154 for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++)
156 snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
157 port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
158 if (!port)
160 printf ("jack_netsource: cannot register %s port\n", buf);
161 break;
163 capture_ports = jack_slist_append(capture_ports, port);
166 /* Allocate audio playback channels */
167 port_flags = JackPortIsInput;
168 playback_ports = NULL;
169 for (chn = 0; chn < n_playback_audio; chn++)
171 snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
172 port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
173 if (!port)
175 printf ("jack_netsource: cannot register %s port\n", buf);
176 break;
178 if( bitdepth == 1000 ) {
179 #if HAVE_CELT
180 #if HAVE_CELT_API_0_7
181 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL );
182 playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
183 #else
184 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL );
185 playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
186 #endif
187 #endif
188 } else {
189 #if HAVE_SAMPLERATE
190 playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
191 #endif
193 playback_ports = jack_slist_append (playback_ports, port);
196 /* Allocate midi playback channels */
197 for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++)
199 snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
200 port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
201 if (!port)
203 printf ("jack_netsource: cannot register %s port\n", buf);
204 break;
206 playback_ports = jack_slist_append (playback_ports, port);
211 * The Sync callback... sync state is set elsewhere...
212 * we will see if this is working correctly.
213 * i dont really believe in it yet.
216 sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
218 static int latency_count = 0;
219 int retval = sync_state;
221 if (latency_count) {
222 latency_count--;
223 retval = 0;
226 else if (state == JackTransportStarting && last_transport_state != JackTransportStarting)
228 retval = 0;
229 latency_count = latency - 1;
232 last_transport_state = state;
233 return retval;
236 void
237 freewheel_cb (int starting, void *arg)
239 freewheeling = starting;
242 int deadline_goodness=0;
244 * The process callback for this JACK application.
245 * It is called by JACK at the appropriate times.
248 process (jack_nframes_t nframes, void *arg)
250 jack_nframes_t net_period;
251 int rx_bufsize, tx_bufsize;
253 jack_default_audio_sample_t *buf;
254 jack_port_t *port;
255 JSList *node;
256 int chn;
257 int size, i;
258 const char *porttype;
259 int input_fd;
261 jack_position_t local_trans_pos;
263 uint32_t *packet_buf, *packet_bufX;
264 uint32_t *rx_packet_ptr;
265 jack_time_t packet_recv_timestamp;
267 if( bitdepth == 1000 )
268 net_period = factor;
269 else
270 net_period = (float) nframes / (float) factor;
272 rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
273 tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header);
276 /* Allocate a buffer where both In and Out Buffer will fit */
277 packet_buf = alloca ((rx_bufsize > tx_bufsize) ? rx_bufsize : tx_bufsize);
279 jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf;
282 * for latency==0 we need to send out the packet before we wait on the reply.
283 * but this introduces a cycle of latency, when netsource is connected to itself.
284 * so we send out before read only in zero latency mode.
288 if( latency == 0 ) {
289 /* reset packet_bufX... */
290 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
292 /* ---------- Send ---------- */
293 render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
294 packet_bufX, net_period, dont_htonl_floats);
296 /* fill in packet hdr */
297 pkthdr->transport_state = jack_transport_query (client, &local_trans_pos);
298 pkthdr->transport_frame = local_trans_pos.frame;
299 pkthdr->framecnt = framecnt;
300 pkthdr->latency = latency;
301 pkthdr->reply_port = reply_port;
302 pkthdr->sample_rate = jack_get_sample_rate (client);
303 pkthdr->period_size = nframes;
305 /* playback for us is capture on the other side */
306 pkthdr->capture_channels_audio = playback_channels_audio;
307 pkthdr->playback_channels_audio = capture_channels_audio;
308 pkthdr->capture_channels_midi = playback_channels_midi;
309 pkthdr->playback_channels_midi = capture_channels_midi;
310 pkthdr->mtu = mtu;
311 if( freewheeling!= 0 )
312 pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
313 else
314 pkthdr->sync_state = (jack_nframes_t)deadline_goodness;
315 //printf("goodness=%d\n", deadline_goodness );
317 packet_header_hton (pkthdr);
318 if (cont_miss < 3*latency+5) {
319 int r;
320 for( r=0; r<redundancy; r++ )
321 netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
323 else if (cont_miss > 50+5*latency)
325 state_connected = 0;
326 packet_cache_reset_master_address( global_packcache );
327 //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
328 cont_miss = 0;
333 * ok... now the RECEIVE code.
337 /* reset packet_bufX... */
338 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
340 if( reply_port )
341 input_fd = insockfd;
342 else
343 input_fd = outsockfd;
345 // for latency == 0 we can poll.
346 if( (latency == 0) || (freewheeling!=0) ) {
347 jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client);
348 // Now loop until we get the right packet.
349 while(1) {
350 jack_nframes_t got_frame;
351 if ( ! netjack_poll_deadline( input_fd, deadline ) )
352 break;
354 packet_cache_drain_socket(global_packcache, input_fd);
356 if (packet_cache_get_next_available_framecnt( global_packcache, framecnt - latency, &got_frame ))
357 if( got_frame == (framecnt - latency) )
358 break;
360 } else {
361 // normally:
362 // only drain socket.
363 packet_cache_drain_socket(global_packcache, input_fd);
366 size = packet_cache_retreive_packet_pointer( global_packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp );
367 /* First alternative : we received what we expected. Render the data
368 * to the JACK ports so it can be played. */
369 if (size == rx_bufsize)
371 packet_buf = rx_packet_ptr;
372 pkthdr = (jacknet_packet_header *) packet_buf;
373 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
374 // calculate how much time there would have been, if this packet was sent at the deadline.
376 int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp);
377 packet_header_ntoh (pkthdr);
378 deadline_goodness = recv_time_offset - (int)pkthdr->latency;
379 //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset );
381 if (cont_miss)
383 //printf("Frame %d \tRecovered from dropouts\n", framecnt);
384 cont_miss = 0;
386 render_payload_to_jack_ports (bitdepth, packet_bufX, net_period,
387 capture_ports, capture_srcs, nframes, dont_htonl_floats);
389 state_currentframe = framecnt;
390 state_recv_packet_queue_time = recv_time_offset;
391 state_connected = 1;
392 sync_state = pkthdr->sync_state;
393 packet_cache_release_packet( global_packcache, framecnt - latency );
395 /* Second alternative : we've received something that's not
396 * as big as expected or we missed a packet. We render silence
397 * to the ouput ports */
398 else
400 jack_nframes_t latency_estimate;
401 if( packet_cache_find_latency( global_packcache, framecnt, &latency_estimate ) )
402 //if( (state_latency == 0) || (latency_estimate < state_latency) )
403 state_latency = latency_estimate;
405 // Set the counters up.
406 state_currentframe = framecnt;
407 //state_latency = framecnt - pkthdr->framecnt;
408 state_netxruns += 1;
410 //printf ("Frame %d \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size);
411 //printf ("Frame %d \tPacket missed or incomplete\n", framecnt);
412 cont_miss += 1;
413 chn = 0;
414 node = capture_ports;
415 while (node != NULL)
417 port = (jack_port_t *) node->data;
418 buf = jack_port_get_buffer (port, nframes);
419 porttype = jack_port_type (port);
420 if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0)
421 for (i = 0; i < nframes; i++)
422 buf[i] = 0.0;
423 else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0)
424 jack_midi_clear_buffer (buf);
425 node = jack_slist_next (node);
426 chn++;
429 if( latency != 0 ) {
430 /* reset packet_bufX... */
431 packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
433 /* ---------- Send ---------- */
434 render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
435 packet_bufX, net_period, dont_htonl_floats);
437 /* fill in packet hdr */
438 pkthdr->transport_state = jack_transport_query (client, &local_trans_pos);
439 pkthdr->transport_frame = local_trans_pos.frame;
440 pkthdr->framecnt = framecnt;
441 pkthdr->latency = latency;
442 pkthdr->reply_port = reply_port;
443 pkthdr->sample_rate = jack_get_sample_rate (client);
444 pkthdr->period_size = nframes;
446 /* playback for us is capture on the other side */
447 pkthdr->capture_channels_audio = playback_channels_audio;
448 pkthdr->playback_channels_audio = capture_channels_audio;
449 pkthdr->capture_channels_midi = playback_channels_midi;
450 pkthdr->playback_channels_midi = capture_channels_midi;
451 pkthdr->mtu = mtu;
452 if( freewheeling!= 0 )
453 pkthdr->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
454 else
455 pkthdr->sync_state = (jack_nframes_t)deadline_goodness;
456 //printf("goodness=%d\n", deadline_goodness );
458 packet_header_hton (pkthdr);
459 if (cont_miss < 3*latency+5) {
460 int r;
461 for( r=0; r<redundancy; r++ )
462 netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
464 else if (cont_miss > 50+5*latency)
466 state_connected = 0;
467 packet_cache_reset_master_address( global_packcache );
468 //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
469 cont_miss = 0;
473 framecnt++;
474 return 0;
478 * This is the shutdown callback for this JACK application.
479 * It is called by JACK if the server ever shuts down or
480 * decides to disconnect the client.
483 void
484 jack_shutdown (void *arg)
486 exit (1);
489 void
490 init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port)
492 printf( "still here... \n" );
493 fflush( stdout );
495 name->sin_family = AF_INET ;
496 name->sin_port = htons (port);
497 if (hostname)
499 struct hostent *hostinfo = gethostbyname (hostname);
500 if (hostinfo == NULL) {
501 fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
502 fflush( stderr );
504 #ifdef WIN32
505 name->sin_addr.s_addr = inet_addr( hostname );
506 #else
507 name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
508 #endif
510 else
511 name->sin_addr.s_addr = htonl (INADDR_ANY) ;
515 void
516 printUsage ()
518 fprintf (stderr, "usage: jack_netsource -h <host peer> [options]\n"
519 "\n"
520 " -n <jack name> - Reports a different name to jack\n"
521 " -s <server name> - The name of the local jack server\n"
522 " -h <host_peer> - Host name of the slave JACK\n"
523 " -p <port> - UDP port used by the slave JACK\n"
524 " -P <num channels> - Number of audio playback channels\n"
525 " -C <num channels> - Number of audio capture channels\n"
526 " -o <num channels> - Number of midi playback channels\n"
527 " -i <num channels> - Number of midi capture channels\n"
528 " -l <latency> - Network latency in number of NetJack frames\n"
529 " -r <reply port> - Local UDP port to use\n"
530 " -f <downsample ratio> - Downsample data in the wire by this factor\n"
531 " -b <bitdepth> - Set transport to use 16bit or 8bit\n"
532 " -m <mtu> - Assume this mtu for the link\n"
533 " -c <bytes> - Use Celt and encode <bytes> per channel and packet.\n"
534 " -R <N> - Send out packets N times.\n"
535 "\n");
539 main (int argc, char *argv[])
541 /* Some startup related basics */
542 char *client_name, *server_name = NULL, *peer_ip;
543 int peer_port = 3000;
544 jack_options_t options = JackNullOption;
545 jack_status_t status;
546 #ifdef WIN32
547 WSADATA wsa;
548 int rc = WSAStartup(MAKEWORD(2,0),&wsa);
549 #endif
550 /* Torben's famous state variables, aka "the reporting API" ! */
551 /* heh ? these are only the copies of them ;) */
552 int statecopy_connected, statecopy_latency, statecopy_netxruns;
553 jack_nframes_t net_period;
554 /* Argument parsing stuff */
555 extern char *optarg;
556 extern int optind, optopt;
557 int errflg=0, c;
559 if (argc < 3)
561 printUsage ();
562 return 1;
565 client_name = (char *) malloc (sizeof (char) * 10);
566 peer_ip = (char *) malloc (sizeof (char) * 10);
567 sprintf(client_name, "netsource");
568 sprintf(peer_ip, "localhost");
570 while ((c = getopt (argc, argv, ":H:R:n:s:h:p:C:P:i:o:l:r:f:b:m:c:")) != -1)
572 switch (c)
574 case 'n':
575 free(client_name);
576 client_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
577 strcpy (client_name, optarg);
578 break;
579 case 's':
580 server_name = (char *) malloc (sizeof (char) * strlen (optarg)+1);
581 strcpy (server_name, optarg);
582 options |= JackServerName;
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 'p':
590 peer_port = atoi (optarg);
591 break;
592 case 'P':
593 playback_channels_audio = atoi (optarg);
594 break;
595 case 'C':
596 capture_channels_audio = atoi (optarg);
597 break;
598 case 'o':
599 playback_channels_midi = atoi (optarg);
600 break;
601 case 'i':
602 capture_channels_midi = atoi (optarg);
603 break;
604 case 'l':
605 latency = atoi (optarg);
606 break;
607 case 'r':
608 reply_port = atoi (optarg);
609 break;
610 case 'f':
611 factor = atoi (optarg);
612 break;
613 case 'b':
614 bitdepth = atoi (optarg);
615 break;
616 case 'c':
617 #if HAVE_CELT
618 bitdepth = 1000;
619 factor = atoi (optarg);
620 #else
621 printf( "not built with celt supprt\n" );
622 exit(10);
623 #endif
624 break;
625 case 'm':
626 mtu = atoi (optarg);
627 break;
628 case 'R':
629 redundancy = atoi (optarg);
630 break;
631 case 'H':
632 dont_htonl_floats = atoi (optarg);
633 break;
634 case ':':
635 fprintf (stderr, "Option -%c requires an operand\n", optopt);
636 errflg++;
637 break;
638 case '?':
639 fprintf (stderr, "Unrecognized option: -%c\n", optopt);
640 errflg++;
643 if (errflg)
645 printUsage ();
646 exit (2);
649 capture_channels = capture_channels_audio + capture_channels_midi;
650 playback_channels = playback_channels_audio + playback_channels_midi;
652 outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
653 insockfd = socket (AF_INET, SOCK_DGRAM, 0);
655 if( (outsockfd == -1) || (insockfd == -1) ) {
656 fprintf (stderr, "cant open sockets\n" );
657 return 1;
660 init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
661 if(reply_port)
663 init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
664 if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) {
665 fprintf (stderr, "bind failure\n" );
669 /* try to become a client of the JACK server */
670 client = jack_client_open (client_name, options, &status, server_name);
671 if (client == NULL)
673 fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n"
674 "Is the JACK server running ?\n", status);
675 return 1;
678 /* Set up jack callbacks */
679 jack_set_process_callback (client, process, 0);
680 jack_set_sync_callback (client, sync_cb, 0);
681 jack_set_freewheel_callback (client, freewheel_cb, 0);
682 jack_on_shutdown (client, jack_shutdown, 0);
684 alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);
686 if( bitdepth == 1000 )
687 net_period = factor;
688 else
689 net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor);
691 int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
692 global_packcache = packet_cache_new (latency + 50, rx_bufsize, mtu);
694 /* tell the JACK server that we are ready to roll */
695 if (jack_activate (client))
697 fprintf (stderr, "Cannot activate client");
698 return 1;
701 /* Now sleep forever... and evaluate the state_ vars */
703 statecopy_connected = 2; // make it report unconnected on start.
704 statecopy_latency = state_latency;
705 statecopy_netxruns = state_netxruns;
707 while (1)
709 #ifdef WIN32
710 Sleep (1000);
711 #else
712 sleep(1);
713 #endif
714 if (statecopy_connected != state_connected)
716 statecopy_connected = state_connected;
717 if (statecopy_connected)
719 state_netxruns = 1; // We want to reset the netxrun count on each new connection
720 printf ("Connected :-)\n");
722 else
723 printf ("Not Connected\n");
725 fflush(stdout);
728 if (statecopy_connected)
730 if (statecopy_netxruns != state_netxruns) {
731 statecopy_netxruns = state_netxruns;
732 printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n",
733 client_name,
734 state_currentframe,
735 statecopy_netxruns,
736 100*statecopy_netxruns/state_currentframe,
737 state_recv_packet_queue_time);
739 fflush(stdout);
742 else
744 if (statecopy_latency != state_latency)
746 statecopy_latency = state_latency;
747 if (statecopy_latency > 1)
748 printf ("current latency %d\n", statecopy_latency);
749 fflush(stdout);
754 /* Never reached. Well we will be a GtkApp someday... */
755 packet_cache_free (global_packcache);
756 jack_client_close (client);
757 exit (0);