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.

1325 lines
30KB

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