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.

1475 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/internal.h>
  45. #include <jack/engine.h>
  46. #include <jack/thread.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 = jack_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 = jack_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 = jack_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. if (driver->engine->set_buffer_size(driver->engine, driver->period_size)) {
  501. jack_error ("sun_driver: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  502. return -1;
  503. }
  504. driver->engine->set_sample_rate(driver->engine, driver->sample_rate);
  505. port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
  506. for (channel = 0; channel < driver->capture_channels; channel++)
  507. {
  508. snprintf(channel_name, sizeof(channel_name),
  509. "capture_%u", channel + 1);
  510. port = jack_port_register(driver->client, channel_name,
  511. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  512. if (port == NULL)
  513. {
  514. jack_error("sun_driver: cannot register port for %s: "
  515. "%s@%i", channel_name, __FILE__, __LINE__);
  516. break;
  517. }
  518. jack_port_set_latency(port,
  519. driver->period_size + driver->sys_in_latency);
  520. driver->capture_ports =
  521. jack_slist_append(driver->capture_ports, port);
  522. }
  523. port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
  524. for (channel = 0; channel < driver->playback_channels; channel++)
  525. {
  526. snprintf(channel_name, sizeof(channel_name),
  527. "playback_%u", channel + 1);
  528. port = jack_port_register(driver->client, channel_name,
  529. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  530. if (port == NULL)
  531. {
  532. jack_error("sun_driver: cannot register port for "
  533. "%s: %s@%i", channel_name, __FILE__, __LINE__);
  534. break;
  535. }
  536. jack_port_set_latency(port,
  537. driver->period_size + driver->sys_out_latency);
  538. driver->playback_ports =
  539. jack_slist_append(driver->playback_ports, port);
  540. }
  541. return jack_activate(driver->client);
  542. }
  543. static int
  544. sun_driver_detach (sun_driver_t *driver)
  545. {
  546. JSList *node;
  547. if (driver->engine == NULL)
  548. return 0;
  549. node = driver->capture_ports;
  550. while (node != NULL)
  551. {
  552. jack_port_unregister(driver->client,
  553. ((jack_port_t *) node->data));
  554. node = jack_slist_next(node);
  555. }
  556. jack_slist_free(driver->capture_ports);
  557. driver->capture_ports = NULL;
  558. node = driver->playback_ports;
  559. while (node != NULL)
  560. {
  561. jack_port_unregister(driver->client,
  562. ((jack_port_t *) node->data));
  563. node = jack_slist_next(node);
  564. }
  565. jack_slist_free(driver->playback_ports);
  566. driver->playback_ports = NULL;
  567. return 0;
  568. }
  569. static int
  570. sun_driver_start (sun_driver_t *driver)
  571. {
  572. audio_info_t audio_if;
  573. if (driver->infd >= 0)
  574. {
  575. #if defined(AUDIO_FLUSH)
  576. if (ioctl(driver->infd, AUDIO_FLUSH, NULL) < 0)
  577. {
  578. jack_error("sun_driver: capture flush failed: %s: "
  579. "%s@%i", strerror(errno), __FILE__, __LINE__);
  580. return -1;
  581. }
  582. #endif
  583. AUDIO_INITINFO(&audio_if);
  584. audio_if.record.pause = 1;
  585. if (driver->outfd == driver->infd)
  586. audio_if.play.pause = 1;
  587. if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
  588. {
  589. jack_error("sun_driver: pause capture failed: %s: "
  590. "%s@%i", strerror(errno), __FILE__, __LINE__);
  591. return -1;
  592. }
  593. }
  594. if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
  595. {
  596. #if defined(AUDIO_FLUSH)
  597. if (ioctl(driver->outfd, AUDIO_FLUSH, NULL) < 0)
  598. {
  599. jack_error("sun_driver: playback flush failed: %s: "
  600. "%s@%i", strerror(errno), __FILE__, __LINE__);
  601. return -1;
  602. }
  603. #endif
  604. AUDIO_INITINFO(&audio_if);
  605. audio_if.play.pause = 1;
  606. if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
  607. {
  608. jack_error("sun_driver: pause playback failed: %s: "
  609. "%s@%i", strerror(errno), __FILE__, __LINE__);
  610. return -1;
  611. }
  612. }
  613. /* AUDIO_FLUSH resets the counters these work with */
  614. driver->playback_drops = driver->capture_drops = 0;
  615. if (driver->outfd >= 0)
  616. {
  617. /* "prime" the playback buffer. if we don't do this, we'll
  618. * end up underrunning. it would get really ugly in duplex
  619. * mode, for example, where we have to wait for a period to
  620. * be available to read before we can write. also helps to
  621. * keep constant latency from the beginning.
  622. */
  623. sun_driver_write_silence(driver,
  624. driver->nperiods * driver->period_size);
  625. }
  626. if (driver->infd >= 0)
  627. {
  628. AUDIO_INITINFO(&audio_if);
  629. audio_if.record.pause = 0;
  630. if (driver->outfd == driver->infd)
  631. audio_if.play.pause = 0;
  632. if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
  633. {
  634. jack_error("sun_driver: start capture failed: %s: "
  635. "%s@%i", strerror(errno), __FILE__, __LINE__);
  636. return -1;
  637. }
  638. }
  639. if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
  640. {
  641. AUDIO_INITINFO(&audio_if);
  642. audio_if.play.pause = 0;
  643. if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
  644. {
  645. jack_error("sun_driver: trigger playback failed: %s: "
  646. "%s@%i", strerror(errno), __FILE__, __LINE__);
  647. return -1;
  648. }
  649. }
  650. return 0;
  651. }
  652. static int
  653. enc_equal(int a, int b)
  654. {
  655. if (a == b)
  656. return 1;
  657. #if defined(AUDIO_ENCODING_SLINEAR)
  658. #if BYTE_ORDER == LITTLE_ENDIAN
  659. if ((a == AUDIO_ENCODING_SLINEAR && b == AUDIO_ENCODING_SLINEAR_LE) ||
  660. (a == AUDIO_ENCODING_SLINEAR_LE && b == AUDIO_ENCODING_SLINEAR) ||
  661. (a == AUDIO_ENCODING_ULINEAR && b == AUDIO_ENCODING_ULINEAR_LE) ||
  662. (a == AUDIO_ENCODING_ULINEAR_LE && b == AUDIO_ENCODING_ULINEAR))
  663. return 1;
  664. #elif BYTE_ORDER == BIG_ENDIAN
  665. if ((a == AUDIO_ENCODING_SLINEAR && b == AUDIO_ENCODING_SLINEAR_BE) ||
  666. (a == AUDIO_ENCODING_SLINEAR_BE && b == AUDIO_ENCODING_SLINEAR) ||
  667. (a == AUDIO_ENCODING_ULINEAR && b == AUDIO_ENCODING_ULINEAR_BE) ||
  668. (a == AUDIO_ENCODING_ULINEAR_BE && b == AUDIO_ENCODING_ULINEAR))
  669. return 1;
  670. #endif
  671. #endif // AUDIO_ENCODING_SLINEAR
  672. return 0;
  673. }
  674. static int
  675. sun_driver_set_parameters (sun_driver_t *driver)
  676. {
  677. audio_info_t audio_if_in, audio_if_out;
  678. int infd = -1;
  679. int outfd = -1;
  680. int s = 1;
  681. unsigned int cap_period = 0, play_period = 0, period_size = 0;
  682. const char *indev = driver->indev;
  683. const char *outdev = driver->outdev;
  684. driver->indevbuf = NULL;
  685. driver->outdevbuf = NULL;
  686. driver->sample_bytes = driver->bits / 8;
  687. if ((strcmp(indev, outdev) == 0) &&
  688. ((driver->capture_channels > 0) && (driver->playback_channels > 0)))
  689. {
  690. infd = outfd = open(indev, O_RDWR);
  691. if (infd < 0)
  692. {
  693. jack_error("sun_driver: failed to open duplex device "
  694. "%s: %s: %s@%i", indev, strerror(errno),
  695. __FILE__, __LINE__);
  696. return -1;
  697. }
  698. #if defined(AUDIO_SETFD)
  699. if (ioctl(infd, AUDIO_SETFD, &s) < 0)
  700. {
  701. jack_error("sun_driver: failed to enable full duplex: "
  702. "%s: %s@%i", strerror(errno),
  703. __FILE__, __LINE__);
  704. return -1;
  705. }
  706. #endif
  707. }
  708. else
  709. {
  710. if (driver->capture_channels > 0)
  711. {
  712. infd = open(indev, O_RDONLY);
  713. if (infd < 0)
  714. {
  715. jack_error("sun_driver: failed to open input "
  716. "device %s: %s: %s@%i", indev,
  717. strerror(errno), __FILE__, __LINE__);
  718. return -1;
  719. }
  720. }
  721. if (driver->playback_channels > 0)
  722. {
  723. outfd = open(outdev, O_WRONLY);
  724. if (outfd < 0)
  725. {
  726. jack_error("sun_driver: failed to open output "
  727. "device %s: %s: %s@%i", outdev,
  728. strerror(errno), __FILE__, __LINE__);
  729. return -1;
  730. }
  731. }
  732. }
  733. if (infd == -1 && outfd == -1)
  734. {
  735. jack_error("sun_driver: no device was opened: %s@%i",
  736. __FILE__, __LINE__);
  737. return -1;
  738. }
  739. driver->infd = infd;
  740. driver->outfd = outfd;
  741. AUDIO_INITINFO(&audio_if_in);
  742. AUDIO_INITINFO(&audio_if_out);
  743. if (infd >= 0)
  744. {
  745. audio_if_in.record.encoding = driver->format;
  746. audio_if_in.record.precision = driver->bits;
  747. audio_if_in.record.channels = driver->capture_channels;
  748. audio_if_in.record.sample_rate = driver->sample_rate;
  749. audio_if_in.record.pause = 1;
  750. }
  751. if (outfd >= 0)
  752. {
  753. audio_if_out.play.encoding = driver->format;
  754. audio_if_out.play.precision = driver->bits;
  755. audio_if_out.play.channels = driver->playback_channels;
  756. audio_if_out.play.sample_rate = driver->sample_rate;
  757. audio_if_out.play.pause = 1;
  758. }
  759. #if defined(__OpenBSD__) || defined(__NetBSD__)
  760. #if defined(__OpenBSD__)
  761. if (driver->infd >= 0)
  762. audio_if_in.record.block_size = driver->capture_channels *
  763. driver->period_size * driver->sample_bytes;
  764. if (driver->outfd >= 0)
  765. audio_if_out.play.block_size = driver->playback_channels *
  766. driver->period_size * driver->sample_bytes;
  767. #else
  768. if (driver->infd >= 0)
  769. audio_if_in.blocksize = driver->capture_channels *
  770. driver->period_size * driver->sample_bytes;
  771. if (driver->outfd >= 0)
  772. audio_if_out.blocksize = driver->playback_channels *
  773. driver->period_size * driver->sample_bytes;
  774. #endif
  775. if (infd == outfd)
  776. audio_if_in.play = audio_if_out.play;
  777. /* this only affects playback. the capture buffer is
  778. * always the max (64k on OpenBSD).
  779. */
  780. audio_if_in.hiwat = audio_if_out.hiwat = driver->nperiods;
  781. /* AUMODE_PLAY makes us "catch up to realtime" if we underrun
  782. * playback. that means, if we are N frames late, the next
  783. * N frames written will be discarded. this keeps playback
  784. * time from expanding with each underrun.
  785. */
  786. if (infd == outfd)
  787. {
  788. audio_if_in.mode = AUMODE_PLAY | AUMODE_RECORD;
  789. }
  790. else
  791. {
  792. if (infd >= 0)
  793. audio_if_in.mode = AUMODE_RECORD;
  794. if (outfd >= 0)
  795. audio_if_out.mode = AUMODE_PLAY;
  796. }
  797. #endif // OpenBSD || NetBSD
  798. if (infd >= 0)
  799. {
  800. if (ioctl(infd, AUDIO_SETINFO, &audio_if_in) < 0)
  801. {
  802. jack_error("sun_driver: failed to set parameters for "
  803. "%s: %s: %s@%i", indev, strerror(errno),
  804. __FILE__, __LINE__);
  805. return -1;
  806. }
  807. }
  808. if (outfd >= 0 && outfd != infd)
  809. {
  810. if (ioctl(outfd, AUDIO_SETINFO, &audio_if_out) < 0)
  811. {
  812. jack_error("sun_driver: failed to set parameters for "
  813. "%s: %s: %s@%i", outdev, strerror(errno),
  814. __FILE__, __LINE__);
  815. return -1;
  816. }
  817. }
  818. if (infd >= 0)
  819. {
  820. if (ioctl(infd, AUDIO_GETINFO, &audio_if_in) < 0)
  821. {
  822. jack_error("sun_driver: AUDIO_GETINFO failed: %s: "
  823. "%s@%i", strerror(errno), __FILE__, __LINE__);
  824. return -1;
  825. }
  826. if (!enc_equal(audio_if_in.record.encoding, driver->format) ||
  827. audio_if_in.record.precision != driver->bits ||
  828. audio_if_in.record.channels != driver->capture_channels ||
  829. audio_if_in.record.sample_rate != driver->sample_rate)
  830. {
  831. jack_error("sun_driver: setting capture parameters "
  832. "failed: %s@%i", __FILE__, __LINE__);
  833. return -1;
  834. }
  835. #if defined(__OpenBSD__)
  836. cap_period = audio_if_in.record.block_size /
  837. driver->capture_channels / driver->sample_bytes;
  838. #elif defined(__NetBSD__)
  839. cap_period = audio_if_in.blocksize /
  840. driver->capture_channels / driver->sample_bytes;
  841. #else
  842. /* how is this done on Solaris? */
  843. cap_period = driver->period_size;
  844. #endif
  845. }
  846. if (outfd >= 0)
  847. {
  848. if (outfd == infd)
  849. {
  850. audio_if_out.play = audio_if_in.play;
  851. }
  852. else
  853. {
  854. if (ioctl(outfd, AUDIO_GETINFO, &audio_if_out) < 0)
  855. {
  856. jack_error("sun_driver: AUDIO_GETINFO failed: "
  857. "%s: %s@%i", strerror(errno),
  858. __FILE__, __LINE__);
  859. return -1;
  860. }
  861. }
  862. if (!enc_equal(audio_if_out.play.encoding, driver->format) ||
  863. audio_if_out.play.precision != driver->bits ||
  864. audio_if_out.play.channels != driver->playback_channels ||
  865. audio_if_out.play.sample_rate != driver->sample_rate)
  866. {
  867. jack_error("sun_driver: playback settings failed: "
  868. "%s@%i", __FILE__, __LINE__);
  869. return -1;
  870. }
  871. #if defined(__OpenBSD__)
  872. play_period = audio_if_out.play.block_size /
  873. driver->playback_channels / driver->sample_bytes;
  874. #elif defined(__NetBSD__)
  875. play_period = audio_if_out.blocksize /
  876. driver->playback_channels / driver->sample_bytes;
  877. #else
  878. /* how is this done on Solaris? */
  879. play_period = driver->period_size;
  880. #endif
  881. }
  882. if (infd >= 0 && outfd >= 0 && play_period != cap_period)
  883. {
  884. jack_error("sun_driver: play and capture periods differ: "
  885. "%s@%i", __FILE__, __LINE__);
  886. return -1;
  887. }
  888. if (infd >= 0)
  889. period_size = cap_period;
  890. else if (outfd >= 0)
  891. period_size = play_period;
  892. if (period_size != 0 && period_size != driver->period_size &&
  893. !driver->ignorehwbuf)
  894. {
  895. printf("sun_driver: period size update: %u\n", period_size);
  896. set_period_size (driver, period_size);
  897. if (driver->engine)
  898. if (driver->engine->set_buffer_size(driver->engine,
  899. driver->period_size)) {
  900. jack_error ("sun_driver: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  901. return -1;
  902. }
  903. }
  904. if (driver->infd >= 0 && driver->capture_channels > 0)
  905. {
  906. driver->indevbufsize = driver->period_size *
  907. driver->capture_channels * driver->sample_bytes;
  908. driver->indevbuf = malloc(driver->indevbufsize);
  909. if (driver->indevbuf == NULL)
  910. {
  911. jack_error( "sun_driver: malloc() failed: %s@%i",
  912. __FILE__, __LINE__);
  913. return -1;
  914. }
  915. bzero(driver->indevbuf, driver->indevbufsize);
  916. }
  917. else
  918. {
  919. driver->indevbufsize = 0;
  920. driver->indevbuf = NULL;
  921. }
  922. if (driver->outfd >= 0 && driver->playback_channels > 0)
  923. {
  924. driver->outdevbufsize = driver->period_size *
  925. driver->playback_channels * driver->sample_bytes;
  926. driver->outdevbuf = malloc(driver->outdevbufsize);
  927. if (driver->outdevbuf == NULL)
  928. {
  929. jack_error("sun_driver: malloc() failed: %s@%i",
  930. __FILE__, __LINE__);
  931. return -1;
  932. }
  933. bzero(driver->outdevbuf, driver->outdevbufsize);
  934. }
  935. else
  936. {
  937. driver->outdevbufsize = 0;
  938. driver->outdevbuf = NULL;
  939. }
  940. printf("sun_driver: indevbuf %zd B, outdevbuf %zd B\n",
  941. driver->indevbufsize, driver->outdevbufsize);
  942. return 0;
  943. }
  944. static int
  945. sun_driver_stop (sun_driver_t *driver)
  946. {
  947. audio_info_t audio_if;
  948. if (driver->infd >= 0)
  949. {
  950. AUDIO_INITINFO(&audio_if);
  951. audio_if.record.pause = 1;
  952. if (driver->outfd == driver->infd)
  953. audio_if.play.pause = 1;
  954. if (ioctl(driver->infd, AUDIO_SETINFO, &audio_if) < 0)
  955. {
  956. jack_error("sun_driver: capture pause failed: %s: "
  957. "%s@%i", strerror(errno), __FILE__, __LINE__);
  958. return -1;
  959. }
  960. }
  961. if ((driver->outfd >= 0) && (driver->outfd != driver->infd))
  962. {
  963. AUDIO_INITINFO(&audio_if);
  964. audio_if.play.pause = 1;
  965. if (ioctl(driver->outfd, AUDIO_SETINFO, &audio_if) < 0)
  966. {
  967. jack_error("sun_driver: playback pause failed: %s: "
  968. "%s@%i", strerror(errno), __FILE__, __LINE__);
  969. return -1;
  970. }
  971. }
  972. return 0;
  973. }
  974. static int
  975. sun_driver_read (sun_driver_t *driver, jack_nframes_t nframes)
  976. {
  977. jack_nframes_t nbytes;
  978. int channel;
  979. ssize_t io_res;
  980. jack_sample_t *portbuf;
  981. JSList *node;
  982. jack_port_t *port;
  983. if (driver->engine->freewheeling || driver->infd < 0)
  984. return 0;
  985. if (nframes > driver->period_size)
  986. {
  987. jack_error("sun_driver: read failed: nframes > period_size: "
  988. "(%u/%u): %s@%i", nframes, driver->period_size,
  989. __FILE__, __LINE__);
  990. return -1;
  991. }
  992. node = driver->capture_ports;
  993. channel = 0;
  994. while (node != NULL)
  995. {
  996. port = (jack_port_t *) node->data;
  997. if (jack_port_connected(port))
  998. {
  999. portbuf = jack_port_get_buffer(port, nframes);
  1000. copy_and_convert_in(portbuf, driver->indevbuf,
  1001. nframes, channel,
  1002. driver->capture_channels,
  1003. driver->bits);
  1004. }
  1005. node = jack_slist_next(node);
  1006. channel++;
  1007. }
  1008. nbytes = nframes * driver->capture_channels * driver->sample_bytes;
  1009. io_res = 0;
  1010. while (nbytes)
  1011. {
  1012. io_res = read(driver->infd, driver->indevbuf, nbytes);
  1013. if (io_res < 0)
  1014. {
  1015. jack_error("sun_driver: read() failed: %s: %s@%i",
  1016. strerror(errno), __FILE__, __LINE__);
  1017. break;
  1018. }
  1019. else
  1020. nbytes -= io_res;
  1021. }
  1022. return 0;
  1023. }
  1024. static int
  1025. sun_driver_write (sun_driver_t *driver, jack_nframes_t nframes)
  1026. {
  1027. jack_nframes_t nbytes;
  1028. int channel;
  1029. ssize_t io_res;
  1030. jack_sample_t *portbuf;
  1031. JSList *node;
  1032. jack_port_t *port;
  1033. if (driver->engine->freewheeling || driver->outfd < 0)
  1034. return 0;
  1035. if (nframes > driver->period_size)
  1036. {
  1037. jack_error("sun_driver: write failed: nframes > period_size "
  1038. "(%u/%u): %s@%i", nframes, driver->period_size,
  1039. __FILE__, __LINE__);
  1040. return -1;
  1041. }
  1042. bzero(driver->outdevbuf, driver->outdevbufsize);
  1043. node = driver->playback_ports;
  1044. channel = 0;
  1045. while (node != NULL)
  1046. {
  1047. port = (jack_port_t *) node->data;
  1048. if (jack_port_connected(port))
  1049. {
  1050. portbuf = jack_port_get_buffer(port, nframes);
  1051. copy_and_convert_out(driver->outdevbuf, portbuf,
  1052. nframes, channel,
  1053. driver->playback_channels,
  1054. driver->bits);
  1055. }
  1056. node = jack_slist_next(node);
  1057. channel++;
  1058. }
  1059. nbytes = nframes * driver->playback_channels * driver->sample_bytes;
  1060. io_res = 0;
  1061. while (nbytes)
  1062. {
  1063. io_res = write(driver->outfd, driver->outdevbuf, nbytes);
  1064. if (io_res < 0)
  1065. {
  1066. jack_error("sun_driver: write() failed: %s: %s@%i",
  1067. strerror(errno), __FILE__, __LINE__);
  1068. break;
  1069. }
  1070. else
  1071. nbytes -= io_res;
  1072. }
  1073. return 0;
  1074. }
  1075. static int
  1076. sun_driver_null_cycle (sun_driver_t *driver, jack_nframes_t nframes)
  1077. {
  1078. if (nframes > driver->period_size)
  1079. {
  1080. jack_error("sun_driver: null cycle failed: "
  1081. "nframes > period_size (%u/%u): %s@%i", nframes,
  1082. driver->period_size, __FILE__, __LINE__);
  1083. return -1;
  1084. }
  1085. printf("sun_driver: running null cycle\n");
  1086. if (driver->outfd >= 0)
  1087. sun_driver_write_silence (driver, nframes);
  1088. if (driver->infd >= 0)
  1089. sun_driver_read_silence (driver, nframes);
  1090. return 0;
  1091. }
  1092. static int
  1093. sun_driver_bufsize (sun_driver_t *driver, jack_nframes_t nframes)
  1094. {
  1095. return sun_driver_set_parameters(driver);
  1096. }
  1097. static void
  1098. sun_driver_delete (sun_driver_t *driver)
  1099. {
  1100. if (driver->outfd >= 0 && driver->outfd != driver->infd)
  1101. {
  1102. close(driver->outfd);
  1103. driver->outfd = -1;
  1104. }
  1105. if (driver->infd >= 0)
  1106. {
  1107. close(driver->infd);
  1108. driver->infd = -1;
  1109. }
  1110. if (driver->indevbuf != NULL)
  1111. {
  1112. free(driver->indevbuf);
  1113. driver->indevbuf = NULL;
  1114. }
  1115. if (driver->outdevbuf != NULL)
  1116. {
  1117. free(driver->outdevbuf);
  1118. driver->outdevbuf = NULL;
  1119. }
  1120. if (driver->indev != NULL)
  1121. free(driver->indev);
  1122. if (driver->outdev != NULL)
  1123. free(driver->outdev);
  1124. jack_driver_nt_finish((jack_driver_nt_t *) driver);
  1125. free(driver);
  1126. }
  1127. void
  1128. driver_finish (jack_driver_t *driver)
  1129. {
  1130. sun_driver_delete ((sun_driver_t *)driver);
  1131. }
  1132. static jack_driver_t *
  1133. sun_driver_new (char *indev, char *outdev, jack_client_t *client,
  1134. jack_nframes_t sample_rate, jack_nframes_t period_size,
  1135. jack_nframes_t nperiods, int bits,
  1136. int capture_channels, int playback_channels,
  1137. jack_nframes_t in_latency, jack_nframes_t out_latency,
  1138. int ignorehwbuf)
  1139. {
  1140. sun_driver_t *driver;
  1141. driver = (sun_driver_t *) malloc(sizeof(sun_driver_t));
  1142. if (driver == NULL)
  1143. {
  1144. jack_error("sun_driver: malloc() failed: %s: %s@%i",
  1145. strerror(errno), __FILE__, __LINE__);
  1146. return NULL;
  1147. }
  1148. driver->engine = NULL;
  1149. jack_driver_nt_init((jack_driver_nt_t *) driver);
  1150. driver->nt_attach = (JackDriverNTAttachFunction) sun_driver_attach;
  1151. driver->nt_detach = (JackDriverNTDetachFunction) sun_driver_detach;
  1152. driver->read = (JackDriverReadFunction) sun_driver_read;
  1153. driver->write = (JackDriverWriteFunction) sun_driver_write;
  1154. driver->null_cycle = (JackDriverNullCycleFunction)
  1155. sun_driver_null_cycle;
  1156. driver->nt_bufsize = (JackDriverNTBufSizeFunction) sun_driver_bufsize;
  1157. driver->nt_start = (JackDriverNTStartFunction) sun_driver_start;
  1158. driver->nt_stop = (JackDriverNTStopFunction) sun_driver_stop;
  1159. driver->nt_run_cycle = (JackDriverNTRunCycleFunction) sun_driver_run_cycle;
  1160. if (indev != NULL)
  1161. driver->indev = strdup(indev);
  1162. if (outdev != NULL)
  1163. driver->outdev = strdup(outdev);
  1164. driver->ignorehwbuf = ignorehwbuf;
  1165. driver->sample_rate = sample_rate;
  1166. driver->period_size = period_size;
  1167. driver->nperiods = nperiods;
  1168. driver->bits = bits;
  1169. driver->capture_channels = capture_channels;
  1170. driver->playback_channels = playback_channels;
  1171. driver->sys_in_latency = in_latency;
  1172. driver->sys_out_latency = out_latency;
  1173. set_period_size(driver, period_size);
  1174. if (driver->indev == NULL)
  1175. driver->indev = strdup(SUN_DRIVER_DEF_DEV);
  1176. if (driver->outdev == NULL)
  1177. driver->outdev = strdup(SUN_DRIVER_DEF_DEV);
  1178. driver->infd = -1;
  1179. driver->outfd = -1;
  1180. #if defined(AUDIO_ENCODING_SLINEAR)
  1181. driver->format = AUDIO_ENCODING_SLINEAR;
  1182. #else
  1183. driver->format = AUDIO_ENCODING_LINEAR;
  1184. #endif
  1185. driver->indevbuf = driver->outdevbuf = NULL;
  1186. driver->capture_ports = NULL;
  1187. driver->playback_ports = NULL;
  1188. driver->iodelay = 0.0F;
  1189. driver->poll_last = driver->poll_next = 0;
  1190. if (sun_driver_set_parameters (driver) < 0)
  1191. {
  1192. free(driver);
  1193. return NULL;
  1194. }
  1195. driver->client = client;
  1196. return (jack_driver_t *) driver;
  1197. }
  1198. /* jack driver published interface */
  1199. const char driver_client_name[] = "sun";
  1200. jack_driver_desc_t *
  1201. driver_get_descriptor ()
  1202. {
  1203. jack_driver_desc_t *desc;
  1204. jack_driver_param_desc_t *params;
  1205. desc = (jack_driver_desc_t *) calloc(1, sizeof(jack_driver_desc_t));
  1206. if (desc == NULL)
  1207. {
  1208. jack_error("sun_driver: calloc() failed: %s: %s@%i",
  1209. strerror(errno), __FILE__, __LINE__);
  1210. return NULL;
  1211. }
  1212. strcpy(desc->name, driver_client_name);
  1213. desc->nparams = SUN_DRIVER_N_PARAMS;
  1214. params = calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
  1215. if (params == NULL)
  1216. {
  1217. jack_error("sun_driver: calloc() failed: %s: %s@%i",
  1218. strerror(errno), __FILE__, __LINE__);
  1219. return NULL;
  1220. }
  1221. memcpy(params, sun_params,
  1222. desc->nparams * sizeof(jack_driver_param_desc_t));
  1223. desc->params = params;
  1224. return desc;
  1225. }
  1226. jack_driver_t *
  1227. driver_initialize (jack_client_t *client, JSList * params)
  1228. {
  1229. int bits = SUN_DRIVER_DEF_BITS;
  1230. jack_nframes_t sample_rate = SUN_DRIVER_DEF_FS;
  1231. jack_nframes_t period_size = SUN_DRIVER_DEF_BLKSIZE;
  1232. jack_nframes_t in_latency = 0;
  1233. jack_nframes_t out_latency = 0;
  1234. unsigned int nperiods = SUN_DRIVER_DEF_NPERIODS;
  1235. unsigned int capture_channels = SUN_DRIVER_DEF_INS;
  1236. unsigned int playback_channels = SUN_DRIVER_DEF_OUTS;
  1237. const JSList *pnode;
  1238. const jack_driver_param_t *param;
  1239. char *indev;
  1240. char *outdev;
  1241. int ignorehwbuf = 0;
  1242. indev = strdup(SUN_DRIVER_DEF_DEV);
  1243. outdev = strdup(SUN_DRIVER_DEF_DEV);
  1244. pnode = params;
  1245. while (pnode != NULL)
  1246. {
  1247. param = (const jack_driver_param_t *) pnode->data;
  1248. switch (param->character)
  1249. {
  1250. case 'r':
  1251. sample_rate = param->value.ui;
  1252. break;
  1253. case 'p':
  1254. period_size = param->value.ui;
  1255. break;
  1256. case 'n':
  1257. nperiods = param->value.ui;
  1258. break;
  1259. case 'w':
  1260. bits = param->value.i;
  1261. break;
  1262. case 'i':
  1263. capture_channels = param->value.ui;
  1264. break;
  1265. case 'o':
  1266. playback_channels = param->value.ui;
  1267. break;
  1268. case 'C':
  1269. indev = strdup(param->value.str);
  1270. break;
  1271. case 'P':
  1272. outdev = strdup(param->value.str);
  1273. break;
  1274. case 'b':
  1275. ignorehwbuf = 1;
  1276. break;
  1277. case 'I':
  1278. in_latency = param->value.ui;
  1279. break;
  1280. case 'O':
  1281. out_latency = param->value.ui;
  1282. break;
  1283. }
  1284. pnode = jack_slist_next(pnode);
  1285. }
  1286. return sun_driver_new (indev, outdev, client, sample_rate, period_size,
  1287. nperiods, bits, capture_channels, playback_channels, in_latency,
  1288. out_latency, ignorehwbuf);
  1289. }