oops, paul should remember to try an OSX build before releasing a tarball; fixed...
[jack.git] / drivers / netjack / net_driver.c
blobaa49271e360ef9517eca7c14a6a8a4f0de73cd4a
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 $
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 <jack/engine.h>
38 #include <sysdeps/time.h>
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <netinet/in.h>
44 #include <samplerate.h>
46 #include "net_driver.h"
47 #include "netjack_packet.h"
49 #undef DEBUG_WAKEUP
51 static int sync_state = TRUE;
52 static jack_transport_state_t last_transport_state;
54 /* This is set upon reading a packetand will be
55 * written into the pkthdr of an outgoing packet */
56 static int framecnt;
58 static int
59 net_driver_sync_cb(jack_transport_state_t state, jack_position_t *pos, net_driver_t *driver)
61 int retval = sync_state;
63 if (state == JackTransportStarting && last_transport_state != JackTransportStarting) {
64 retval = 0;
66 if (state == JackTransportStarting)
67 jack_info("Starting sync_state = %d", sync_state);
68 last_transport_state = state;
69 return retval;
72 static jack_nframes_t
73 net_driver_wait (net_driver_t *driver, int extra_fd, int *status, float *delayed_usecs)
75 // ok... we wait for a packet on the socket
76 // TODO:
77 // we should be able to run freely if the sync source is not transmitting
78 // especially we should be able to compensate for packet loss somehow.
79 // but lets try this out first.
81 // on packet loss we should either detect an xrun or just continue running when we
82 // think, that the sync source is not running anymore.
84 socklen_t address_size = sizeof (struct sockaddr_in);
85 int bufsize, len;
86 jacknet_packet_header *pkthdr = (jacknet_packet_header *) driver->rx_buf;
88 bufsize = get_sample_size (driver->bitdepth) * driver->capture_channels * driver->net_period_down + sizeof (jacknet_packet_header);
90 if (netjack_poll (driver->sockfd, 500))
91 len = netjack_recvfrom (driver->sockfd, (char *)driver->rx_buf, bufsize, MSG_WAITALL, (struct sockaddr*) & driver->syncsource_address, &address_size, driver->mtu);
92 else
93 len = 0;
94 while (len != bufsize)
96 jack_error ("wrong_packet_len: len=%d, expected=%d", len, bufsize);
97 if (netjack_poll (driver->sockfd, 500))
98 len = netjack_recvfrom (driver->sockfd, (char *)driver->rx_buf, bufsize, MSG_WAITALL, (struct sockaddr*) & driver->syncsource_address, &address_size, driver->mtu);
99 else
100 len = 0;
103 packet_header_ntoh (pkthdr);
104 driver->last_wait_ust = jack_get_microseconds ();
105 driver->engine->transport_cycle_start (driver->engine, driver->last_wait_ust);
106 /* this driver doesn't work so well if we report a delay */
107 *delayed_usecs = 0; /* lie about it */
108 *status = 0;
109 return driver->period_size;
112 static inline int
113 net_driver_run_cycle (net_driver_t *driver)
115 jack_engine_t *engine = driver->engine;
116 int wait_status = -1;
117 float delayed_usecs;
119 jack_nframes_t nframes = net_driver_wait (driver, -1, &wait_status,
120 &delayed_usecs);
122 // currently there is no xrun detection.
123 // so nframes will always be period_size.
124 // XXX: i uncomment this code because the signature of delay()
125 // changed samewhere in the 0.99.x series. so this is the showstopper for 0.99.0
127 #if 0
128 if (nframes == 0) {
129 /* we detected an xrun and restarted: notify
130 * clients about the delay. */
131 engine->delay (engine, delayed_usecs);
132 return 0;
134 #endif
136 if (wait_status == 0)
137 return engine->run_cycle (engine, nframes, delayed_usecs);
139 if (wait_status < 0)
140 return -1;
141 else
142 return 0;
145 static int
146 net_driver_null_cycle (net_driver_t* driver, jack_nframes_t nframes)
148 //int rx_size = get_sample_size(driver->bitdepth) * driver->capture_channels * driver->net_period_down + sizeof(jacknet_packet_header);
149 int tx_size = get_sample_size(driver->bitdepth) * driver->playback_channels * driver->net_period_up + sizeof(jacknet_packet_header);
150 unsigned int *packet_buf, *packet_bufX;
152 packet_buf = alloca( tx_size);
153 jacknet_packet_header *tx_pkthdr = (jacknet_packet_header *)packet_buf;
154 jacknet_packet_header *rx_pkthdr = (jacknet_packet_header *)driver->rx_buf;
156 framecnt = rx_pkthdr->framecnt;
158 driver->reply_port = rx_pkthdr->reply_port;
160 // offset packet_bufX by the packetheader.
161 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
163 tx_pkthdr->sync_state = (driver->engine->control->sync_remain <= 1);
165 tx_pkthdr->framecnt = framecnt;
167 // memset 0 the payload.
168 int payload_size = get_sample_size(driver->bitdepth) * driver->playback_channels * driver->net_period_up;
169 memset(packet_bufX, 0, payload_size);
171 packet_header_hton(tx_pkthdr);
172 if (driver->srcaddress_valid)
173 if (driver->reply_port)
174 driver->syncsource_address.sin_port = htons(driver->reply_port);
176 netjack_sendto(driver->outsockfd, (char *)packet_buf, tx_size,
177 0, (struct sockaddr*)&driver->syncsource_address, sizeof(struct sockaddr_in), driver->mtu);
179 return 0;
182 static int
183 net_driver_bufsize (net_driver_t* driver, jack_nframes_t nframes)
185 if (nframes != driver->period_size)
186 return EINVAL;
188 return 0;
191 static int
192 net_driver_read (net_driver_t* driver, jack_nframes_t nframes)
194 //jack_default_audio_sample_t* buf;
195 //jack_port_t *port;
196 jack_position_t local_trans_pos;
197 jack_transport_state_t local_trans_state;
199 //int bufsize = get_sample_size(driver->bitdepth) * driver->capture_channels * driver->net_period_down + sizeof(jacknet_packet_header);
200 unsigned int *packet_buf, *packet_bufX;
202 packet_buf = driver->rx_buf;
204 jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf;
206 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
208 //packet_header_ntoh(pkthdr);
209 // fill framecnt from pkthdr.
211 //if (pkthdr->framecnt != framecnt + 1)
212 // jack_info("bogus framecount %d", pkthdr->framecnt);
214 framecnt = pkthdr->framecnt;
215 driver->reply_port = pkthdr->reply_port;
217 // check whether, we should handle the transport sync stuff, or leave trnasports untouched.
218 if (driver->handle_transport_sync) {
220 // read local transport info....
221 local_trans_state = jack_transport_query(driver->client, &local_trans_pos);
223 // Now check if we have to start or stop local transport to sync to remote...
224 switch (pkthdr->transport_state) {
225 case JackTransportStarting:
226 // the master transport is starting... so we set our reply to the sync_callback;
227 if (local_trans_state == JackTransportStopped) {
228 jack_transport_start(driver->client);
229 last_transport_state = JackTransportStopped;
230 sync_state = FALSE;
231 jack_info("locally stopped... starting...");
234 if (local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * nframes)) {
235 jack_transport_locate(driver->client, (pkthdr->transport_frame + (pkthdr->latency) * nframes));
236 last_transport_state = JackTransportRolling;
237 sync_state = FALSE;
238 jack_info("starting locate to %d", pkthdr->transport_frame + (pkthdr->latency)*nframes);
240 break;
241 case JackTransportStopped:
242 sync_state = TRUE;
243 if (local_trans_pos.frame != (pkthdr->transport_frame)) {
244 jack_transport_locate(driver->client, (pkthdr->transport_frame));
245 jack_info("transport is stopped locate to %d", pkthdr->transport_frame);
247 if (local_trans_state != JackTransportStopped)
248 jack_transport_stop(driver->client);
249 break;
250 case JackTransportRolling:
251 sync_state = TRUE;
252 // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * nframes)) {
253 // jack_transport_locate(driver->client, (pkthdr->transport_frame + (pkthdr->latency + 2) * nframes));
254 // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*nframes);
255 // }
256 if (local_trans_state != JackTransportRolling)
257 jack_transport_start (driver->client);
258 break;
260 case JackTransportLooping:
261 break;
265 render_payload_to_jack_ports (driver->bitdepth, packet_bufX, driver->net_period_down, driver->capture_ports, driver->capture_srcs, nframes);
267 return 0;
270 static int
271 net_driver_write (net_driver_t* driver, jack_nframes_t nframes)
273 uint32_t *packet_buf, *packet_bufX;
275 int packet_size = get_sample_size(driver->bitdepth) * driver->playback_channels * driver->net_period_up + sizeof(jacknet_packet_header);
277 packet_buf = alloca(packet_size);
279 jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf;
281 // offset packet_bufX by the packetheader.
282 packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
284 pkthdr->sync_state = (driver->engine->control->sync_remain <= 1);
285 pkthdr->framecnt = framecnt;
287 render_jack_ports_to_payload(driver->bitdepth, driver->playback_ports, driver->playback_srcs, nframes, packet_bufX, driver->net_period_up);
289 packet_header_hton(pkthdr);
290 if (driver->srcaddress_valid)
291 if (driver->reply_port)
292 driver->syncsource_address.sin_port = htons(driver->reply_port);
293 netjack_sendto(driver->outsockfd, (char *)packet_buf, packet_size,
294 0, (struct sockaddr*)&driver->syncsource_address, sizeof(struct sockaddr_in), driver->mtu);
296 return 0;
300 static int
301 net_driver_attach (net_driver_t *driver)
303 //puts ("net_driver_attach");
304 jack_port_t * port;
305 char buf[32];
306 unsigned int chn;
307 int port_flags;
309 driver->engine->set_buffer_size (driver->engine, driver->period_size);
310 driver->engine->set_sample_rate (driver->engine, driver->sample_rate);
312 if (driver->handle_transport_sync)
313 jack_set_sync_callback(driver->client, (JackSyncCallback) net_driver_sync_cb, driver);
315 port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
317 for (chn = 0; chn < driver->capture_channels_audio; chn++) {
318 snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
320 port = jack_port_register (driver->client, buf,
321 JACK_DEFAULT_AUDIO_TYPE,
322 port_flags, 0);
323 if (!port) {
324 jack_error ("NET: cannot register port for %s", buf);
325 break;
328 driver->capture_ports =
329 jack_slist_append (driver->capture_ports, port);
330 driver->capture_srcs = jack_slist_append(driver->capture_srcs, src_new(SRC_LINEAR, 1, NULL));
332 for (chn = driver->capture_channels_audio; chn < driver->capture_channels; chn++) {
333 snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
335 port = jack_port_register (driver->client, buf,
336 JACK_DEFAULT_MIDI_TYPE,
337 port_flags, 0);
338 if (!port) {
339 jack_error ("NET: cannot register port for %s", buf);
340 break;
343 driver->capture_ports =
344 jack_slist_append (driver->capture_ports, port);
345 //driver->capture_srcs = jack_slist_append(driver->capture_srcs, src_new(SRC_LINEAR, 1, NULL));
348 port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
350 for (chn = 0; chn < driver->playback_channels_audio; chn++) {
351 snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
353 port = jack_port_register (driver->client, buf,
354 JACK_DEFAULT_AUDIO_TYPE,
355 port_flags, 0);
357 if (!port) {
358 jack_error ("NET: cannot register port for %s", buf);
359 break;
362 driver->playback_ports =
363 jack_slist_append (driver->playback_ports, port);
364 driver->playback_srcs = jack_slist_append(driver->playback_srcs, src_new(SRC_LINEAR, 1, NULL));
366 for (chn = driver->playback_channels_audio; chn < driver->playback_channels; chn++) {
367 snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
369 port = jack_port_register (driver->client, buf,
370 JACK_DEFAULT_MIDI_TYPE,
371 port_flags, 0);
373 if (!port) {
374 jack_error ("NET: cannot register port for %s", buf);
375 break;
378 driver->playback_ports =
379 jack_slist_append (driver->playback_ports, port);
380 //driver->playback_srcs = jack_slist_append(driver->playback_srcs, src_new(SRC_LINEAR, 1, NULL));
383 jack_activate (driver->client);
384 return 0;
387 static int
388 net_driver_detach (net_driver_t *driver)
390 JSList * node;
392 if (driver->engine == 0)
393 return 0;
394 //#if 0
395 for (node = driver->capture_ports; node; node = jack_slist_next (node))
396 jack_port_unregister (driver->client,
397 ((jack_port_t *) node->data));
399 jack_slist_free (driver->capture_ports);
400 driver->capture_ports = NULL;
401 //#endif
403 for (node = driver->playback_ports; node; node = jack_slist_next (node))
404 jack_port_unregister (driver->client,
405 ((jack_port_t *) node->data));
407 jack_slist_free (driver->playback_ports);
408 driver->playback_ports = NULL;
410 return 0;
413 static void
414 net_driver_delete (net_driver_t *driver)
416 jack_driver_nt_finish ((jack_driver_nt_t *) driver);
417 free (driver);
420 static jack_driver_t *
421 net_driver_new (jack_client_t * client,
422 char *name,
423 unsigned int capture_ports,
424 unsigned int playback_ports,
425 unsigned int capture_ports_midi,
426 unsigned int playback_ports_midi,
427 jack_nframes_t sample_rate,
428 jack_nframes_t period_size,
429 unsigned int listen_port,
430 unsigned int transport_sync,
431 unsigned int resample_factor,
432 unsigned int resample_factor_up,
433 unsigned int bitdepth)
435 net_driver_t * driver;
436 int first_pack_len, rx_bufsize;
437 struct sockaddr_in address;
439 jack_info ("creating net driver ... %s|%" PRIu32 "|%" PRIu32
440 "|%u|%u|%u|transport_sync:%u", name, sample_rate, period_size, listen_port,
441 capture_ports, playback_ports, transport_sync);
443 driver = (net_driver_t *) calloc (1, sizeof (net_driver_t));
445 jack_driver_nt_init ((jack_driver_nt_t *) driver);
447 driver->write = (JackDriverWriteFunction) net_driver_write;
448 driver->read = (JackDriverReadFunction) net_driver_read;
449 driver->null_cycle = (JackDriverNullCycleFunction) net_driver_null_cycle;
450 driver->nt_attach = (JackDriverNTAttachFunction) net_driver_attach;
451 driver->nt_detach = (JackDriverNTDetachFunction) net_driver_detach;
452 driver->nt_bufsize = (JackDriverNTBufSizeFunction) net_driver_bufsize;
453 driver->nt_run_cycle = (JackDriverNTRunCycleFunction) net_driver_run_cycle;
455 // Fill in driver values.
456 // might be subject to autoconfig...
457 // so dont calculate anything with them...
459 driver->sample_rate = sample_rate;
460 driver->period_size = period_size;
462 driver->listen_port = listen_port;
463 driver->last_wait_ust = 0;
465 driver->capture_channels = capture_ports + capture_ports_midi;
466 driver->capture_channels_audio = capture_ports;
467 driver->capture_channels_midi = capture_ports_midi;
468 driver->capture_ports = NULL;
469 driver->playback_channels = playback_ports + playback_ports_midi;
470 driver->playback_channels_audio = playback_ports;
471 driver->playback_channels_midi = playback_ports_midi;
472 driver->playback_ports = NULL;
474 driver->handle_transport_sync = transport_sync;
475 driver->client = client;
476 driver->engine = NULL;
478 if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16))
480 jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth);
481 return NULL;
483 driver->bitdepth = bitdepth;
486 if (resample_factor_up == 0)
487 resample_factor_up = resample_factor;
489 // Now open the socket, and wait for the first packet to arrive...
490 driver->sockfd = socket (PF_INET, SOCK_DGRAM, 0);
491 if (driver->sockfd == -1)
493 jack_info ("socket error");
494 return NULL;
496 address.sin_family = AF_INET;
497 address.sin_port = htons(driver->listen_port);
498 address.sin_addr.s_addr = htonl(INADDR_ANY);
499 if (bind (driver->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0)
501 jack_info("bind error");
502 return NULL;
505 driver->outsockfd = socket (PF_INET, SOCK_DGRAM, 0);
506 if (driver->sockfd == -1)
508 jack_info ("socket error");
509 return NULL;
511 driver->srcaddress_valid = 0;
513 jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header));
514 socklen_t address_size = sizeof (struct sockaddr_in);
516 jack_info ("Waiting for an incoming packet !!!");
517 jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!");
519 if (netjack_poll (driver->sockfd, 500))
520 first_pack_len = recvfrom (driver->sockfd, first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & driver->syncsource_address, &address_size);
521 else
522 first_pack_len = 0;
524 driver->srcaddress_valid = 1;
526 driver->mtu = 0;
528 if (first_pack_len == sizeof (jacknet_packet_header))
530 packet_header_ntoh (first_packet);
532 jack_info ("AutoConfig Override !!!");
533 if (driver->sample_rate != first_packet->sample_rate)
535 jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate);
536 driver->sample_rate = first_packet->sample_rate;
539 if (driver->period_size != first_packet->period_size)
541 jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size);
542 driver->period_size = first_packet->period_size;
544 if (driver->capture_channels_audio != first_packet->capture_channels_audio)
546 jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio);
547 driver->capture_channels_audio = first_packet->capture_channels_audio;
549 if (driver->capture_channels_midi != first_packet->capture_channels_midi)
551 jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi);
552 driver->capture_channels_midi = first_packet->capture_channels_midi;
554 if (driver->playback_channels_audio != first_packet->playback_channels_audio)
556 jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio);
557 driver->playback_channels_audio = first_packet->playback_channels_audio;
559 if (driver->playback_channels_midi != first_packet->playback_channels_midi)
561 jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi);
562 driver->playback_channels_midi = first_packet->playback_channels_midi;
564 driver->capture_channels = driver->capture_channels_audio + driver->capture_channels_midi;
565 driver->playback_channels = driver->playback_channels_audio + driver->playback_channels_midi;
567 driver->mtu = first_packet->mtu;
568 jack_info ("MTU is set to %d bytes", first_packet->mtu);
569 driver->latency = first_packet->latency;
572 // After possible Autoconfig: do all calculations...
573 driver->period_usecs =
574 (jack_time_t) floor ((((float) driver->period_size) / driver->sample_rate)
575 * 1000000.0f);
577 driver->net_period_down = (float) driver->period_size / (float) resample_factor;
578 driver->net_period_up = (float) driver->period_size / (float) resample_factor_up;
580 /* TODO: this seems... useles */
581 rx_bufsize = sizeof (jacknet_packet_header) + driver->net_period_down * driver->capture_channels * get_sample_size (driver->bitdepth);
582 driver->rx_buf = malloc (rx_bufsize);
583 driver->pkt_buf = malloc (rx_bufsize);
584 global_packcache = packet_cache_new (driver->latency + 5, rx_bufsize, driver->mtu);
586 jack_info ("netjack: period : up: %d / dn: %d", driver->net_period_up, driver->net_period_down);
587 jack_info ("netjack: framerate: %d", driver->sample_rate);
588 jack_info ("netjack: audio : cap: %d / pbk: %d)", driver->capture_channels_audio, driver->playback_channels_audio);
589 jack_info ("netjack: midi : cap: %d / pbk: %d)", driver->capture_channels_midi, driver->playback_channels_midi);
590 jack_info ("netjack: buffsize : rx: %d)", rx_bufsize);
591 return (jack_driver_t *) driver;
594 /* DRIVER "PLUGIN" INTERFACE */
596 jack_driver_desc_t *
597 driver_get_descriptor ()
599 jack_driver_desc_t * desc;
600 jack_driver_param_desc_t * params;
601 unsigned int i;
603 desc = calloc (1, sizeof (jack_driver_desc_t));
604 strcpy (desc->name, "net");
605 desc->nparams = 11;
607 params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
609 i = 0;
610 strcpy (params[i].name, "inchannels");
611 params[i].character = 'i';
612 params[i].type = JackDriverParamUInt;
613 params[i].value.ui = 2U;
614 strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)");
615 strcpy (params[i].long_desc, params[i].short_desc);
617 i++;
618 strcpy (params[i].name, "outchannels");
619 params[i].character = 'o';
620 params[i].type = JackDriverParamUInt;
621 params[i].value.ui = 2U;
622 strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)");
623 strcpy (params[i].long_desc, params[i].short_desc);
625 i++;
626 strcpy (params[i].name, "midi inchannels");
627 params[i].character = 'I';
628 params[i].type = JackDriverParamUInt;
629 params[i].value.ui = 1U;
630 strcpy (params[i].short_desc, "Number of midi capture channels (defaults to 1)");
631 strcpy (params[i].long_desc, params[i].short_desc);
633 i++;
634 strcpy (params[i].name, "midi outchannels");
635 params[i].character = 'O';
636 params[i].type = JackDriverParamUInt;
637 params[i].value.ui = 1U;
638 strcpy (params[i].short_desc, "Number of midi playback channels (defaults to 1)");
639 strcpy (params[i].long_desc, params[i].short_desc);
641 i++;
642 strcpy (params[i].name, "rate");
643 params[i].character = 'r';
644 params[i].type = JackDriverParamUInt;
645 params[i].value.ui = 48000U;
646 strcpy (params[i].short_desc, "Sample rate");
647 strcpy (params[i].long_desc, params[i].short_desc);
649 i++;
650 strcpy (params[i].name, "period");
651 params[i].character = 'p';
652 params[i].type = JackDriverParamUInt;
653 params[i].value.ui = 1024U;
654 strcpy (params[i].short_desc, "Frames per period");
655 strcpy (params[i].long_desc, params[i].short_desc);
657 i++;
658 strcpy (params[i].name, "listen-port");
659 params[i].character = 'l';
660 params[i].type = JackDriverParamUInt;
661 params[i].value.ui = 3000U;
662 strcpy (params[i].short_desc,
663 "The socket port we are listening on for sync packets");
664 strcpy (params[i].long_desc, params[i].short_desc);
666 i++;
667 strcpy (params[i].name, "factor");
668 params[i].character = 'f';
669 params[i].type = JackDriverParamUInt;
670 params[i].value.ui = 1U;
671 strcpy (params[i].short_desc,
672 "Factor for sample rate reduction");
673 strcpy (params[i].long_desc, params[i].short_desc);
675 i++;
676 strcpy (params[i].name, "upstream-factor");
677 params[i].character = 'u';
678 params[i].type = JackDriverParamUInt;
679 params[i].value.ui = 0U;
680 strcpy (params[i].short_desc,
681 "Factor for sample rate reduction on the upstream");
682 strcpy (params[i].long_desc, params[i].short_desc);
684 i++;
685 strcpy (params[i].name, "bit-depth");
686 params[i].character = 'b';
687 params[i].type = JackDriverParamUInt;
688 params[i].value.ui = 0U;
689 strcpy (params[i].short_desc,
690 "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)");
691 strcpy (params[i].long_desc, params[i].short_desc);
692 i++;
694 strcpy (params[i].name, "transport-sync");
695 params[i].character = 't';
696 params[i].type = JackDriverParamUInt;
697 params[i].value.ui = 1U;
698 strcpy (params[i].short_desc,
699 "Whether to slave the transport to the master transport");
700 strcpy (params[i].long_desc, params[i].short_desc);
702 desc->params = params;
704 return desc;
707 const char driver_client_name[] = "net_pcm";
709 jack_driver_t *
710 driver_initialize (jack_client_t *client, const JSList * params)
712 jack_nframes_t sample_rate = 48000;
713 jack_nframes_t resample_factor = 1;
714 jack_nframes_t period_size = 1024;
715 unsigned int capture_ports = 2;
716 unsigned int playback_ports = 2;
717 unsigned int capture_ports_midi = 1;
718 unsigned int playback_ports_midi = 1;
719 unsigned int listen_port = 3000;
720 unsigned int resample_factor_up = 0;
721 unsigned int bitdepth = 0;
722 unsigned int handle_transport_sync = 1;
723 const JSList * node;
724 const jack_driver_param_t * param;
726 for (node = params; node; node = jack_slist_next (node)) {
727 param = (const jack_driver_param_t *) node->data;
729 switch (param->character) {
731 case 'i':
732 capture_ports = param->value.ui;
733 break;
735 case 'o':
736 playback_ports = param->value.ui;
737 break;
739 case 'I':
740 capture_ports_midi = param->value.ui;
741 break;
743 case 'O':
744 playback_ports_midi = param->value.ui;
745 break;
747 case 'r':
748 sample_rate = param->value.ui;
749 break;
751 case 'p':
752 period_size = param->value.ui;
753 break;
755 case 'l':
756 listen_port = param->value.ui;
757 break;
759 case 'f':
760 resample_factor = param->value.ui;
761 break;
763 case 'u':
764 resample_factor_up = param->value.ui;
765 break;
767 case 'b':
768 bitdepth = param->value.ui;
769 break;
771 case 't':
772 handle_transport_sync = param->value.ui;
773 break;
777 return net_driver_new (client, "net_pcm", capture_ports, playback_ports,
778 capture_ports_midi, playback_ports_midi,
779 sample_rate, period_size,
780 listen_port, handle_transport_sync,
781 resample_factor, resample_factor_up, bitdepth);
784 void
785 driver_finish (jack_driver_t *driver)
787 net_driver_delete ((net_driver_t *) driver);