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.

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