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.

1379 lines
35KB

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