jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

708 lines
24KB

  1. /* -*- mode: c; c-file-style: "linux"; -*- */
  2. /*
  3. NetJack Driver
  4. Copyright (C) 2006 Torben Hohn <torbenh@gmx.de>
  5. Copyright (C) 2003 Robert Ham <rah@bash.sh>
  6. Copyright (C) 2001 Paul Davis
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $
  19. */
  20. #include <math.h>
  21. #include <stdio.h>
  22. #include <memory.h>
  23. #include <unistd.h>
  24. #include <stdlib.h>
  25. #include <errno.h>
  26. #include <stdarg.h>
  27. #include <sys/mman.h>
  28. #include <sys/poll.h>
  29. #include <jack/types.h>
  30. #include <jack/engine.h>
  31. #include <sysdeps/time.h>
  32. #include <sys/types.h>
  33. #include <sys/socket.h>
  34. #include <netinet/in.h>
  35. #include <samplerate.h>
  36. #include "net_driver.h"
  37. #include "netjack_packet.h"
  38. #undef DEBUG_WAKEUP
  39. static int sync_state = TRUE;
  40. static jack_transport_state_t last_transport_state;
  41. static int framecnt; // this is set upon reading a packet.
  42. // and will be written into the pkthdr of an outgoing packet.
  43. static int
  44. net_driver_sync_cb(jack_transport_state_t state, jack_position_t *pos, net_driver_t *driver)
  45. {
  46. int retval = sync_state;
  47. if (state == JackTransportStarting && last_transport_state != JackTransportStarting) {
  48. retval = 0;
  49. }
  50. if (state == JackTransportStarting)
  51. jack_info("Starting sync_state = %d", sync_state);
  52. last_transport_state = state;
  53. return retval;
  54. }
  55. static jack_nframes_t
  56. net_driver_wait (net_driver_t *driver, int extra_fd, int *status,
  57. float *delayed_usecs)
  58. {
  59. // ok... we wait for a packet on the socket
  60. // TODO:
  61. // we should be able to run freely if the sync source is not transmitting
  62. // especially we should be able to compensate for packet loss somehow.
  63. // but lets try this out first.
  64. //
  65. // on packet loss we should either detect an xrun or just continue running when we
  66. // think, that the sync source is not running anymore.
  67. #if 0
  68. fd_set read_fds;
  69. int res = 0;
  70. while (res == 0) {
  71. FD_ZERO(&read_fds);
  72. FD_SET(driver->sockfd, &read_fds);
  73. res = select(driver->sockfd + 1, &read_fds, NULL, NULL, NULL); // wait here until there is a packet to get
  74. }
  75. #endif
  76. socklen_t address_size = sizeof(struct sockaddr_in);
  77. int bufsize = get_sample_size(driver->bitdepth) * driver->capture_channels * driver->net_period_down + sizeof(jacknet_packet_header);
  78. jacknet_packet_header *pkthdr = (jacknet_packet_header *)driver->rx_buf;
  79. rx_again:
  80. if (!driver->srcaddress_valid) {
  81. // XXX: Somthings really bad ;)
  82. puts("!driver->srcaddress_valid");
  83. return 0;
  84. }
  85. int len = netjack_recvfrom(driver->sockfd, (char *)driver->rx_buf, bufsize,
  86. MSG_WAITALL, (struct sockaddr*) & driver->syncsource_address, &address_size, 1400);
  87. if (len != bufsize) {
  88. jack_info("wrong_packet_len: len=%d, expected=%d", len, bufsize);
  89. goto rx_again;
  90. }
  91. packet_header_ntoh(pkthdr);
  92. //driver->srcaddress_valid = 0;
  93. driver->last_wait_ust = jack_get_microseconds ();
  94. driver->engine->transport_cycle_start (driver->engine,
  95. driver->last_wait_ust);
  96. /* this driver doesn't work so well if we report a delay */
  97. *delayed_usecs = 0; /* lie about it */
  98. *status = 0;
  99. return driver->period_size;
  100. }
  101. static inline int
  102. net_driver_run_cycle (net_driver_t *driver)
  103. {
  104. jack_engine_t *engine = driver->engine;
  105. int wait_status;
  106. float delayed_usecs;
  107. jack_nframes_t nframes = net_driver_wait (driver, -1, &wait_status,
  108. &delayed_usecs);
  109. // currently there is no xrun detection.
  110. // so nframes will always be period_size.
  111. // XXX: i uncomment this code because the signature of delay()
  112. // changed samewhere in the 0.99.x series. so this is the showstopper for 0.99.0
  113. #if 0
  114. if (nframes == 0) {
  115. /* we detected an xrun and restarted: notify
  116. * clients about the delay. */
  117. engine->delay (engine, delayed_usecs);
  118. return 0;
  119. }
  120. #endif
  121. if (wait_status == 0)
  122. return engine->run_cycle (engine, nframes, delayed_usecs);
  123. if (wait_status < 0)
  124. return -1;
  125. else
  126. return 0;
  127. }
  128. static int
  129. net_driver_null_cycle (net_driver_t* driver, jack_nframes_t nframes)
  130. {
  131. //int rx_size = get_sample_size(driver->bitdepth) * driver->capture_channels * driver->net_period_down + sizeof(jacknet_packet_header);
  132. int tx_size = get_sample_size(driver->bitdepth) * driver->playback_channels * driver->net_period_up + sizeof(jacknet_packet_header);
  133. unsigned int *packet_buf, *packet_bufX;
  134. packet_buf = alloca( tx_size);
  135. jacknet_packet_header *tx_pkthdr = (jacknet_packet_header *)packet_buf;
  136. jacknet_packet_header *rx_pkthdr = (jacknet_packet_header *)driver->rx_buf;
  137. framecnt = rx_pkthdr->framecnt;
  138. driver->reply_port = rx_pkthdr->reply_port;
  139. // offset packet_bufX by the packetheader.
  140. packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
  141. tx_pkthdr->sync_state = (driver->engine->control->sync_remain <= 1);
  142. tx_pkthdr->framecnt = framecnt;
  143. // memset 0 the payload.
  144. int payload_size = get_sample_size(driver->bitdepth) * driver->playback_channels * driver->net_period_up;
  145. memset(packet_bufX, 0, payload_size);
  146. packet_header_hton(tx_pkthdr);
  147. if (driver->srcaddress_valid)
  148. if (driver->reply_port)
  149. driver->syncsource_address.sin_port = htons(driver->reply_port);
  150. netjack_sendto(driver->outsockfd, (char *)packet_buf, tx_size,
  151. 0, (struct sockaddr*)&driver->syncsource_address, sizeof(struct sockaddr_in), 1400);
  152. return 0;
  153. }
  154. static int
  155. net_driver_bufsize (net_driver_t* driver, jack_nframes_t nframes)
  156. {
  157. if (nframes != driver->period_size)
  158. return EINVAL;
  159. return 0;
  160. }
  161. static int
  162. net_driver_read (net_driver_t* driver, jack_nframes_t nframes)
  163. {
  164. //jack_default_audio_sample_t* buf;
  165. //jack_port_t *port;
  166. jack_position_t local_trans_pos;
  167. jack_transport_state_t local_trans_state;
  168. //int bufsize = get_sample_size(driver->bitdepth) * driver->capture_channels * driver->net_period_down + sizeof(jacknet_packet_header);
  169. unsigned int *packet_buf, *packet_bufX;
  170. packet_buf = driver->rx_buf;
  171. jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf;
  172. packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
  173. //packet_header_ntoh(pkthdr);
  174. // fill framecnt from pkthdr.
  175. if (pkthdr->framecnt != framecnt + 1)
  176. jack_info("bogus framecount %d", pkthdr->framecnt);
  177. framecnt = pkthdr->framecnt;
  178. driver->reply_port = pkthdr->reply_port;
  179. // check whether, we should handle the transport sync stuff, or leave trnasports untouched.
  180. if (driver->handle_transport_sync) {
  181. // read local transport info....
  182. local_trans_state = jack_transport_query(driver->client, &local_trans_pos);
  183. // Now check if we have to start or stop local transport to sync to remote...
  184. switch (pkthdr->transport_state) {
  185. case JackTransportStarting:
  186. // the master transport is starting... so we set our reply to the sync_callback;
  187. if (local_trans_state == JackTransportStopped) {
  188. jack_transport_start(driver->client);
  189. last_transport_state = JackTransportStopped;
  190. sync_state = FALSE;
  191. jack_info("locally stopped... starting...");
  192. }
  193. if (local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * nframes)) {
  194. jack_transport_locate(driver->client, (pkthdr->transport_frame + (pkthdr->latency) * nframes));
  195. last_transport_state = JackTransportRolling;
  196. sync_state = FALSE;
  197. jack_info("starting locate to %d", pkthdr->transport_frame + (pkthdr->latency)*nframes);
  198. }
  199. break;
  200. case JackTransportStopped:
  201. sync_state = TRUE;
  202. if (local_trans_pos.frame != (pkthdr->transport_frame)) {
  203. jack_transport_locate(driver->client, (pkthdr->transport_frame));
  204. jack_info("transport is stopped locate to %d", pkthdr->transport_frame);
  205. }
  206. if (local_trans_state != JackTransportStopped)
  207. jack_transport_stop(driver->client);
  208. break;
  209. case JackTransportRolling:
  210. sync_state = TRUE;
  211. // if(local_trans_pos.frame != (pkthdr->transport_frame + (pkthdr->latency) * nframes)) {
  212. // jack_transport_locate(driver->client, (pkthdr->transport_frame + (pkthdr->latency + 2) * nframes));
  213. // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*nframes);
  214. // }
  215. if (local_trans_state != JackTransportRolling)
  216. jack_transport_start(driver->client);
  217. break;
  218. case JackTransportLooping:
  219. break;
  220. }
  221. }
  222. render_payload_to_jack_ports(driver->bitdepth, packet_bufX, driver->net_period_down, driver->capture_ports, driver->capture_srcs, nframes);
  223. return 0;
  224. }
  225. static int
  226. net_driver_write (net_driver_t* driver, jack_nframes_t nframes)
  227. {
  228. uint32_t *packet_buf, *packet_bufX;
  229. int packet_size = get_sample_size(driver->bitdepth) * driver->playback_channels * driver->net_period_up + sizeof(jacknet_packet_header);
  230. packet_buf = alloca(packet_size);
  231. jacknet_packet_header *pkthdr = (jacknet_packet_header *)packet_buf;
  232. // offset packet_bufX by the packetheader.
  233. packet_bufX = packet_buf + sizeof(jacknet_packet_header) / sizeof(jack_default_audio_sample_t);
  234. pkthdr->sync_state = (driver->engine->control->sync_remain <= 1);
  235. pkthdr->framecnt = framecnt;
  236. render_jack_ports_to_payload(driver->bitdepth, driver->playback_ports, driver->playback_srcs, nframes, packet_bufX, driver->net_period_up);
  237. packet_header_hton(pkthdr);
  238. if (driver->srcaddress_valid)
  239. if (driver->reply_port)
  240. driver->syncsource_address.sin_port = htons(driver->reply_port);
  241. netjack_sendto(driver->outsockfd, (char *)packet_buf, packet_size,
  242. 0, (struct sockaddr*)&driver->syncsource_address, sizeof(struct sockaddr_in), 1400);
  243. return 0;
  244. }
  245. static int
  246. net_driver_attach (net_driver_t *driver)
  247. {
  248. puts ("net_driver_attach");
  249. jack_port_t * port;
  250. char buf[32];
  251. unsigned int chn;
  252. int port_flags;
  253. driver->engine->set_buffer_size (driver->engine, driver->period_size);
  254. driver->engine->set_sample_rate (driver->engine, driver->sample_rate);
  255. if (driver->handle_transport_sync)
  256. jack_set_sync_callback(driver->client, (JackSyncCallback) net_driver_sync_cb, driver);
  257. port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal;
  258. for (chn = 0; chn < driver->capture_channels; chn++) {
  259. snprintf (buf, sizeof(buf) - 1, "capture_%u", chn + 1);
  260. port = jack_port_register (driver->client, buf,
  261. JACK_DEFAULT_AUDIO_TYPE,
  262. port_flags, 0);
  263. if (!port) {
  264. jack_error ("DUMMY: cannot register port for %s", buf);
  265. break;
  266. }
  267. driver->capture_ports =
  268. jack_slist_append (driver->capture_ports, port);
  269. driver->capture_srcs = jack_slist_append(driver->capture_srcs, src_new(SRC_LINEAR, 1, NULL));
  270. }
  271. port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal;
  272. for (chn = 0; chn < driver->playback_channels; chn++) {
  273. snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1);
  274. port = jack_port_register (driver->client, buf,
  275. JACK_DEFAULT_AUDIO_TYPE,
  276. port_flags, 0);
  277. if (!port) {
  278. jack_error ("DUMMY: cannot register port for %s", buf);
  279. break;
  280. }
  281. driver->playback_ports =
  282. jack_slist_append (driver->playback_ports, port);
  283. driver->playback_srcs = jack_slist_append(driver->playback_srcs, src_new(SRC_LINEAR, 1, NULL));
  284. }
  285. jack_activate (driver->client);
  286. return 0;
  287. }
  288. static int
  289. net_driver_detach (net_driver_t *driver)
  290. {
  291. JSList * node;
  292. if (driver->engine == 0)
  293. return 0;
  294. //#if 0
  295. for (node = driver->capture_ports; node; node = jack_slist_next (node))
  296. jack_port_unregister (driver->client,
  297. ((jack_port_t *) node->data));
  298. jack_slist_free (driver->capture_ports);
  299. driver->capture_ports = NULL;
  300. //#endif
  301. for (node = driver->playback_ports; node; node = jack_slist_next (node))
  302. jack_port_unregister (driver->client,
  303. ((jack_port_t *) node->data));
  304. jack_slist_free (driver->playback_ports);
  305. driver->playback_ports = NULL;
  306. return 0;
  307. }
  308. static void
  309. net_driver_delete (net_driver_t *driver)
  310. {
  311. jack_driver_nt_finish ((jack_driver_nt_t *) driver);
  312. free (driver);
  313. }
  314. static jack_driver_t *
  315. net_driver_new (jack_client_t * client,
  316. char *name,
  317. unsigned int capture_ports,
  318. unsigned int playback_ports,
  319. jack_nframes_t sample_rate,
  320. jack_nframes_t period_size,
  321. unsigned int listen_port,
  322. unsigned int transport_sync,
  323. unsigned int resample_factor,
  324. unsigned int resample_factor_up,
  325. unsigned int bitdepth)
  326. {
  327. net_driver_t * driver;
  328. struct sockaddr_in address;
  329. jack_info("creating net driver ... %s|%" PRIu32 "|%" PRIu32
  330. "|%u|%u|%u|transport_sync:%u", name, sample_rate, period_size, listen_port,
  331. capture_ports, playback_ports, transport_sync);
  332. driver = (net_driver_t *) calloc (1, sizeof (net_driver_t));
  333. jack_driver_nt_init ((jack_driver_nt_t *) driver);
  334. driver->write = (JackDriverWriteFunction) net_driver_write;
  335. driver->read = (JackDriverReadFunction) net_driver_read;
  336. driver->null_cycle = (JackDriverNullCycleFunction) net_driver_null_cycle;
  337. driver->nt_attach = (JackDriverNTAttachFunction) net_driver_attach;
  338. driver->nt_detach = (JackDriverNTDetachFunction) net_driver_detach;
  339. driver->nt_bufsize = (JackDriverNTBufSizeFunction) net_driver_bufsize;
  340. driver->nt_run_cycle = (JackDriverNTRunCycleFunction) net_driver_run_cycle;
  341. // Fill in driver values.
  342. // might be subject to autoconfig...
  343. // so dont calculate anything with them...
  344. driver->sample_rate = sample_rate;
  345. driver->period_size = period_size;
  346. driver->listen_port = listen_port;
  347. driver->last_wait_ust = 0;
  348. driver->capture_channels = capture_ports;
  349. driver->capture_ports = NULL;
  350. driver->playback_channels = playback_ports;
  351. driver->playback_ports = NULL;
  352. driver->handle_transport_sync = transport_sync;
  353. driver->client = client;
  354. driver->engine = NULL;
  355. if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16)) {
  356. jack_info("Invalid bitdepth: %d (8,16 or 0 for float) !!!", bitdepth);
  357. return NULL;
  358. }
  359. driver->bitdepth = bitdepth;
  360. if (resample_factor_up == 0)
  361. resample_factor_up = resample_factor;
  362. // Now open the socket, and wait for the first packet to arrive...
  363. driver->sockfd = socket(PF_INET, SOCK_DGRAM, 0);
  364. if (driver->sockfd == -1) {
  365. jack_info("socket error");
  366. return NULL;
  367. }
  368. address.sin_family = AF_INET;
  369. address.sin_port = htons(driver->listen_port);
  370. address.sin_addr.s_addr = htonl(INADDR_ANY);
  371. if (bind(driver->sockfd, (struct sockaddr *) &address, sizeof(address)) < 0) {
  372. jack_info("bind error");
  373. return NULL;
  374. }
  375. driver->outsockfd = socket(PF_INET, SOCK_DGRAM, 0);
  376. if (driver->sockfd == -1) {
  377. jack_info("socket error");
  378. return NULL;
  379. }
  380. driver->srcaddress_valid = 0;
  381. jacknet_packet_header *first_packet = alloca(sizeof(jacknet_packet_header));
  382. socklen_t address_size = sizeof(struct sockaddr_in);
  383. jack_info("Waiting for an incoming packet !!!");
  384. jack_info("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!");
  385. int first_pack_len = recvfrom(driver->sockfd, first_packet, sizeof(jacknet_packet_header), 0, (struct sockaddr*) & driver->syncsource_address, &address_size);
  386. driver->srcaddress_valid = 1;
  387. jack_info("first_pack_len=%d", first_pack_len);
  388. // A packet is here.... If it wasnt the old trigger packet containing only 'x' evaluate the autoconf data...
  389. driver->mtu = 0;
  390. if (first_pack_len == sizeof(jacknet_packet_header)) {
  391. packet_header_ntoh(first_packet);
  392. jack_info("AutoConfig Override !!!");
  393. if (driver->sample_rate != first_packet->sample_rate) {
  394. jack_info("AutoConfig Override: sample_rate = %d", first_packet->sample_rate);
  395. driver->sample_rate = first_packet->sample_rate;
  396. }
  397. if (driver->period_size != first_packet->period_size) {
  398. jack_info("AutoConfig Override: period_size = %d", first_packet->period_size);
  399. driver->period_size = first_packet->period_size;
  400. }
  401. driver->mtu = first_packet->mtu;
  402. driver->latency = first_packet->latency;
  403. }
  404. // After possible Autoconfig: do all calculations...
  405. driver->period_usecs =
  406. (jack_time_t) floor ((((float) driver->period_size) / driver->sample_rate)
  407. * 1000000.0f);
  408. driver->net_period_down = (float) driver->period_size / (float) resample_factor;
  409. driver->net_period_up = (float) driver->period_size / (float) resample_factor_up;
  410. driver->rx_buf = malloc(sizeof(jacknet_packet_header) + driver->net_period_down * driver->capture_channels * get_sample_size(driver->bitdepth));
  411. // XXX: dont need it when packet size < mtu
  412. driver->pkt_buf = malloc(sizeof(jacknet_packet_header) + driver->net_period_down * driver->capture_channels * get_sample_size(driver->bitdepth));
  413. int rx_bufsize = sizeof(jacknet_packet_header) + driver->net_period_down * driver->capture_channels * get_sample_size(driver->bitdepth);
  414. global_packcache = packet_cache_new(driver->latency + 5, rx_bufsize, 1400);
  415. jack_info("net_period: (up:%d/dn:%d)", driver->net_period_up, driver->net_period_down);
  416. return (jack_driver_t *) driver;
  417. }
  418. /* DRIVER "PLUGIN" INTERFACE */
  419. jack_driver_desc_t *
  420. driver_get_descriptor ()
  421. {
  422. jack_driver_desc_t * desc;
  423. jack_driver_param_desc_t * params;
  424. unsigned int i;
  425. desc = calloc (1, sizeof (jack_driver_desc_t));
  426. strcpy (desc->name, "net");
  427. desc->nparams = 9;
  428. params = calloc (desc->nparams, sizeof (jack_driver_param_desc_t));
  429. i = 0;
  430. strcpy (params[i].name, "inchannels");
  431. params[i].character = 'i';
  432. params[i].type = JackDriverParamUInt;
  433. params[i].value.ui = 2U;
  434. strcpy (params[i].short_desc, "Number of capture channels (defaults to 2)");
  435. strcpy (params[i].long_desc, params[i].short_desc);
  436. i++;
  437. strcpy (params[i].name, "outchannels");
  438. params[i].character = 'o';
  439. params[i].type = JackDriverParamUInt;
  440. params[i].value.ui = 2U;
  441. strcpy (params[i].short_desc, "Number of playback channels (defaults to 2)");
  442. strcpy (params[i].long_desc, params[i].short_desc);
  443. i++;
  444. strcpy (params[i].name, "rate");
  445. params[i].character = 'r';
  446. params[i].type = JackDriverParamUInt;
  447. params[i].value.ui = 48000U;
  448. strcpy (params[i].short_desc, "Sample rate");
  449. strcpy (params[i].long_desc, params[i].short_desc);
  450. i++;
  451. strcpy (params[i].name, "period");
  452. params[i].character = 'p';
  453. params[i].type = JackDriverParamUInt;
  454. params[i].value.ui = 1024U;
  455. strcpy (params[i].short_desc, "Frames per period");
  456. strcpy (params[i].long_desc, params[i].short_desc);
  457. i++;
  458. strcpy (params[i].name, "listen-port");
  459. params[i].character = 'l';
  460. params[i].type = JackDriverParamUInt;
  461. params[i].value.ui = 3000U;
  462. strcpy (params[i].short_desc,
  463. "The socket port we are listening on for sync packets");
  464. strcpy (params[i].long_desc, params[i].short_desc);
  465. i++;
  466. strcpy (params[i].name, "factor");
  467. params[i].character = 'f';
  468. params[i].type = JackDriverParamUInt;
  469. params[i].value.ui = 1U;
  470. strcpy (params[i].short_desc,
  471. "Factor for sample rate reduction");
  472. strcpy (params[i].long_desc, params[i].short_desc);
  473. i++;
  474. strcpy (params[i].name, "upstream-factor");
  475. params[i].character = 'u';
  476. params[i].type = JackDriverParamUInt;
  477. params[i].value.ui = 0U;
  478. strcpy (params[i].short_desc,
  479. "Factor for sample rate reduction on the upstream");
  480. strcpy (params[i].long_desc, params[i].short_desc);
  481. i++;
  482. strcpy (params[i].name, "bit-depth");
  483. params[i].character = 'b';
  484. params[i].type = JackDriverParamUInt;
  485. params[i].value.ui = 0U;
  486. strcpy (params[i].short_desc,
  487. "Sample bit-depth (0 for float, 8 for 8bit and 16 for 16bit)");
  488. strcpy (params[i].long_desc, params[i].short_desc);
  489. i++;
  490. strcpy (params[i].name, "transport-sync");
  491. params[i].character = 't';
  492. params[i].type = JackDriverParamUInt;
  493. params[i].value.ui = 1U;
  494. strcpy (params[i].short_desc,
  495. "Whether to slave the transport to the master transport");
  496. strcpy (params[i].long_desc, params[i].short_desc);
  497. desc->params = params;
  498. return desc;
  499. }
  500. const char driver_client_name[] = "net_pcm";
  501. jack_driver_t *
  502. driver_initialize (jack_client_t *client, const JSList * params)
  503. {
  504. jack_nframes_t sample_rate = 48000;
  505. jack_nframes_t resample_factor = 1;
  506. jack_nframes_t period_size = 1024;
  507. unsigned int capture_ports = 2;
  508. unsigned int playback_ports = 2;
  509. unsigned int listen_port = 3000;
  510. unsigned int resample_factor_up = 0;
  511. unsigned int bitdepth = 0;
  512. unsigned int handle_transport_sync = 1;
  513. const JSList * node;
  514. const jack_driver_param_t * param;
  515. for (node = params; node; node = jack_slist_next (node)) {
  516. param = (const jack_driver_param_t *) node->data;
  517. switch (param->character) {
  518. case 'i':
  519. capture_ports = param->value.ui;
  520. break;
  521. case 'o':
  522. playback_ports = param->value.ui;
  523. break;
  524. case 'r':
  525. sample_rate = param->value.ui;
  526. break;
  527. case 'p':
  528. period_size = param->value.ui;
  529. break;
  530. case 'l':
  531. listen_port = param->value.ui;
  532. break;
  533. case 'f':
  534. resample_factor = param->value.ui;
  535. break;
  536. case 'u':
  537. resample_factor_up = param->value.ui;
  538. break;
  539. case 'b':
  540. bitdepth = param->value.ui;
  541. break;
  542. case 't':
  543. handle_transport_sync = param->value.ui;
  544. break;
  545. }
  546. }
  547. return net_driver_new (client, "net_pcm", capture_ports,
  548. playback_ports, sample_rate, period_size,
  549. listen_port, handle_transport_sync,
  550. resample_factor, resample_factor_up, bitdepth);
  551. }
  552. void
  553. driver_finish (jack_driver_t *driver)
  554. {
  555. net_driver_delete ((net_driver_t *) driver);
  556. }