9c8cd3202a96acc2bba17ebdea28270889361de0
1 /* -*- mode: c; c-file-style: "linux"; -*- */
2 /*
3 NetJack Driver
5 Copyright (C) 2008 Pieter Palmers <pieterpalmers@users.sourceforge.net>
6 Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
7 Copyright (C) 2003 Robert Ham <rah@bash.sh>
8 Copyright (C) 2001 Paul Davis
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $
25 */
27 #include <math.h>
28 #include <stdio.h>
29 #include <memory.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <stdarg.h>
34 #include <sys/mman.h>
36 #include <jack/types.h>
37 #include "engine.h"
38 #include <sysdeps/time.h>
40 #include <sys/types.h>
42 #include "config.h"
45 #include "netjack.h"
46 #include "netjack_packet.h"
47 #include "net_driver.h"
49 #undef DEBUG_WAKEUP
52 #define MIN(x,y) ((x)<(y) ? (x) : (y))
54 static jack_transport_state_t last_transport_state;
55 static int sync_state = TRUE;
57 static jack_nframes_t
58 net_driver_wait (net_driver_t *driver, int extra_fd, int *status, float *delayed_usecs)
59 {
60 netjack_driver_state_t *netj = &( driver->netj );
61 int delay;
63 delay = netjack_wait( netj, driver->engine->get_microseconds );
64 if( delay ) {
65 //driver->engine->delay( driver->engine, (float)delay );
66 jack_error( "netxruns amount: %dms", delay/1000 );
67 }
70 driver->last_wait_ust = driver->engine->get_microseconds ();
71 driver->engine->transport_cycle_start (driver->engine, driver->last_wait_ust);
73 /* this driver doesn't work so well if we report a delay */
74 /* XXX: this might not be the case anymore */
75 /* the delayed _usecs is a resync or something. */
76 *delayed_usecs = 0; /* lie about it */
77 *status = 0;
78 return netj->period_size;
79 }
81 static int
82 net_driver_run_cycle (net_driver_t *driver)
83 {
84 jack_engine_t *engine = driver->engine;
85 //netjack_driver_state_t *netj = &(driver->netj);
86 int wait_status = -1;
87 float delayed_usecs;
89 jack_nframes_t nframes = net_driver_wait (driver, -1, &wait_status,
90 &delayed_usecs);
92 // XXX: xrun code removed.
93 // especially with celt there are no real xruns anymore.
94 // things are different on the net.
96 if (wait_status == 0)
97 return engine->run_cycle (engine, nframes, delayed_usecs);
99 if (wait_status < 0)
100 return -1;
101 else
102 return 0;
103 }
105 static int
106 net_driver_null_cycle (net_driver_t* driver, jack_nframes_t nframes)
107 {
108 // TODO: talk to paul about this.
109 // do i wait here ?
110 // just sending out a packet marked with junk ?
112 netjack_driver_state_t *netj = &(driver->netj);
113 int sync_state = (driver->engine->control->sync_remain <= 1);
114 netjack_send_silence( netj, sync_state );
116 return 0;
117 }
119 static int
120 net_driver_bufsize (net_driver_t* driver, jack_nframes_t nframes)
121 {
122 netjack_driver_state_t *netj = &(driver->netj);
123 if (nframes != netj->period_size)
124 return EINVAL;
126 return 0;
127 }
129 static int
130 net_driver_read (net_driver_t* driver, jack_nframes_t nframes)
131 {
132 netjack_driver_state_t *netj = &(driver->netj);
134 jack_position_t local_trans_pos;
135 jack_transport_state_t local_trans_state;
137 unsigned int *packet_buf, *packet_bufX;
139 if( ! netj->packet_data_valid ) {
140 render_payload_to_jack_ports (netj->bitdepth, NULL, netj->net_period_down, netj->capture_ports, netj->capture_srcs, nframes, netj->dont_htonl_floats );
141 return 0;
142 }
143 packet_buf = netj->rx_buf;
145 jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf;
147 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
149 netj->reply_port = pkthdr->reply_port;
150 netj->latency = pkthdr->latency;
152 // Special handling for latency=0
153 if( netj->latency == 0 )
154 netj->resync_threshold = 0;
155 else
156 netj->resync_threshold = MIN( 15, pkthdr->latency-1 );
158 // check whether, we should handle the transport sync stuff, or leave trnasports untouched.
159 if (netj->handle_transport_sync) {
160 int compensated_tranport_pos = (pkthdr->transport_frame + (pkthdr->latency * nframes) + netj->codec_latency);
162 // read local transport info....
163 local_trans_state = jack_transport_query(netj->client, &local_trans_pos);
165 // Now check if we have to start or stop local transport to sync to remote...
166 switch (pkthdr->transport_state) {
167 case JackTransportStarting:
168 // the master transport is starting... so we set our reply to the sync_callback;
169 if (local_trans_state == JackTransportStopped) {
170 jack_transport_start(netj->client);
171 last_transport_state = JackTransportStopped;
172 sync_state = FALSE;
173 jack_info("locally stopped... starting...");
174 }
176 if (local_trans_pos.frame != compensated_tranport_pos)
177 {
178 jack_transport_locate(netj->client, compensated_tranport_pos);
179 last_transport_state = JackTransportRolling;
180 sync_state = FALSE;
181 jack_info("starting locate to %d", compensated_tranport_pos );
182 }
183 break;
184 case JackTransportStopped:
185 sync_state = TRUE;
186 if (local_trans_pos.frame != (pkthdr->transport_frame)) {
187 jack_transport_locate(netj->client, (pkthdr->transport_frame));
188 jack_info("transport is stopped locate to %d", pkthdr->transport_frame);
189 }
190 if (local_trans_state != JackTransportStopped)
191 jack_transport_stop(netj->client);
192 break;
193 case JackTransportRolling:
194 sync_state = TRUE;
195 // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * nframes)) {
196 // jack_transport_locate(netj->client, (pkthdr->transport_frame + (pkthdr->latency + 2) * nframes));
197 // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*nframes);
198 // }
199 if (local_trans_state != JackTransportRolling)
200 jack_transport_start (netj->client);
201 break;
203 case JackTransportLooping:
204 break;
205 }
206 }
208 render_payload_to_jack_ports (netj->bitdepth, packet_bufX, netj->net_period_down, netj->capture_ports, netj->capture_srcs, nframes, netj->dont_htonl_floats );
209 packet_cache_release_packet(netj->packcache, netj->expected_framecnt );
211 return 0;
212 }
214 static int
215 net_driver_write (net_driver_t* driver, jack_nframes_t nframes)
216 {
217 netjack_driver_state_t *netj = &(driver->netj);
219 int sync_state = (driver->engine->control->sync_remain <= 1);;
221 uint32_t *packet_buf, *packet_bufX;
223 int packet_size = get_sample_size(netj->bitdepth) * netj->playback_channels * netj->net_period_up + sizeof(jacknet_packet_header);
224 jacknet_packet_header *pkthdr;
226 packet_buf = alloca(packet_size);
227 pkthdr = (jacknet_packet_header *)packet_buf;
229 if( netj->running_free ) {
230 return 0;
231 }
233 // offset packet_bufX by the packetheader.
234 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
236 pkthdr->sync_state = sync_state;
237 pkthdr->latency = netj->time_to_deadline;
238 //printf( "time to deadline = %d goodness=%d\n", (int)netj->time_to_deadline, netj->deadline_goodness );
239 pkthdr->framecnt = netj->expected_framecnt;
242 render_jack_ports_to_payload(netj->bitdepth, netj->playback_ports, netj->playback_srcs, nframes, packet_bufX, netj->net_period_up, netj->dont_htonl_floats );
244 packet_header_hton(pkthdr);
245 if (netj->srcaddress_valid)
246 {
247 int r;
249 #ifndef MSG_CONFIRM
250 static const int flag = 0;
251 #else
252 static const int flag = MSG_CONFIRM;
253 #endif
255 if (netj->reply_port)
256 netj->syncsource_address.sin_port = htons(netj->reply_port);
258 for( r=0; r<netj->redundancy; r++ )
259 netjack_sendto(netj->sockfd, (char *)packet_buf, packet_size,
260 flag, (struct sockaddr*)&(netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu);
261 }
263 return 0;
264 }
267 static int
268 net_driver_attach (net_driver_t *driver)
269 {
270 netjack_driver_state_t *netj = &( driver->netj );
271 if (driver->engine->set_buffer_size (driver->engine, netj->period_size)) {
272 jack_error ("netjack: cannot set engine buffer size to %d (check MIDI)", netj->period_size);
273 return -1;
274 }
275 driver->engine->set_sample_rate (driver->engine, netj->sample_rate);
277 netjack_attach( netj );
278 return 0;
279 }
281 static int
282 net_driver_detach (net_driver_t *driver)
283 {
284 netjack_driver_state_t *netj = &( driver->netj );
286 if (driver->engine == 0)
287 return 0;
289 netjack_detach( netj );
290 return 0;
291 }
293 static void
294 net_driver_delete (net_driver_t *driver)
295 {
296 netjack_driver_state_t *netj = &( driver->netj );
297 netjack_release( netj );
298 jack_driver_nt_finish ((jack_driver_nt_t *) driver);
299 free (driver);
300 }
302 static jack_driver_t *
303 net_driver_new (jack_client_t * client,
304 char *name,
305 unsigned int capture_ports,
306 unsigned int playback_ports,
307 unsigned int capture_ports_midi,
308 unsigned int playback_ports_midi,
309 jack_nframes_t sample_rate,
310 jack_nframes_t period_size,
311 unsigned int listen_port,
312 unsigned int transport_sync,
313 unsigned int resample_factor,
314 unsigned int resample_factor_up,
315 unsigned int bitdepth,
316 unsigned int use_autoconfig,
317 unsigned int latency,
318 unsigned int redundancy,
319 int dont_htonl_floats,
320 int always_deadline,
321 int jitter_val)
322 {
323 net_driver_t * driver;
325 jack_info ("creating net driver ... %s|%" PRIu32 "|%" PRIu32
326 "|%u|%u|%u|transport_sync:%u", name, sample_rate, period_size, listen_port,
327 capture_ports, playback_ports, transport_sync);
329 driver = (net_driver_t *) calloc (1, sizeof (net_driver_t));
331 jack_driver_nt_init ((jack_driver_nt_t *) driver);
333 driver->write = (JackDriverWriteFunction) net_driver_write;
334 driver->read = (JackDriverReadFunction) net_driver_read;
335 driver->null_cycle = (JackDriverNullCycleFunction) net_driver_null_cycle;
336 driver->nt_attach = (JackDriverNTAttachFunction) net_driver_attach;
337 driver->nt_detach = (JackDriverNTDetachFunction) net_driver_detach;
338 driver->nt_bufsize = (JackDriverNTBufSizeFunction) net_driver_bufsize;
339 driver->nt_run_cycle = (JackDriverNTRunCycleFunction) net_driver_run_cycle;
341 driver->last_wait_ust = 0;
342 driver->engine = NULL;
344 netjack_driver_state_t *netj = &(driver->netj);
346 netjack_init ( netj,
347 client,
348 name,
349 capture_ports,
350 playback_ports,
351 capture_ports_midi,
352 playback_ports_midi,
353 sample_rate,
354 period_size,
355 listen_port,
356 transport_sync,
357 resample_factor,
358 resample_factor_up,
359 bitdepth,
360 use_autoconfig,
361 latency,
362 redundancy,
363 dont_htonl_floats,
364 always_deadline,
365 jitter_val );
367 netjack_startup( netj );
369 jack_info ("netjack: period : up: %d / dn: %d", netj->net_period_up, netj->net_period_down);
370 jack_info ("netjack: framerate: %d", netj->sample_rate);
371 jack_info ("netjack: audio : cap: %d / pbk: %d)", netj->capture_channels_audio, netj->playback_channels_audio);
372 jack_info ("netjack: midi : cap: %d / pbk: %d)", netj->capture_channels_midi, netj->playback_channels_midi);
373 jack_info ("netjack: buffsize : rx: %d)", netj->rx_bufsize);
374 driver->period_usecs = netj->period_usecs;
376 return (jack_driver_t *) driver;
377 }
379 /* DRIVER "PLUGIN" INTERFACE */
381 jack_driver_desc_t *
382 driver_get_descriptor ()
383 {
384 jack_driver_desc_t * desc;
385 jack_driver_param_desc_t * params;
386 unsigned int i;
388 desc = calloc (1, sizeof (jack_driver_desc_t));
389 strcpy (desc->name, "net");
390 desc->nparams = 18;
392 params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
394 i = 0;
395 strcpy (params[i].name, "audio-ins");
396 params[i].character = 'i';
397 params[i].type = JackDriverParamUInt;
398 params[i].value.ui = 2U;
399 strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)");
400 strcpy (params[i].long_desc, params[i].short_desc);
402 i++;
403 strcpy (params[i].name, "audio-outs");
404 params[i].character = 'o';
405 params[i].type = JackDriverParamUInt;
406 params[i].value.ui = 2U;
407 strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)");
408 strcpy (params[i].long_desc, params[i].short_desc);
410 i++;
411 strcpy (params[i].name, "midi-ins");
412 params[i].character = 'I';
413 params[i].type = JackDriverParamUInt;
414 params[i].value.ui = 1U;
415 strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)");
416 strcpy (params[i].long_desc, params[i].short_desc);
418 i++;
419 strcpy (params[i].name, "midi-outs");
420 params[i].character = 'O';
421 params[i].type = JackDriverParamUInt;
422 params[i].value.ui = 1U;
423 strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)");
424 strcpy (params[i].long_desc, params[i].short_desc);
426 i++;
427 strcpy (params[i].name, "rate");
428 params[i].character = 'r';
429 params[i].type = JackDriverParamUInt;
430 params[i].value.ui = 48000U;
431 strcpy (params[i].short_desc, "Sample rate");
432 strcpy (params[i].long_desc, params[i].short_desc);
434 i++;
435 strcpy (params[i].name, "period");
436 params[i].character = 'p';
437 params[i].type = JackDriverParamUInt;
438 params[i].value.ui = 1024U;
439 strcpy (params[i].short_desc, "Frames per period");
440 strcpy (params[i].long_desc, params[i].short_desc);
442 i++;
443 strcpy (params[i].name, "num-periods");
444 params[i].character = 'n';
445 params[i].type = JackDriverParamUInt;
446 params[i].value.ui = 5U;
447 strcpy (params[i].short_desc,
448 "Network latency setting in no. of periods");
449 strcpy (params[i].long_desc, params[i].short_desc);
451 i++;
452 strcpy (params[i].name, "listen-port");
453 params[i].character = 'l';
454 params[i].type = JackDriverParamUInt;
455 params[i].value.ui = 3000U;
456 strcpy (params[i].short_desc,
457 "The socket port we are listening on for sync packets");
458 strcpy (params[i].long_desc, params[i].short_desc);
460 i++;
461 strcpy (params[i].name, "factor");
462 params[i].character = 'f';
463 params[i].type = JackDriverParamUInt;
464 params[i].value.ui = 1U;
465 strcpy (params[i].short_desc,
466 "Factor for sample rate reduction (deprecated)");
467 strcpy (params[i].long_desc, params[i].short_desc);
469 i++;
470 strcpy (params[i].name, "upstream-factor");
471 params[i].character = 'u';
472 params[i].type = JackDriverParamUInt;
473 params[i].value.ui = 0U;
474 strcpy (params[i].short_desc,
475 "Factor for sample rate reduction on the upstream (deprecated)");
476 strcpy (params[i].long_desc, params[i].short_desc);
478 i++;
479 strcpy (params[i].name, "celt");
480 params[i].character = 'c';
481 params[i].type = JackDriverParamUInt;
482 params[i].value.ui = 0U;
483 strcpy (params[i].short_desc,
484 "sets celt encoding and kbits value one channel is encoded at");
485 strcpy (params[i].long_desc, params[i].short_desc);
487 i++;
488 strcpy (params[i].name, "bit-depth");
489 params[i].character = 'b';
490 params[i].type = JackDriverParamUInt;
491 params[i].value.ui = 0U;
492 strcpy (params[i].short_desc,
493 "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)");
494 strcpy (params[i].long_desc, params[i].short_desc);
496 i++;
497 strcpy (params[i].name, "transport-sync");
498 params[i].character = 't';
499 params[i].type = JackDriverParamUInt;
500 params[i].value.ui = 1U;
501 strcpy (params[i].short_desc,
502 "Whether to slave the transport to the master transport");
503 strcpy (params[i].long_desc, params[i].short_desc);
505 i++;
506 strcpy (params[i].name, "autoconf");
507 params[i].character = 'a';
508 params[i].type = JackDriverParamUInt;
509 params[i].value.ui = 1U;
510 strcpy (params[i].short_desc,
511 "Whether to use Autoconfig, or just start.");
512 strcpy (params[i].long_desc, params[i].short_desc);
513 i++;
514 strcpy (params[i].name, "redundancy");
515 params[i].character = 'R';
516 params[i].type = JackDriverParamUInt;
517 params[i].value.ui = 1U;
518 strcpy (params[i].short_desc,
519 "Send packets N times");
520 strcpy (params[i].long_desc, params[i].short_desc);
522 i++;
523 strcpy (params[i].name, "native-endian");
524 params[i].character = 'e';
525 params[i].type = JackDriverParamUInt;
526 params[i].value.ui = 0U;
527 strcpy (params[i].short_desc,
528 "Don't convert samples to network byte order.");
529 strcpy (params[i].long_desc, params[i].short_desc);
531 i++;
532 strcpy (params[i].name, "jitterval");
533 params[i].character = 'J';
534 params[i].type = JackDriverParamInt;
535 params[i].value.i = 0;
536 strcpy (params[i].short_desc,
537 "attempted jitterbuffer microseconds on master");
538 strcpy (params[i].long_desc, params[i].short_desc);
540 i++;
541 strcpy (params[i].name, "always-deadline");
542 params[i].character = 'D';
543 params[i].type = JackDriverParamUInt;
544 params[i].value.ui = 0U;
545 strcpy (params[i].short_desc,
546 "Always wait until deadline");
547 strcpy (params[i].long_desc, params[i].short_desc);
548 desc->params = params;
550 return desc;
551 }
553 const char driver_client_name[] = "net_pcm";
555 jack_driver_t *
556 driver_initialize (jack_client_t *client, const JSList * params)
557 {
558 jack_nframes_t sample_rate = 48000;
559 jack_nframes_t resample_factor = 1;
560 jack_nframes_t period_size = 1024;
561 unsigned int capture_ports = 2;
562 unsigned int playback_ports = 2;
563 unsigned int capture_ports_midi = 1;
564 unsigned int playback_ports_midi = 1;
565 unsigned int listen_port = 3000;
566 unsigned int resample_factor_up = 0;
567 unsigned int bitdepth = 0;
568 unsigned int handle_transport_sync = 1;
569 unsigned int use_autoconfig = 1;
570 unsigned int latency = 5;
571 unsigned int redundancy = 1;
572 int dont_htonl_floats = 0;
573 int always_deadline = 0;
574 int jitter_val = 0;
575 const JSList * node;
576 const jack_driver_param_t * param;
578 for (node = params; node; node = jack_slist_next (node)) {
579 param = (const jack_driver_param_t *) node->data;
581 switch (param->character) {
583 case 'i':
584 capture_ports = param->value.ui;
585 break;
587 case 'o':
588 playback_ports = param->value.ui;
589 break;
591 case 'I':
592 capture_ports_midi = param->value.ui;
593 break;
595 case 'O':
596 playback_ports_midi = param->value.ui;
597 break;
599 case 'r':
600 sample_rate = param->value.ui;
601 break;
603 case 'p':
604 period_size = param->value.ui;
605 break;
607 case 'l':
608 listen_port = param->value.ui;
609 break;
611 case 'f':
612 #if HAVE_SAMPLERATE
613 resample_factor = param->value.ui;
614 #else
615 printf( "not built with libsamplerate support\n" );
616 exit(10);
617 #endif
618 break;
620 case 'u':
621 #if HAVE_SAMPLERATE
622 resample_factor_up = param->value.ui;
623 #else
624 printf( "not built with libsamplerate support\n" );
625 exit(10);
626 #endif
627 break;
629 case 'b':
630 bitdepth = param->value.ui;
631 break;
633 case 'c':
634 #if HAVE_CELT
635 bitdepth = 1000;
636 resample_factor = param->value.ui;
637 #else
638 printf( "not built with celt support\n" );
639 exit(10);
640 #endif
641 break;
643 case 't':
644 handle_transport_sync = param->value.ui;
645 break;
647 case 'a':
648 use_autoconfig = param->value.ui;
649 break;
651 case 'n':
652 latency = param->value.ui;
653 break;
655 case 'R':
656 redundancy = param->value.ui;
657 break;
659 case 'e':
660 dont_htonl_floats = param->value.ui;
661 break;
662 case 'J':
663 jitter_val = param->value.i;
664 break;
665 case 'D':
666 always_deadline = param->value.ui;
667 break;
668 }
669 }
671 return net_driver_new (client, "net_pcm", capture_ports, playback_ports,
672 capture_ports_midi, playback_ports_midi,
673 sample_rate, period_size,
674 listen_port, handle_transport_sync,
675 resample_factor, resample_factor_up, bitdepth,
676 use_autoconfig, latency, redundancy,
677 dont_htonl_floats, always_deadline, jitter_val);
678 }
680 void
681 driver_finish (jack_driver_t *driver)
682 {
683 net_driver_delete ((net_driver_t *) driver);
684 }
