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.

1477 lines
34KB

  1. /*
  2. Sun Audio API driver for Jack
  3. Copyright (C) 2008 Jacob Meuser <jakemsr@sdf.lonestar.org>
  4. Based heavily on oss_driver.c which came with the following
  5. copyright notice.
  6. Copyright (C) 2003-2007 Jussi Laako <jussi@sonarnerd.net>
  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., 59 Temple Place, Suite 330, Boston,
  18. MA 02111-1307 USA
  19. */
  20. #include <config.h>
  21. #ifndef _REENTRANT
  22. #define _REENTRANT
  23. #endif
  24. #ifndef _THREAD_SAFE
  25. #define _THREAD_SAFE
  26. #endif
  27. #include <sys/stat.h>
  28. #include <sys/types.h>
  29. #include <sys/ioctl.h>
  30. #include <sys/audioio.h>
  31. #include <poll.h>
  32. #include <unistd.h>
  33. #include <pthread.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <stdio.h>
  37. #include <fcntl.h>
  38. #include <errno.h>
  39. #include <math.h>
  40. #include <float.h>
  41. #include <stdarg.h>
  42. #include <getopt.h>
  43. #include <jack/types.h>
  44. #include <jack/thread.h>
  45. #include "internal.h"
  46. #include "engine.h"
  47. #include <sysdeps/time.h>
  48. #include "sun_driver.h"
  49. #define SUN_DRIVER_N_PARAMS 11
  50. const static jack_driver_param_desc_t sun_params[SUN_DRIVER_N_PARAMS] = {
  51. { "rate",
  52. 'r',
  53. JackDriverParamUInt,
  54. { .ui = SUN_DRIVER_DEF_FS },
  55. "sample rate",
  56. "sample rate"
  57. },
  58. { "period",
  59. 'p',
  60. JackDriverParamUInt,
  61. { .ui = SUN_DRIVER_DEF_BLKSIZE },
  62. "period size",
  63. "period size"
  64. },
  65. { "nperiods",
  66. 'n',
  67. JackDriverParamUInt,
  68. { .ui = SUN_DRIVER_DEF_NPERIODS },
  69. "number of periods in buffer",
  70. "number of periods in buffer"
  71. },
  72. { "wordlength",
  73. 'w',
  74. JackDriverParamInt,
  75. { .i = SUN_DRIVER_DEF_BITS },
  76. "word length",
  77. "word length"
  78. },
  79. { "inchannels",
  80. 'i',
  81. JackDriverParamUInt,
  82. { .ui = SUN_DRIVER_DEF_INS },
  83. "capture channels",
  84. "capture channels"
  85. },
  86. { "outchannels",
  87. 'o',
  88. JackDriverParamUInt,
  89. { .ui = SUN_DRIVER_DEF_OUTS },
  90. "playback channels",
  91. "playback channels"
  92. },
  93. { "capture",
  94. 'C',
  95. JackDriverParamString,
  96. { .str = SUN_DRIVER_DEF_DEV },
  97. "input device",
  98. "input device"
  99. },
  100. { "playback",
  101. 'P',
  102. JackDriverParamString,
  103. { .str = SUN_DRIVER_DEF_DEV },
  104. "output device",
  105. "output device"
  106. },
  107. { "ignorehwbuf",
  108. 'b',
  109. JackDriverParamBool,
  110. { },
  111. "ignore hardware period size",
  112. "ignore hardware period size"
  113. },
  114. { "input latency",
  115. 'I',
  116. JackDriverParamUInt,
  117. { .ui = 0 },
  118. "system input latency",
  119. "system input latency"
  120. },
  121. { "output latency",
  122. 'O',
  123. JackDriverParamUInt,
  124. { .ui = 0 },
  125. "system output latency",
  126. "system output latency"
  127. }
  128. };
  129. /* internal functions */
  130. static void
  131. set_period_size (sun_driver_t *driver, jack_nframes_t new_period_size)
  132. {
  133. driver->period_size = new_period_size;
  134. driver->period_usecs =
  135. ((double) driver->period_size /
  136. (double) driver->sample_rate) * 1e6;
  137. driver->last_wait_ust = 0;
  138. driver->iodelay = 0.0F;
  139. driver->poll_timeout = (int)(driver->period_usecs / 666);
  140. }
  141. static void
  142. sun_driver_write_silence (sun_driver_t *driver, jack_nframes_t nframes)
  143. {
  144. size_t localsize;
  145. ssize_t io_res;
  146. void *localbuf;
  147. localsize = nframes * driver->sample_bytes * driver->playback_channels;
  148. localbuf = malloc(localsize);
  149. if (localbuf == NULL)
  150. {
  151. jack_error("sun_driver: malloc() failed: %s@%i",
  152. __FILE__, __LINE__);
  153. return;
  154. }
  155. bzero(localbuf, localsize);
  156. io_res = write(driver->outfd, localbuf, localsize);
  157. if (io_res < (ssize_t) localsize)
  158. {
  159. jack_error("sun_driver: write() failed: %s: "
  160. "count=%d/%d: %s@%i", strerror(errno), io_res,
  161. localsize, __FILE__, __LINE__);
  162. }
  163. free(localbuf);
  164. }
  165. static void
  166. sun_driver_read_silence (sun_driver_t *driver, jack_nframes_t nframes)
  167. {
  168. size_t localsize;
  169. ssize_t io_res;
  170. void *localbuf;
  171. localsize = nframes * driver->sample_bytes * driver->capture_channels;
  172. localbuf = malloc(localsize);
  173. if (localbuf == NULL)
  174. {
  175. jack_error("sun_driver: malloc() failed: %s@%i",
  176. __FILE__, __LINE__);
  177. return;
  178. }
  179. io_res = read(driver->infd, localbuf, localsize);
  180. if (io_res < (ssize_t) localsize)
  181. {
  182. jack_error("sun_driver: read() failed: %s: "
  183. "count=%d/%d: %s@%i", strerror(errno), io_res,
  184. localsize, __FILE__, __LINE__);
  185. }
  186. free(localbuf);
  187. }
  188. static jack_nframes_t
  189. sun_driver_wait (sun_driver_t *driver, int *status, float *iodelay)
  190. {
  191. audio_info_t auinfo;
  192. struct pollfd pfd[2];
  193. nfds_t nfds;
  194. float delay;
  195. jack_time_t poll_enter;
  196. jack_time_t poll_ret;
  197. int need_capture = 0;
  198. int need_playback = 0;
  199. int capture_errors = 0;
  200. int playback_errors = 0;
  201. int capture_seek;
  202. int playback_seek;
  203. *status = -1;
  204. *iodelay = 0;
  205. pfd[0].fd = driver->infd;
  206. pfd[0].events = POLLIN;
  207. if (driver->infd >= 0)
  208. need_capture = 1;
  209. pfd[1].fd = driver->outfd;
  210. pfd[1].events = POLLOUT;
  211. if (driver->outfd >= 0)
  212. need_playback = 1;
  213. poll_enter = driver->engine->get_microseconds();
  214. if (poll_enter > driver->poll_next)
  215. {
  216. /* late. don't count as wakeup delay. */
  217. driver->poll_next = 0;
  218. }
  219. while (need_capture || need_playback)
  220. {
  221. nfds = poll(pfd, 2, driver->poll_timeout);
  222. if ( nfds == -1 ||
  223. ((pfd[0].revents | pfd[1].revents) &
  224. (POLLERR | POLLHUP | POLLNVAL)) )
  225. {
  226. jack_error("sun_driver: poll() error: %s: %s@%i",
  227. strerror(errno), __FILE__, __LINE__);
  228. *status = -3;
  229. return 0;
  230. }
  231. if (nfds == 0)
  232. {
  233. jack_error("sun_driver: poll() timeout: %s@%i",
  234. __FILE__, __LINE__);
  235. *status = -5;
  236. return 0;
  237. }
  238. if (need_capture && (pfd[0].revents & POLLIN))
  239. {
  240. need_capture = 0;
  241. pfd[0].fd = -1;
  242. }
  243. if (need_playback && (pfd[1].revents & POLLOUT))
  244. {
  245. need_playback = 0;
  246. pfd[1].fd = -1;
  247. }
  248. }
  249. poll_ret = driver->engine->get_microseconds();
  250. if (driver->poll_next && poll_ret > driver->poll_next)
  251. *iodelay = poll_ret - driver->poll_next;
  252. driver->poll_last = poll_ret;
  253. driver->poll_next = poll_ret + driver->period_usecs;
  254. driver->engine->transport_cycle_start(driver->engine, poll_ret);
  255. #if defined(AUDIO_RERROR) && defined(AUDIO_PERROR)
  256. /* low level error reporting and recovery. recovery is necessary
  257. * when doing both playback and capture and using AUMODE_PLAY,
  258. * because we process one period of both playback and capture data
  259. * in each cycle, and we wait in each cycle for that to be possible.
  260. * for example, playback will continuously underrun if it underruns
  261. * and we have to wait for capture data to become available
  262. * before we can write enough playback data to catch up.
  263. */
  264. if (driver->infd >= 0)
  265. {
  266. if (ioctl(driver->infd, AUDIO_RERROR, &capture_errors) < 0)
  267. {
  268. jack_error("sun_driver: AUDIO_RERROR failed: %s: %s@%i",
  269. strerror(errno), __FILE__, __LINE__);
  270. return 0;
  271. }
  272. capture_errors -= driver->capture_drops;
  273. driver->capture_drops += capture_errors;
  274. }
  275. if (capture_errors > 0)
  276. {
  277. delay = (capture_errors * 1000.0) / driver->sample_rate;
  278. printf("sun_driver: capture xrun of %d frames (%f msec)\n",
  279. capture_errors, delay);
  280. }
  281. if (driver->outfd >= 0)
  282. {
  283. if (ioctl(driver->outfd, AUDIO_PERROR, &playback_errors) < 0)
  284. {
  285. jack_error("sun_driver: AUDIO_PERROR failed: %s: %s@%i",
  286. strerror(errno), __FILE__, __LINE__);
  287. return 0;
  288. }
  289. playback_errors -= driver->playback_drops;
  290. driver->playback_drops += playback_errors;
  291. }
  292. if (playback_errors > 0)
  293. {
  294. delay = (playback_errors * 1000.0) / driver->sample_rate;
  295. printf("sun_driver: playback xrun of %d frames (%f msec)\n",
  296. playback_errors, delay);
  297. }
  298. if ((driver->outfd >= 0 && driver->infd >= 0) &&
  299. (capture_errors || playback_errors))
  300. {
  301. if (ioctl(driver->infd, AUDIO_GETINFO, &auinfo) < 0)
  302. {
  303. jack_error("sun_driver: AUDIO_GETINFO failed: %s: "
  304. "%s@%i", strerror(errno), __FILE__, __LINE__);
  305. return 0;
  306. }
  307. capture_seek = auinfo.record.seek;
  308. if (driver->infd == driver->outfd)
  309. playback_seek = auinfo.play.seek;
  310. else
  311. {
  312. if (ioctl(driver->outfd, AUDIO_GETINFO, &auinfo) < 0)
  313. {
  314. jack_error("sun_driver: AUDIO_GETINFO failed: "
  315. "%s: %s@%i", strerror(errno),
  316. __FILE__, __LINE__);
  317. return 0;
  318. }
  319. playback_seek = auinfo.play.seek;
  320. }
  321. capture_seek /= driver->capture_channels *
  322. driver->sample_bytes;
  323. playback_seek /= driver->playback_channels *
  324. driver->sample_bytes;
  325. if (playback_seek == driver->period_size &&
  326. capture_seek == driver->period_size &&
  327. playback_errors)
  328. {
  329. /* normally, 1 period in each buffer is exactly
  330. * what we want, but if there was an error then
  331. * we effectively have 0 periods in the playback
  332. * buffer, because the period in the buffer will
  333. * be used to catch up to realtime.
  334. */
  335. printf("sun_driver: writing %d frames of silence "
  336. "to correct I/O sync\n", driver->period_size);
  337. sun_driver_write_silence(driver, driver->period_size);
  338. }
  339. else if (capture_errors && playback_errors)
  340. {
  341. /* serious delay. we've lost the ability to
  342. * write capture_errors frames to catch up on
  343. * playback.
  344. */
  345. printf("sun_driver: writing %d frames of silence "
  346. "to correct I/O sync\n", capture_errors);
  347. sun_driver_write_silence(driver, capture_errors);
  348. }
  349. }
  350. #endif // AUDIO_RERROR && AUDIO_PERROR
  351. driver->last_wait_ust = poll_ret;
  352. *status = 0;
  353. return driver->period_size;
  354. }
  355. static inline int
  356. sun_driver_run_cycle (sun_driver_t *driver)
  357. {
  358. jack_nframes_t nframes;
  359. jack_time_t now;
  360. int wait_status;
  361. float iodelay;
  362. nframes = sun_driver_wait (driver, &wait_status, &iodelay);
  363. if (wait_status < 0)
  364. {
  365. switch (wait_status)
  366. {
  367. case -3:
  368. /* poll() error */
  369. return -1;
  370. case -5:
  371. /* poll() timeout */
  372. now = driver->engine->get_microseconds();
  373. if (now > driver->poll_next)
  374. {
  375. iodelay = now - driver->poll_next;
  376. driver->poll_next = now + driver->period_usecs;
  377. driver->engine->delay(driver->engine, iodelay);
  378. printf("sun_driver: iodelay = %f\n", iodelay);
  379. }
  380. break;
  381. default:
  382. /* any other fatal error */
  383. return -1;
  384. }
  385. }
  386. return driver->engine->run_cycle(driver->engine, nframes, iodelay);
  387. }
  388. static void
  389. copy_and_convert_in (jack_sample_t *dst, void *src,
  390. size_t nframes, int channel, int chcount, int bits)
  391. {
  392. int srcidx;
  393. int dstidx;
  394. signed short *s16src = (signed short *) src;
  395. signed int *s32src = (signed int *) src;
  396. double *f64src = (double *) src;
  397. jack_sample_t scale;
  398. srcidx = channel;
  399. switch (bits)
  400. {
  401. case 16:
  402. scale = 1.0f / 0x7fff;
  403. for (dstidx = 0; dstidx < nframes; dstidx++)
  404. {
  405. dst[dstidx] = (jack_sample_t)
  406. s16src[srcidx] * scale;
  407. srcidx += chcount;
  408. }
  409. break;
  410. case 24:
  411. scale = 1.0f / 0x7fffff;
  412. for (dstidx = 0; dstidx < nframes; dstidx++)
  413. {
  414. dst[dstidx] = (jack_sample_t)
  415. s32src[srcidx] * scale;
  416. srcidx += chcount;
  417. }
  418. break;
  419. case 32:
  420. scale = 1.0f / 0x7fffffff;
  421. for (dstidx = 0; dstidx < nframes; dstidx++)
  422. {
  423. dst[dstidx] = (jack_sample_t)
  424. s32src[srcidx] * scale;
  425. srcidx += chcount;
  426. }
  427. break;
  428. case 64:
  429. for (dstidx = 0; dstidx < nframes; dstidx++)
  430. {
  431. dst[dstidx] = (jack_sample_t) f64src[srcidx];
  432. srcidx += chcount;
  433. }
  434. break;
  435. }
  436. }
  437. static void
  438. copy_and_convert_out (void *dst, jack_sample_t *src,
  439. size_t nframes, int channel, int chcount, int bits)
  440. {
  441. int srcidx;
  442. int dstidx;
  443. signed short *s16dst = (signed short *) dst;
  444. signed int *s32dst = (signed int *) dst;
  445. double *f64dst = (double *) dst;
  446. jack_sample_t scale;
  447. dstidx = channel;
  448. switch (bits)
  449. {
  450. case 16:
  451. scale = 0x7fff;
  452. for (srcidx = 0; srcidx < nframes; srcidx++)
  453. {
  454. s16dst[dstidx] = (signed short)
  455. (src[srcidx] >= 0.0f) ?
  456. (src[srcidx] * scale + 0.5f) :
  457. (src[srcidx] * scale - 0.5f);
  458. dstidx += chcount;
  459. }
  460. break;
  461. case 24:
  462. scale = 0x7fffff;
  463. for (srcidx = 0; srcidx < nframes; srcidx++)
  464. {
  465. s32dst[dstidx] = (signed int)
  466. (src[srcidx] >= 0.0f) ?
  467. (src[srcidx] * scale + 0.5f) :
  468. (src[srcidx] * scale - 0.5f);
  469. dstidx += chcount;
  470. }
  471. break;
  472. case 32:
  473. scale = 0x7fffffff;
  474. for (srcidx = 0; srcidx < nframes; srcidx++)
  475. {
  476. s32dst[dstidx] = (signed int)
  477. (src[srcidx] >= 0.0f) ?
  478. (src[srcidx] * scale + 0.5f) :
  479. (src[srcidx] * scale - 0.5f);
  480. dstidx += chcount;
  481. }
  482. break;
  483. case 64:
  484. for (srcidx = 0; srcidx < nframes; srcidx++)
  485. {
  486. f64dst[dstidx] = (double) src[srcidx];
  487. dstidx += chcount;
  488. }
  489. break;
  490. }
  491. }
  492. /* jack driver interface */
  493. static int
  494. sun_driver_attach (sun_driver_t *driver)
  495. {
  496. int port_flags;
  497. int channel;
  498. char channel_name[64];
  499. jack_port_t *port;
  500. jack_latency_range_t range;
  501. if (driver->engine->set_buffer_size(driver->engine, driver->period_size)) {
  502. jack_error ("sun_driver: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  503. return -1;
  504. }
  505. driver->engine->set_sample_rate(driver->engine, driver->sample_rate);
  506. port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
  507. for (channel = 0; channel < driver->capture_channels; channel++)
  508. {
  509. snprintf(channel_name, sizeof(channel_name),
  510. "capture_%u", channel + 1);
  511. port = jack_port_register(driver->client, channel_name,
  512. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  513. if (port == NULL)
  514. {
  515. jack_error("sun_driver: cannot register port for %s: "
  516. "%s@%i", channel_name, __FILE__, __LINE__);
  517. break;
  518. }
  519. range.min = range.max = driver->period_size + driver->sys_in_latency;
  520. jack_port_set_latency_range(port, JackCaptureLatency, &range);
  521. driver->capture_ports =
  522. jack_slist_append(driver->capture_ports, port);
  523. }
  524. port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
  525. for (channel = 0; channel < driver->playback_channels; channel++)
  526. {
  527. snprintf(channel_name, sizeof(channel_name),
  528. "playback_%u", channel + 1);
  529. port = jack_port_register(driver->client, channel_name,
  530. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  531. if (port == NULL)
  532. {
  533. jack_error("sun_driver: cannot register port for "
  534. "%s: %s@%i", channel_name, __FILE__, __LINE__);
  535. break;
  536. }
  537. range.min = range.max = driver->period_size + driver->sys_out_latency;
  538. jack_port_set_latency_range(port, JackPlaybackLatency, &range);
  539. driver->playback_ports =
  540. jack_slist_append(driver->playback_ports, port);
  541. }
  542. return jack_activate(driver->client);
  543. }
  544. static int
  545. sun_driver_detach (sun_driver_t *driver)
  546. {
  547. JSList *node;
  548. if (driver->engine == NULL)
  549. return 0;
  550. node = driver->capture_ports;
  551. while (node != NULL)
  552. {
  553. jack_port_unregister(driver->client,
  554. ((jack_port_t *) node->data));
  555. node = jack_slist_next(node);
  556. }
  557. jack_slist_free(driver->capture_ports);
  558. driver->capture_ports = NULL;
  559. node = driver->playback_ports;
  560. while (node != NULL)
  561. {
  562. jack_port_unregister(driver->client,
  563. ((jack_port_t *) node->data));
  564. node = jack_slist_next(node);
  565. }
  566. jack_slist_free(driver->playback_ports);
  567. driver->playback_ports = NULL;
  568. return 0;
  569. }
  570. static int
  571. sun_driver_start (sun_driver_t *driver)
  572. {
  573. audio_info_t audio_if;
  574. if (driver->infd >= 0)
  575. {
  576. #if defined(AUDIO_FLUSH)
  577. if (ioctl(driver->infd, AUDIO_FLUSH, NULL) < 0)
  578. {
  579. jack_error("sun_driver: capture flush failed: %s: "
  580. "%s@%i", strerror(errno), __FILE__, __LINE__);
  581. return -1;
  582. }
  583. #endif
  584. AUDIO_INITINFO(&audio_if);
  585. audio_if.record.pause = 1;
  586. if (driver->outfd == driver->infd)
  587. audio_if.play.pause = 1;
  588. if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
  589. {
  590. jack_error("sun_driver: pause capture failed: %s: "
  591. "%s@%i", strerror(errno), __FILE__, __LINE__);
  592. return -1;
  593. }
  594. }
  595. if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
  596. {
  597. #if defined(AUDIO_FLUSH)
  598. if (ioctl(driver->outfd, AUDIO_FLUSH, NULL) < 0)
  599. {
  600. jack_error("sun_driver: playback flush failed: %s: "
  601. "%s@%i", strerror(errno), __FILE__, __LINE__);
  602. return -1;
  603. }
  604. #endif
  605. AUDIO_INITINFO(&audio_if);
  606. audio_if.play.pause = 1;
  607. if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
  608. {
  609. jack_error("sun_driver: pause playback failed: %s: "
  610. "%s@%i", strerror(errno), __FILE__, __LINE__);
  611. return -1;
  612. }
  613. }
  614. /* AUDIO_FLUSH resets the counters these work with */
  615. driver->playback_drops = driver->capture_drops = 0;
  616. if (driver->outfd >= 0)
  617. {
  618. /* "prime" the playback buffer. if we don't do this, we'll
  619. * end up underrunning. it would get really ugly in duplex
  620. * mode, for example, where we have to wait for a period to
  621. * be available to read before we can write. also helps to
  622. * keep constant latency from the beginning.
  623. */
  624. sun_driver_write_silence(driver,
  625. driver->nperiods * driver->period_size);
  626. }
  627. if (driver->infd >= 0)
  628. {
  629. AUDIO_INITINFO(&audio_if);
  630. audio_if.record.pause = 0;
  631. if (driver->outfd == driver->infd)
  632. audio_if.play.pause = 0;
  633. if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
  634. {
  635. jack_error("sun_driver: start capture failed: %s: "
  636. "%s@%i", strerror(errno), __FILE__, __LINE__);
  637. return -1;
  638. }
  639. }
  640. if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
  641. {
  642. AUDIO_INITINFO(&audio_if);
  643. audio_if.play.pause = 0;
  644. if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
  645. {
  646. jack_error("sun_driver: trigger playback failed: %s: "
  647. "%s@%i", strerror(errno), __FILE__, __LINE__);
  648. return -1;
  649. }
  650. }
  651. return 0;
  652. }
  653. static int
  654. enc_equal(int a, int b)
  655. {
  656. if (a == b)
  657. return 1;
  658. #if defined(AUDIO_ENCODING_SLINEAR)
  659. #if BYTE_ORDER == LITTLE_ENDIAN
  660. if ((a == AUDIO_ENCODING_SLINEAR && b == AUDIO_ENCODING_SLINEAR_LE) ||
  661. (a == AUDIO_ENCODING_SLINEAR_LE && b == AUDIO_ENCODING_SLINEAR) ||
  662. (a == AUDIO_ENCODING_ULINEAR && b == AUDIO_ENCODING_ULINEAR_LE) ||
  663. (a == AUDIO_ENCODING_ULINEAR_LE && b == AUDIO_ENCODING_ULINEAR))
  664. return 1;
  665. #elif BYTE_ORDER == BIG_ENDIAN
  666. if ((a == AUDIO_ENCODING_SLINEAR && b == AUDIO_ENCODING_SLINEAR_BE) ||
  667. (a == AUDIO_ENCODING_SLINEAR_BE && b == AUDIO_ENCODING_SLINEAR) ||
  668. (a == AUDIO_ENCODING_ULINEAR && b == AUDIO_ENCODING_ULINEAR_BE) ||
  669. (a == AUDIO_ENCODING_ULINEAR_BE && b == AUDIO_ENCODING_ULINEAR))
  670. return 1;
  671. #endif
  672. #endif // AUDIO_ENCODING_SLINEAR
  673. return 0;
  674. }
  675. static int
  676. sun_driver_set_parameters (sun_driver_t *driver)
  677. {
  678. audio_info_t audio_if_in, audio_if_out;
  679. int infd = -1;
  680. int outfd = -1;
  681. int s = 1;
  682. unsigned int cap_period = 0, play_period = 0, period_size = 0;
  683. const char *indev = driver->indev;
  684. const char *outdev = driver->outdev;
  685. driver->indevbuf = NULL;
  686. driver->outdevbuf = NULL;
  687. driver->sample_bytes = driver->bits / 8;
  688. if ((strcmp(indev, outdev) == 0) &&
  689. ((driver->capture_channels > 0) && (driver->playback_channels > 0)))
  690. {
  691. infd = outfd = open(indev, O_RDWR);
  692. if (infd < 0)
  693. {
  694. jack_error("sun_driver: failed to open duplex device "
  695. "%s: %s: %s@%i", indev, strerror(errno),
  696. __FILE__, __LINE__);
  697. return -1;
  698. }
  699. #if defined(AUDIO_SETFD)
  700. if (ioctl(infd, AUDIO_SETFD, &s) < 0)
  701. {
  702. jack_error("sun_driver: failed to enable full duplex: "
  703. "%s: %s@%i", strerror(errno),
  704. __FILE__, __LINE__);
  705. return -1;
  706. }
  707. #endif
  708. }
  709. else
  710. {
  711. if (driver->capture_channels > 0)
  712. {
  713. infd = open(indev, O_RDONLY);
  714. if (infd < 0)
  715. {
  716. jack_error("sun_driver: failed to open input "
  717. "device %s: %s: %s@%i", indev,
  718. strerror(errno), __FILE__, __LINE__);
  719. return -1;
  720. }
  721. }
  722. if (driver->playback_channels > 0)
  723. {
  724. outfd = open(outdev, O_WRONLY);
  725. if (outfd < 0)
  726. {
  727. jack_error("sun_driver: failed to open output "
  728. "device %s: %s: %s@%i", outdev,
  729. strerror(errno), __FILE__, __LINE__);
  730. return -1;
  731. }
  732. }
  733. }
  734. if (infd == -1 && outfd == -1)
  735. {
  736. jack_error("sun_driver: no device was opened: %s@%i",
  737. __FILE__, __LINE__);
  738. return -1;
  739. }
  740. driver->infd = infd;
  741. driver->outfd = outfd;
  742. AUDIO_INITINFO(&audio_if_in);
  743. AUDIO_INITINFO(&audio_if_out);
  744. if (infd >= 0)
  745. {
  746. audio_if_in.record.encoding = driver->format;
  747. audio_if_in.record.precision = driver->bits;
  748. audio_if_in.record.channels = driver->capture_channels;
  749. audio_if_in.record.sample_rate = driver->sample_rate;
  750. audio_if_in.record.pause = 1;
  751. }
  752. if (outfd >= 0)
  753. {
  754. audio_if_out.play.encoding = driver->format;
  755. audio_if_out.play.precision = driver->bits;
  756. audio_if_out.play.channels = driver->playback_channels;
  757. audio_if_out.play.sample_rate = driver->sample_rate;
  758. audio_if_out.play.pause = 1;
  759. }
  760. #if defined(__OpenBSD__) || defined(__NetBSD__)
  761. #if defined(__OpenBSD__)
  762. if (driver->infd >= 0)
  763. audio_if_in.record.block_size = driver->capture_channels *
  764. driver->period_size * driver->sample_bytes;
  765. if (driver->outfd >= 0)
  766. audio_if_out.play.block_size = driver->playback_channels *
  767. driver->period_size * driver->sample_bytes;
  768. #else
  769. if (driver->infd >= 0)
  770. audio_if_in.blocksize = driver->capture_channels *
  771. driver->period_size * driver->sample_bytes;
  772. if (driver->outfd >= 0)
  773. audio_if_out.blocksize = driver->playback_channels *
  774. driver->period_size * driver->sample_bytes;
  775. #endif
  776. if (infd == outfd)
  777. audio_if_in.play = audio_if_out.play;
  778. /* this only affects playback. the capture buffer is
  779. * always the max (64k on OpenBSD).
  780. */
  781. audio_if_in.hiwat = audio_if_out.hiwat = driver->nperiods;
  782. /* AUMODE_PLAY makes us "catch up to realtime" if we underrun
  783. * playback. that means, if we are N frames late, the next
  784. * N frames written will be discarded. this keeps playback
  785. * time from expanding with each underrun.
  786. */
  787. if (infd == outfd)
  788. {
  789. audio_if_in.mode = AUMODE_PLAY | AUMODE_RECORD;
  790. }
  791. else
  792. {
  793. if (infd >= 0)
  794. audio_if_in.mode = AUMODE_RECORD;
  795. if (outfd >= 0)
  796. audio_if_out.mode = AUMODE_PLAY;
  797. }
  798. #endif // OpenBSD || NetBSD
  799. if (infd >= 0)
  800. {
  801. if (ioctl(infd, AUDIO_SETINFO, &audio_if_in) < 0)
  802. {
  803. jack_error("sun_driver: failed to set parameters for "
  804. "%s: %s: %s@%i", indev, strerror(errno),
  805. __FILE__, __LINE__);
  806. return -1;
  807. }
  808. }
  809. if (outfd >= 0 && outfd != infd)
  810. {
  811. if (ioctl(outfd, AUDIO_SETINFO, &audio_if_out) < 0)
  812. {
  813. jack_error("sun_driver: failed to set parameters for "
  814. "%s: %s: %s@%i", outdev, strerror(errno),
  815. __FILE__, __LINE__);
  816. return -1;
  817. }
  818. }
  819. if (infd >= 0)
  820. {
  821. if (ioctl(infd, AUDIO_GETINFO, &audio_if_in) < 0)
  822. {
  823. jack_error("sun_driver: AUDIO_GETINFO failed: %s: "
  824. "%s@%i", strerror(errno), __FILE__, __LINE__);
  825. return -1;
  826. }
  827. if (!enc_equal(audio_if_in.record.encoding, driver->format) ||
  828. audio_if_in.record.precision != driver->bits ||
  829. audio_if_in.record.channels != driver->capture_channels ||
  830. audio_if_in.record.sample_rate != driver->sample_rate)
  831. {
  832. jack_error("sun_driver: setting capture parameters "
  833. "failed: %s@%i", __FILE__, __LINE__);
  834. return -1;
  835. }
  836. #if defined(__OpenBSD__)
  837. cap_period = audio_if_in.record.block_size /
  838. driver->capture_channels / driver->sample_bytes;
  839. #elif defined(__NetBSD__)
  840. cap_period = audio_if_in.blocksize /
  841. driver->capture_channels / driver->sample_bytes;
  842. #else
  843. /* how is this done on Solaris? */
  844. cap_period = driver->period_size;
  845. #endif
  846. }
  847. if (outfd >= 0)
  848. {
  849. if (outfd == infd)
  850. {
  851. audio_if_out.play = audio_if_in.play;
  852. }
  853. else
  854. {
  855. if (ioctl(outfd, AUDIO_GETINFO, &audio_if_out) < 0)
  856. {
  857. jack_error("sun_driver: AUDIO_GETINFO failed: "
  858. "%s: %s@%i", strerror(errno),
  859. __FILE__, __LINE__);
  860. return -1;
  861. }
  862. }
  863. if (!enc_equal(audio_if_out.play.encoding, driver->format) ||
  864. audio_if_out.play.precision != driver->bits ||
  865. audio_if_out.play.channels != driver->playback_channels ||
  866. audio_if_out.play.sample_rate != driver->sample_rate)
  867. {
  868. jack_error("sun_driver: playback settings failed: "
  869. "%s@%i", __FILE__, __LINE__);
  870. return -1;
  871. }
  872. #if defined(__OpenBSD__)
  873. play_period = audio_if_out.play.block_size /
  874. driver->playback_channels / driver->sample_bytes;
  875. #elif defined(__NetBSD__)
  876. play_period = audio_if_out.blocksize /
  877. driver->playback_channels / driver->sample_bytes;
  878. #else
  879. /* how is this done on Solaris? */
  880. play_period = driver->period_size;
  881. #endif
  882. }
  883. if (infd >= 0 && outfd >= 0 && play_period != cap_period)
  884. {
  885. jack_error("sun_driver: play and capture periods differ: "
  886. "%s@%i", __FILE__, __LINE__);
  887. return -1;
  888. }
  889. if (infd >= 0)
  890. period_size = cap_period;
  891. else if (outfd >= 0)
  892. period_size = play_period;
  893. if (period_size != 0 && period_size != driver->period_size &&
  894. !driver->ignorehwbuf)
  895. {
  896. printf("sun_driver: period size update: %u\n", period_size);
  897. set_period_size (driver, period_size);
  898. if (driver->engine)
  899. if (driver->engine->set_buffer_size(driver->engine,
  900. driver->period_size)) {
  901. jack_error ("sun_driver: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  902. return -1;
  903. }
  904. }
  905. if (driver->infd >= 0 && driver->capture_channels > 0)
  906. {
  907. driver->indevbufsize = driver->period_size *
  908. driver->capture_channels * driver->sample_bytes;
  909. driver->indevbuf = malloc(driver->indevbufsize);
  910. if (driver->indevbuf == NULL)
  911. {
  912. jack_error( "sun_driver: malloc() failed: %s@%i",
  913. __FILE__, __LINE__);
  914. return -1;
  915. }
  916. bzero(driver->indevbuf, driver->indevbufsize);
  917. }
  918. else
  919. {
  920. driver->indevbufsize = 0;
  921. driver->indevbuf = NULL;
  922. }
  923. if (driver->outfd >= 0 && driver->playback_channels > 0)
  924. {
  925. driver->outdevbufsize = driver->period_size *
  926. driver->playback_channels * driver->sample_bytes;
  927. driver->outdevbuf = malloc(driver->outdevbufsize);
  928. if (driver->outdevbuf == NULL)
  929. {
  930. jack_error("sun_driver: malloc() failed: %s@%i",
  931. __FILE__, __LINE__);
  932. return -1;
  933. }
  934. bzero(driver->outdevbuf, driver->outdevbufsize);
  935. }
  936. else
  937. {
  938. driver->outdevbufsize = 0;
  939. driver->outdevbuf = NULL;
  940. }
  941. printf("sun_driver: indevbuf %zd B, outdevbuf %zd B\n",
  942. driver->indevbufsize, driver->outdevbufsize);
  943. return 0;
  944. }
  945. static int
  946. sun_driver_stop (sun_driver_t *driver)
  947. {
  948. audio_info_t audio_if;
  949. if (driver->infd >= 0)
  950. {
  951. AUDIO_INITINFO(&audio_if);
  952. audio_if.record.pause = 1;
  953. if (driver->outfd == driver->infd)
  954. audio_if.play.pause = 1;
  955. if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
  956. {
  957. jack_error("sun_driver: capture pause failed: %s: "
  958. "%s@%i", strerror(errno), __FILE__, __LINE__);
  959. return -1;
  960. }
  961. }
  962. if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
  963. {
  964. AUDIO_INITINFO(&audio_if);
  965. audio_if.play.pause = 1;
  966. if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
  967. {
  968. jack_error("sun_driver: playback pause failed: %s: "
  969. "%s@%i", strerror(errno), __FILE__, __LINE__);
  970. return -1;
  971. }
  972. }
  973. return 0;
  974. }
  975. static int
  976. sun_driver_read (sun_driver_t *driver, jack_nframes_t nframes)
  977. {
  978. jack_nframes_t nbytes;
  979. int channel;
  980. ssize_t io_res;
  981. jack_sample_t *portbuf;
  982. JSList *node;
  983. jack_port_t *port;
  984. if (driver->engine->freewheeling || driver->infd < 0)
  985. return 0;
  986. if (nframes > driver->period_size)
  987. {
  988. jack_error("sun_driver: read failed: nframes > period_size: "
  989. "(%u/%u): %s@%i", nframes, driver->period_size,
  990. __FILE__, __LINE__);
  991. return -1;
  992. }
  993. node = driver->capture_ports;
  994. channel = 0;
  995. while (node != NULL)
  996. {
  997. port = (jack_port_t *) node->data;
  998. if (jack_port_connected(port))
  999. {
  1000. portbuf = jack_port_get_buffer(port, nframes);
  1001. copy_and_convert_in(portbuf, driver->indevbuf,
  1002. nframes, channel,
  1003. driver->capture_channels,
  1004. driver->bits);
  1005. }
  1006. node = jack_slist_next(node);
  1007. channel++;
  1008. }
  1009. nbytes = nframes * driver->capture_channels * driver->sample_bytes;
  1010. io_res = 0;
  1011. while (nbytes)
  1012. {
  1013. io_res = read(driver->infd, driver->indevbuf, nbytes);
  1014. if (io_res < 0)
  1015. {
  1016. jack_error("sun_driver: read() failed: %s: %s@%i",
  1017. strerror(errno), __FILE__, __LINE__);
  1018. break;
  1019. }
  1020. else
  1021. nbytes -= io_res;
  1022. }
  1023. return 0;
  1024. }
  1025. static int
  1026. sun_driver_write (sun_driver_t *driver, jack_nframes_t nframes)
  1027. {
  1028. jack_nframes_t nbytes;
  1029. int channel;
  1030. ssize_t io_res;
  1031. jack_sample_t *portbuf;
  1032. JSList *node;
  1033. jack_port_t *port;
  1034. if (driver->engine->freewheeling || driver->outfd < 0)
  1035. return 0;
  1036. if (nframes > driver->period_size)
  1037. {
  1038. jack_error("sun_driver: write failed: nframes > period_size "
  1039. "(%u/%u): %s@%i", nframes, driver->period_size,
  1040. __FILE__, __LINE__);
  1041. return -1;
  1042. }
  1043. bzero(driver->outdevbuf, driver->outdevbufsize);
  1044. node = driver->playback_ports;
  1045. channel = 0;
  1046. while (node != NULL)
  1047. {
  1048. port = (jack_port_t *) node->data;
  1049. if (jack_port_connected(port))
  1050. {
  1051. portbuf = jack_port_get_buffer(port, nframes);
  1052. copy_and_convert_out(driver->outdevbuf, portbuf,
  1053. nframes, channel,
  1054. driver->playback_channels,
  1055. driver->bits);
  1056. }
  1057. node = jack_slist_next(node);
  1058. channel++;
  1059. }
  1060. nbytes = nframes * driver->playback_channels * driver->sample_bytes;
  1061. io_res = 0;
  1062. while (nbytes)
  1063. {
  1064. io_res = write(driver->outfd, driver->outdevbuf, nbytes);
  1065. if (io_res < 0)
  1066. {
  1067. jack_error("sun_driver: write() failed: %s: %s@%i",
  1068. strerror(errno), __FILE__, __LINE__);
  1069. break;
  1070. }
  1071. else
  1072. nbytes -= io_res;
  1073. }
  1074. return 0;
  1075. }
  1076. static int
  1077. sun_driver_null_cycle (sun_driver_t *driver, jack_nframes_t nframes)
  1078. {
  1079. if (nframes > driver->period_size)
  1080. {
  1081. jack_error("sun_driver: null cycle failed: "
  1082. "nframes > period_size (%u/%u): %s@%i", nframes,
  1083. driver->period_size, __FILE__, __LINE__);
  1084. return -1;
  1085. }
  1086. printf("sun_driver: running null cycle\n");
  1087. if (driver->outfd >= 0)
  1088. sun_driver_write_silence (driver, nframes);
  1089. if (driver->infd >= 0)
  1090. sun_driver_read_silence (driver, nframes);
  1091. return 0;
  1092. }
  1093. static int
  1094. sun_driver_bufsize (sun_driver_t *driver, jack_nframes_t nframes)
  1095. {
  1096. return sun_driver_set_parameters(driver);
  1097. }
  1098. static void
  1099. sun_driver_delete (sun_driver_t *driver)
  1100. {
  1101. if (driver->outfd >= 0 && driver->outfd != driver->infd)
  1102. {
  1103. close(driver->outfd);
  1104. driver->outfd = -1;
  1105. }
  1106. if (driver->infd >= 0)
  1107. {
  1108. close(driver->infd);
  1109. driver->infd = -1;
  1110. }
  1111. if (driver->indevbuf != NULL)
  1112. {
  1113. free(driver->indevbuf);
  1114. driver->indevbuf = NULL;
  1115. }
  1116. if (driver->outdevbuf != NULL)
  1117. {
  1118. free(driver->outdevbuf);
  1119. driver->outdevbuf = NULL;
  1120. }
  1121. if (driver->indev != NULL)
  1122. free(driver->indev);
  1123. if (driver->outdev != NULL)
  1124. free(driver->outdev);
  1125. jack_driver_nt_finish((jack_driver_nt_t *) driver);
  1126. free(driver);
  1127. }
  1128. void
  1129. driver_finish (jack_driver_t *driver)
  1130. {
  1131. sun_driver_delete ((sun_driver_t *)driver);
  1132. }
  1133. static jack_driver_t *
  1134. sun_driver_new (char *indev, char *outdev, jack_client_t *client,
  1135. jack_nframes_t sample_rate, jack_nframes_t period_size,
  1136. jack_nframes_t nperiods, int bits,
  1137. int capture_channels, int playback_channels,
  1138. jack_nframes_t in_latency, jack_nframes_t out_latency,
  1139. int ignorehwbuf)
  1140. {
  1141. sun_driver_t *driver;
  1142. driver = (sun_driver_t *) malloc(sizeof(sun_driver_t));
  1143. if (driver == NULL)
  1144. {
  1145. jack_error("sun_driver: malloc() failed: %s: %s@%i",
  1146. strerror(errno), __FILE__, __LINE__);
  1147. return NULL;
  1148. }
  1149. driver->engine = NULL;
  1150. jack_driver_nt_init((jack_driver_nt_t *) driver);
  1151. driver->nt_attach = (JackDriverNTAttachFunction) sun_driver_attach;
  1152. driver->nt_detach = (JackDriverNTDetachFunction) sun_driver_detach;
  1153. driver->read = (JackDriverReadFunction) sun_driver_read;
  1154. driver->write = (JackDriverWriteFunction) sun_driver_write;
  1155. driver->null_cycle = (JackDriverNullCycleFunction)
  1156. sun_driver_null_cycle;
  1157. driver->nt_bufsize = (JackDriverNTBufSizeFunction) sun_driver_bufsize;
  1158. driver->nt_start = (JackDriverNTStartFunction) sun_driver_start;
  1159. driver->nt_stop = (JackDriverNTStopFunction) sun_driver_stop;
  1160. driver->nt_run_cycle = (JackDriverNTRunCycleFunction) sun_driver_run_cycle;
  1161. if (indev != NULL)
  1162. driver->indev = strdup(indev);
  1163. if (outdev != NULL)
  1164. driver->outdev = strdup(outdev);
  1165. driver->ignorehwbuf = ignorehwbuf;
  1166. driver->sample_rate = sample_rate;
  1167. driver->period_size = period_size;
  1168. driver->nperiods = nperiods;
  1169. driver->bits = bits;
  1170. driver->capture_channels = capture_channels;
  1171. driver->playback_channels = playback_channels;
  1172. driver->sys_in_latency = in_latency;
  1173. driver->sys_out_latency = out_latency;
  1174. set_period_size(driver, period_size);
  1175. if (driver->indev == NULL)
  1176. driver->indev = strdup(SUN_DRIVER_DEF_DEV);
  1177. if (driver->outdev == NULL)
  1178. driver->outdev = strdup(SUN_DRIVER_DEF_DEV);
  1179. driver->infd = -1;
  1180. driver->outfd = -1;
  1181. #if defined(AUDIO_ENCODING_SLINEAR)
  1182. driver->format = AUDIO_ENCODING_SLINEAR;
  1183. #else
  1184. driver->format = AUDIO_ENCODING_LINEAR;
  1185. #endif
  1186. driver->indevbuf = driver->outdevbuf = NULL;
  1187. driver->capture_ports = NULL;
  1188. driver->playback_ports = NULL;
  1189. driver->iodelay = 0.0F;
  1190. driver->poll_last = driver->poll_next = 0;
  1191. if (sun_driver_set_parameters (driver) < 0)
  1192. {
  1193. free(driver);
  1194. return NULL;
  1195. }
  1196. driver->client = client;
  1197. return (jack_driver_t *) driver;
  1198. }
  1199. /* jack driver published interface */
  1200. const char driver_client_name[] = "sun";
  1201. jack_driver_desc_t *
  1202. driver_get_descriptor ()
  1203. {
  1204. jack_driver_desc_t *desc;
  1205. jack_driver_param_desc_t *params;
  1206. desc = (jack_driver_desc_t *) calloc(1, sizeof(jack_driver_desc_t));
  1207. if (desc == NULL)
  1208. {
  1209. jack_error("sun_driver: calloc() failed: %s: %s@%i",
  1210. strerror(errno), __FILE__, __LINE__);
  1211. return NULL;
  1212. }
  1213. strcpy(desc->name, driver_client_name);
  1214. desc->nparams = SUN_DRIVER_N_PARAMS;
  1215. params = calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
  1216. if (params == NULL)
  1217. {
  1218. jack_error("sun_driver: calloc() failed: %s: %s@%i",
  1219. strerror(errno), __FILE__, __LINE__);
  1220. return NULL;
  1221. }
  1222. memcpy(params, sun_params,
  1223. desc->nparams * sizeof(jack_driver_param_desc_t));
  1224. desc->params = params;
  1225. return desc;
  1226. }
  1227. jack_driver_t *
  1228. driver_initialize (jack_client_t *client, JSList * params)
  1229. {
  1230. int bits = SUN_DRIVER_DEF_BITS;
  1231. jack_nframes_t sample_rate = SUN_DRIVER_DEF_FS;
  1232. jack_nframes_t period_size = SUN_DRIVER_DEF_BLKSIZE;
  1233. jack_nframes_t in_latency = 0;
  1234. jack_nframes_t out_latency = 0;
  1235. unsigned int nperiods = SUN_DRIVER_DEF_NPERIODS;
  1236. unsigned int capture_channels = SUN_DRIVER_DEF_INS;
  1237. unsigned int playback_channels = SUN_DRIVER_DEF_OUTS;
  1238. const JSList *pnode;
  1239. const jack_driver_param_t *param;
  1240. char *indev;
  1241. char *outdev;
  1242. int ignorehwbuf = 0;
  1243. indev = strdup(SUN_DRIVER_DEF_DEV);
  1244. outdev = strdup(SUN_DRIVER_DEF_DEV);
  1245. pnode = params;
  1246. while (pnode != NULL)
  1247. {
  1248. param = (const jack_driver_param_t *) pnode->data;
  1249. switch (param->character)
  1250. {
  1251. case 'r':
  1252. sample_rate = param->value.ui;
  1253. break;
  1254. case 'p':
  1255. period_size = param->value.ui;
  1256. break;
  1257. case 'n':
  1258. nperiods = param->value.ui;
  1259. break;
  1260. case 'w':
  1261. bits = param->value.i;
  1262. break;
  1263. case 'i':
  1264. capture_channels = param->value.ui;
  1265. break;
  1266. case 'o':
  1267. playback_channels = param->value.ui;
  1268. break;
  1269. case 'C':
  1270. indev = strdup(param->value.str);
  1271. break;
  1272. case 'P':
  1273. outdev = strdup(param->value.str);
  1274. break;
  1275. case 'b':
  1276. ignorehwbuf = 1;
  1277. break;
  1278. case 'I':
  1279. in_latency = param->value.ui;
  1280. break;
  1281. case 'O':
  1282. out_latency = param->value.ui;
  1283. break;
  1284. }
  1285. pnode = jack_slist_next(pnode);
  1286. }
  1287. return sun_driver_new (indev, outdev, client, sample_rate, period_size,
  1288. nperiods, bits, capture_channels, playback_channels, in_latency,
  1289. out_latency, ignorehwbuf);
  1290. }