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.

709 lines
20KB

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