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.
26
* @brief This client connects a remote slave JACK to a local JACK server assumed to be the master
37
#include <netinet/in.h>
40
/* These two required by FreeBSD. */
41
#include <sys/types.h>
42
#include <sys/socket.h>
48
#include <jack/jack.h>
50
#include <net_driver.h>
51
#include <netjack_packet.h>
52
#include <samplerate.h>
55
#include <celt/celt.h>
58
JSList *capture_ports = NULL;
59
JSList *capture_srcs = NULL;
60
int capture_channels = 0;
61
int capture_channels_audio = 2;
62
int capture_channels_midi = 1;
63
JSList *playback_ports = NULL;
64
JSList *playback_srcs = NULL;
65
int playback_channels = 0;
66
int playback_channels_audio = 2;
67
int playback_channels_midi = 1;
70
jack_nframes_t factor = 1;
74
jack_client_t *client;
76
int state_connected = 0;
77
int state_latency = 0;
78
int state_netxruns = 0;
79
int state_currentframe = 0;
84
struct sockaddr destaddr;
85
struct sockaddr bindaddr;
88
jack_transport_state_t last_transport_state;
95
* This Function allocates all the I/O Ports which are added the lists.
98
alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi)
101
int port_flags = JackPortIsOutput;
106
capture_ports = NULL;
107
/* Allocate audio capture channels */
108
for (chn = 0; chn < n_capture_audio; chn++)
110
snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
111
port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
114
printf( "jack_netsource: cannot register %s port\n", buf);
117
if( bitdepth == 1000 ) {
120
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL );
121
capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
124
capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
126
capture_ports = jack_slist_append (capture_ports, port);
129
/* Allocate midi capture channels */
130
for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++)
132
snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
133
port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
136
printf ("jack_netsource: cannot register %s port\n", buf);
139
capture_ports = jack_slist_append(capture_ports, port);
142
/* Allocate audio playback channels */
143
port_flags = JackPortIsInput;
144
playback_ports = NULL;
145
for (chn = 0; chn < n_playback_audio; chn++)
147
snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
148
port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
151
printf ("jack_netsource: cannot register %s port\n", buf);
154
if( bitdepth == 1000 ) {
157
CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL );
158
playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
161
playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
163
playback_ports = jack_slist_append (playback_ports, port);
166
/* Allocate midi playback channels */
167
for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++)
169
snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
170
port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
173
printf ("jack_netsource: cannot register %s port\n", buf);
176
playback_ports = jack_slist_append (playback_ports, port);
181
* The Sync callback... sync state is set elsewhere...
182
* we will see if this is working correctly.
183
* i dont really believe in it yet.
186
sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg)
188
static int latency_count = 0;
189
int retval = sync_state;
196
else if (state == JackTransportStarting && last_transport_state != JackTransportStarting)
199
latency_count = latency - 1;
202
last_transport_state = state;
207
* The process callback for this JACK application.
208
* It is called by JACK at the appropriate times.
211
process (jack_nframes_t nframes, void *arg)
213
jack_nframes_t net_period;
215
if( bitdepth == 1000 )
218
net_period = (float) nframes / (float) factor;
220
int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
221
int tx_bufsize = get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header);
223
jack_default_audio_sample_t *buf;
228
const char *porttype;
230
jack_position_t local_trans_pos;
232
uint32_t *packet_buf, *packet_bufX;
234
/* Allocate a buffer where both In and Out Buffer will fit */
235
packet_buf = alloca ((rx_bufsize > tx_bufsize) ? rx_bufsize : tx_bufsize);
237
jacknet_packet_header *pkthdr = (jacknet_packet_header *) packet_buf;
239
packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (uint32_t);
243
packet_cache_drain_socket(global_packcache, insockfd);
245
packet_cache_drain_socket(global_packcache, outsockfd);
247
size = packet_cache_retreive_packet( global_packcache, framecnt - latency, (char *)packet_buf, rx_bufsize );
249
/* First alternative : we received what we expected. Render the data
250
* to the JACK ports so it can be played. */
251
if (size == rx_bufsize)
255
//printf("Frame %d \tRecovered from dropouts\n", framecnt);
258
render_payload_to_jack_ports (bitdepth, packet_bufX, net_period, capture_ports, capture_srcs, nframes);
260
/* Now evaluate packet header */
261
//if (sync_state != pkthdr->sync_state)
262
// printf ("Frame %d \tSync has been set\n", framecnt);
264
state_currentframe = framecnt;
265
//state_latency = framecnt - pkthdr->framecnt;
267
sync_state = pkthdr->sync_state;
269
/* Second alternative : we've received something that's not
270
* as big as expected or we missed a packet. We render silence
271
* to the ouput ports */
274
jack_nframes_t latency_estimate;
275
if( packet_cache_find_latency( global_packcache, framecnt, &latency_estimate ) )
276
state_latency = latency_estimate;
278
// Set the counters up.
279
state_currentframe = framecnt;
280
//state_latency = framecnt - pkthdr->framecnt;
283
//printf ("Frame %d \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size);
284
//printf ("Frame %d \tPacket missed or incomplete\n", framecnt);
287
node = capture_ports;
290
port = (jack_port_t *) node->data;
291
buf = jack_port_get_buffer (port, nframes);
292
porttype = jack_port_type (port);
293
if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0)
294
for (i = 0; i < nframes; i++)
296
else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0)
297
jack_midi_clear_buffer (buf);
298
node = jack_slist_next (node);
302
/* reset packet_bufX... */
303
packet_bufX = packet_buf + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
305
/* ---------- Send ---------- */
306
render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, packet_bufX, net_period);
308
/* fill in packet hdr */
309
pkthdr->transport_state = jack_transport_query (client, &local_trans_pos);
310
pkthdr->transport_frame = local_trans_pos.frame;
311
pkthdr->framecnt = framecnt;
312
pkthdr->latency = latency;
313
pkthdr->reply_port = reply_port;
314
pkthdr->sample_rate = jack_get_sample_rate (client);
315
pkthdr->period_size = nframes;
317
/* playback for us is capture on the other side */
318
pkthdr->capture_channels_audio = playback_channels_audio;
319
pkthdr->playback_channels_audio = capture_channels_audio;
320
pkthdr->capture_channels_midi = playback_channels_midi;
321
pkthdr->playback_channels_midi = capture_channels_midi;
324
packet_header_hton (pkthdr);
325
if (cont_miss < 2*latency+5)
326
netjack_sendto (outsockfd, (char *) packet_buf, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
327
// else if (cont_miss >= 10 && cont_miss <= 50)
328
// printf ("Frame %d \tToo many packets missed (%d). We have stopped sending data\n", framecnt, cont_miss);
329
else if (cont_miss > 50+5*latency)
332
//printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
341
* This is the shutdown callback for this JACK application.
342
* It is called by JACK if the server ever shuts down or
343
* decides to disconnect the client.
347
jack_shutdown (void *arg)
353
init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t port)
355
name->sin_family = AF_INET ;
356
name->sin_port = htons (port);
359
struct hostent *hostinfo = gethostbyname (hostname);
360
if (hostinfo == NULL)
361
fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname);
362
name->sin_addr = *(struct in_addr *) hostinfo->h_addr ;
365
name->sin_addr.s_addr = htonl (INADDR_ANY) ;
371
fprintf (stderr, "usage: jack_netsource -h <host peer> [options]\n"
373
" -n <jack name> - Reports a different name to jack\n"
374
" -s <server name> - The name of the local jack server\n"
375
" -h <host_peer> - Host name of the slave JACK\n"
376
" -p <port> - UDP port used by the slave JACK\n"
377
" -P <num channels> - Number of audio playback channels\n"
378
" -C <num channels> - Number of audio capture channels\n"
379
" -o <num channels> - Number of midi playback channels\n"
380
" -i <num channels> - Number of midi capture channels\n"
381
" -l <latency> - Network latency in number of NetJack frames\n"
382
" -r <reply port> - Local UDP port to use\n"
383
" -f <downsample ratio> - Downsample data in the wire by this factor\n"
384
" -b <bitdepth> - Set transport to use 16bit or 8bit\n"
385
" -m <mtu> - Assume this mtu for the link\n"
386
" -c <bytes> - Use Celt and encode <bytes> per channel and packet.\n"
391
main (int argc, char *argv[])
393
/* Some startup related basics */
394
char *client_name, *server_name = NULL, *peer_ip;
395
int peer_port = 3000;
396
jack_options_t options = JackNullOption;
397
jack_status_t status;
399
/* Torben's famous state variables, aka "the reporting API" ! */
400
int statecopy_connected, statecopy_latency, statecopy_netxruns;
402
/* Argument parsing stuff */
404
extern int optind, optopt;
413
client_name = (char *) malloc (sizeof (char) * 9);
414
peer_ip = (char *) malloc (sizeof (char) * 9);
415
sprintf(client_name, "netsource");
416
sprintf(peer_ip, "localhost");
418
while ((c = getopt (argc, argv, ":n:s:h:p:C:P:i:o:l:r:f:b:m:c:")) != -1)
424
client_name = (char *) malloc (sizeof (char) * strlen (optarg));
425
strcpy (client_name, optarg);
428
server_name = (char *) malloc (sizeof (char) * strlen (optarg));
429
strcpy (server_name, optarg);
430
options |= JackServerName;
434
peer_ip = (char *) malloc (sizeof (char) * strlen (optarg));
435
strcpy (peer_ip, optarg);
438
peer_port = atoi (optarg);
441
playback_channels_audio = atoi (optarg);
444
capture_channels_audio = atoi (optarg);
447
playback_channels_midi = atoi (optarg);
450
capture_channels_midi = atoi (optarg);
453
latency = atoi (optarg);
456
reply_port = atoi (optarg);
459
factor = atoi (optarg);
462
bitdepth = atoi (optarg);
467
factor = atoi (optarg);
469
printf( "not built with celt supprt\n" );
477
fprintf (stderr, "Option -%c requires an operand\n", optopt);
481
fprintf (stderr, "Unrecognized option: -%c\n", optopt);
491
capture_channels = capture_channels_audio + capture_channels_midi;
492
playback_channels = playback_channels_audio + playback_channels_midi;
494
outsockfd = socket (PF_INET, SOCK_DGRAM, 0);
495
insockfd = socket (PF_INET, SOCK_DGRAM, 0);
496
init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
499
init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
500
bind (insockfd, &bindaddr, sizeof (bindaddr));
503
/* try to become a client of the JACK server */
504
client = jack_client_open (client_name, options, &status, server_name);
507
fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n"
508
"Is the JACK server running ?\n", status);
512
/* Set up jack callbacks */
513
jack_set_process_callback (client, process, 0);
514
jack_set_sync_callback (client, sync_cb, 0);
515
jack_on_shutdown (client, jack_shutdown, 0);
517
alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);
519
jack_nframes_t net_period = (float) jack_get_buffer_size (client) / (float) factor;
520
int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
521
global_packcache = packet_cache_new (latency + 5, rx_bufsize, mtu);
523
/* tell the JACK server that we are ready to roll */
524
if (jack_activate (client))
526
fprintf (stderr, "Cannot activate client");
530
/* Now sleep forever... and evaluate the state_ vars */
532
statecopy_connected = 2; // make it report unconnected on start.
533
statecopy_latency = state_latency;
534
statecopy_netxruns = state_netxruns;
539
if (statecopy_connected != state_connected)
541
statecopy_connected = state_connected;
542
if (statecopy_connected)
544
state_netxruns = 1; // We want to reset the netxrun count on each new connection
545
printf ("Connected :-)\n");
548
printf ("Not Connected\n");
551
if (statecopy_connected)
553
if (statecopy_netxruns != state_netxruns) {
554
statecopy_netxruns = state_netxruns;
555
printf ("at frame %06d -> total netxruns %d\n", state_currentframe, statecopy_netxruns);
560
if (statecopy_latency != state_latency)
562
statecopy_latency = state_latency;
563
if (statecopy_latency > 1)
564
printf ("current latency %d\n", statecopy_latency);
569
/* Never reached. Well we will be a GtkApp someday... */
570
packet_cache_free (global_packcache);
571
jack_client_close (client);