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.

998 lines
22KB

  1. /*
  2. * Copyright (c) 2009 Jacob Meuser <jakemsr@sdf.lonestar.org>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <config.h>
  17. #ifndef _REENTRANT
  18. #define _REENTRANT
  19. #endif
  20. #ifndef _THREAD_SAFE
  21. #define _THREAD_SAFE
  22. #endif
  23. #include <sys/types.h>
  24. #include <errno.h>
  25. #include <getopt.h>
  26. #include <poll.h>
  27. #include <sndio.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <unistd.h>
  32. #include <jack/types.h>
  33. #include <internal.h>
  34. #include <engine.h>
  35. #include <jack/thread.h>
  36. #include <sysdeps/time.h>
  37. #include "sndio_driver.h"
  38. #define SNDIO_DRIVER_N_PARAMS 10
  39. const static jack_driver_param_desc_t sndio_params[SNDIO_DRIVER_N_PARAMS] = {
  40. { "rate",
  41. 'r',
  42. JackDriverParamUInt,
  43. { .ui = SNDIO_DRIVER_DEF_FS },
  44. NULL,
  45. "sample rate",
  46. "sample rate"
  47. },
  48. { "period",
  49. 'p',
  50. JackDriverParamUInt,
  51. { .ui = SNDIO_DRIVER_DEF_BLKSIZE },
  52. NULL,
  53. "period size",
  54. "period size"
  55. },
  56. { "nperiods",
  57. 'n',
  58. JackDriverParamUInt,
  59. { .ui = SNDIO_DRIVER_DEF_NPERIODS },
  60. NULL,
  61. "number of periods in buffer",
  62. "number of periods in buffer"
  63. },
  64. { "wordlength",
  65. 'w',
  66. JackDriverParamInt,
  67. { .i = SNDIO_DRIVER_DEF_BITS },
  68. NULL,
  69. "word length",
  70. "word length"
  71. },
  72. { "inchannels",
  73. 'i',
  74. JackDriverParamUInt,
  75. { .ui = SNDIO_DRIVER_DEF_INS },
  76. NULL,
  77. "capture channels",
  78. "capture channels"
  79. },
  80. { "outchannels",
  81. 'o',
  82. JackDriverParamUInt,
  83. { .ui = SNDIO_DRIVER_DEF_OUTS },
  84. NULL,
  85. "playback channels",
  86. "playback channels"
  87. },
  88. { "device",
  89. 'd',
  90. JackDriverParamString,
  91. { },
  92. NULL,
  93. "device",
  94. "device"
  95. },
  96. { "ignorehwbuf",
  97. 'b',
  98. JackDriverParamBool,
  99. { },
  100. NULL,
  101. "ignore hardware period size",
  102. "ignore hardware period size"
  103. },
  104. { "input latency",
  105. 'I',
  106. JackDriverParamUInt,
  107. { .ui = 0 },
  108. NULL,
  109. "system capture latency",
  110. "system capture latency"
  111. },
  112. { "output latency",
  113. 'O',
  114. JackDriverParamUInt,
  115. { .ui = 0 },
  116. NULL,
  117. "system playback latency",
  118. "system playback latency"
  119. }
  120. };
  121. /* internal functions */
  122. static void
  123. set_period_size (sndio_driver_t *driver, jack_nframes_t new_period_size)
  124. {
  125. driver->period_size = new_period_size;
  126. driver->period_usecs =
  127. ((double)driver->period_size /
  128. (double)driver->sample_rate) * 1e6;
  129. driver->last_wait_ust = 0;
  130. driver->poll_timeout = (int)(driver->period_usecs / 666);
  131. }
  132. static void
  133. sndio_driver_write_silence (sndio_driver_t *driver, jack_nframes_t nframes)
  134. {
  135. size_t localsize, io_res, nbytes, offset;
  136. void *localbuf;
  137. localsize = nframes * driver->sample_bytes * driver->playback_channels;
  138. localbuf = malloc(localsize);
  139. if (localbuf == NULL)
  140. {
  141. jack_error("sndio_driver: malloc() failed: %s@%i",
  142. __FILE__, __LINE__);
  143. return;
  144. }
  145. memset(localbuf, 0, localsize);
  146. offset = 0;
  147. nbytes = localsize;
  148. while (nbytes > 0)
  149. {
  150. io_res = sio_write(driver->hdl, localbuf + offset, nbytes);
  151. if (io_res == 0)
  152. {
  153. jack_error("sndio_driver: sio_write() failed: "
  154. "count=%d/%d: %s@%i", io_res, localsize,
  155. __FILE__, __LINE__);
  156. }
  157. offset += io_res;
  158. nbytes -= io_res;
  159. }
  160. free(localbuf);
  161. }
  162. static void
  163. sndio_driver_read_silence (sndio_driver_t *driver, jack_nframes_t nframes)
  164. {
  165. size_t localsize, io_res, nbytes, offset;
  166. void *localbuf;
  167. localsize = nframes * driver->sample_bytes * driver->capture_channels;
  168. localbuf = malloc(localsize);
  169. if (localbuf == NULL)
  170. {
  171. jack_error("sndio_driver: malloc() failed: %s@%i",
  172. __FILE__, __LINE__);
  173. return;
  174. }
  175. offset = 0;
  176. nbytes = localsize;
  177. while (nbytes > 0) {
  178. io_res = sio_read(driver->hdl, localbuf + offset, nbytes);
  179. if (io_res == 0) {
  180. jack_error("sndio_driver: sio_read() failed: "
  181. "count=%d/%d: %s@%i", io_res, nbytes,
  182. __FILE__, __LINE__);
  183. break;
  184. }
  185. offset +=- io_res;
  186. nbytes -= io_res;
  187. }
  188. free(localbuf);
  189. }
  190. static int
  191. sndio_driver_start (sndio_driver_t *driver)
  192. {
  193. if (!sio_start(driver->hdl))
  194. jack_error("sio_start failed: %s@%i",
  195. __FILE__, __LINE__);
  196. /* prime playback buffers */
  197. if (driver->playback_channels > 0)
  198. sndio_driver_write_silence(driver, driver->pprime);
  199. return 0;
  200. }
  201. static int
  202. sndio_driver_set_parameters (sndio_driver_t *driver)
  203. {
  204. struct sio_par par;
  205. unsigned int period_size = 0;
  206. unsigned int nperiods;
  207. int mode = 0;
  208. if (driver->capture_channels > 0)
  209. mode |= SIO_REC;
  210. if (driver->playback_channels > 0)
  211. mode |= SIO_PLAY;
  212. driver->hdl = sio_open(driver->dev, mode, 0);
  213. if (driver->hdl == NULL)
  214. {
  215. jack_error("sndio_driver: failed to open device "
  216. "%s: %s@%i", (driver->dev == NULL) ?
  217. "default" : driver->dev, __FILE__, __LINE__);
  218. return -1;
  219. }
  220. if (driver->bits != 16 && driver->bits != 24 && driver->bits != 32)
  221. {
  222. jack_error("sndio_driver: invalid sample bits");
  223. return -1;
  224. }
  225. sio_initpar(&par);
  226. par.sig = 1;
  227. par.bits = driver->bits;
  228. par.pchan = driver->playback_channels;
  229. par.rchan = driver->capture_channels;
  230. par.rate = driver->sample_rate;
  231. par.appbufsz = driver->period_size * driver->nperiods;
  232. par.round = driver->period_size;
  233. par.xrun = SIO_SYNC;
  234. if (!sio_setpar(driver->hdl, &par))
  235. {
  236. jack_error("sndio_driver: failed to set parameters: %s@%i",
  237. __FILE__, __LINE__);
  238. return -1;
  239. }
  240. if (!sio_getpar(driver->hdl, &par))
  241. {
  242. jack_error("sndio_driver: sio_getpar() failed: %s@%i",
  243. __FILE__, __LINE__);
  244. return -1;
  245. }
  246. if (par.sig != 1 || par.bits != driver->bits ||
  247. par.pchan != driver->playback_channels ||
  248. par.rchan != driver->capture_channels ||
  249. par.rate != driver->sample_rate)
  250. {
  251. jack_error("sndio_driver: setting parameters failed: %s@%i",
  252. __FILE__, __LINE__);
  253. return -1;
  254. }
  255. period_size = par.round;
  256. nperiods = par.appbufsz / par.round;
  257. driver->sample_bytes = par.bps;
  258. driver->pprime = par.bufsz;
  259. if (period_size != 0 && !driver->ignorehwbuf &&
  260. (period_size != driver->period_size ||
  261. nperiods != driver->nperiods))
  262. {
  263. printf("sndio_driver: buffer update: "
  264. "period_size=%u, nperiods=%u\n", period_size, nperiods);
  265. driver->nperiods = nperiods;
  266. set_period_size(driver, period_size);
  267. if (driver->engine)
  268. driver->engine->set_buffer_size(driver->engine,
  269. driver->period_size);
  270. }
  271. driver->capbufsize = 0;
  272. driver->capbuf = NULL;
  273. if (driver->capture_channels != 0)
  274. {
  275. driver->capbufsize = driver->period_size *
  276. driver->capture_channels * driver->sample_bytes;
  277. driver->capbuf = malloc(driver->capbufsize);
  278. if (driver->capbuf == NULL)
  279. {
  280. jack_error("sndio_driver: malloc() failed: %s@%i",
  281. __FILE__, __LINE__);
  282. return -1;
  283. }
  284. memset(driver->capbuf, 0, driver->capbufsize);
  285. }
  286. driver->playbufsize = 0;
  287. driver->playbuf = NULL;
  288. if (driver->playback_channels > 0)
  289. {
  290. driver->playbufsize = driver->period_size *
  291. driver->playback_channels * driver->sample_bytes;
  292. driver->playbuf = malloc(driver->playbufsize);
  293. if (driver->playbuf == NULL)
  294. {
  295. jack_error("sndio_driver: malloc() failed: %s@%i",
  296. __FILE__, __LINE__);
  297. return -1;
  298. }
  299. memset(driver->playbuf, 0, driver->playbufsize);
  300. }
  301. printf("sndio_driver: capbuf %zd B, playbuf %zd B\n",
  302. driver->capbufsize, driver->playbufsize);
  303. return 0;
  304. }
  305. static int
  306. sndio_driver_stop (sndio_driver_t *driver)
  307. {
  308. if (driver->hdl != NULL)
  309. sio_stop(driver->hdl);
  310. return 0;
  311. }
  312. static jack_nframes_t
  313. sndio_driver_wait (sndio_driver_t *driver, int *status, float *iodelay)
  314. {
  315. struct pollfd pfd;
  316. nfds_t snfds, nfds;
  317. jack_time_t poll_ret;
  318. int need_capture, need_playback;
  319. int events, revents;
  320. *status = 0;
  321. *iodelay = 0;
  322. need_capture = need_playback = 0;
  323. if (driver->capture_channels > 0)
  324. need_capture = 1;
  325. if (driver->playback_channels > 0)
  326. need_playback = 1;
  327. if (jack_get_microseconds() > driver->poll_next)
  328. {
  329. /* late. don't count as wakeup delay. */
  330. driver->poll_next = 0;
  331. }
  332. snfds = sio_nfds(driver->hdl);
  333. while (need_capture || need_playback)
  334. {
  335. events = 0;
  336. if (need_capture)
  337. events |= POLLIN;
  338. if (need_playback)
  339. events |= POLLOUT;
  340. if (snfds != sio_pollfd(driver->hdl, &pfd, events)) {
  341. jack_error("sndio_driver: sio_pollfd failed: %s@%i",
  342. __FILE__, __LINE__);
  343. *status = -1;
  344. return 0;
  345. }
  346. nfds = poll(&pfd, snfds, 1000);
  347. if (nfds == -1)
  348. {
  349. jack_error("sndio_driver: poll() error: %s: %s@%i",
  350. strerror(errno), __FILE__, __LINE__);
  351. *status = -1;
  352. return 0;
  353. }
  354. else if (nfds == 0)
  355. {
  356. jack_error("sndio_driver: poll() time out: %s@%i",
  357. __FILE__, __LINE__);
  358. *status = -1;
  359. return 0;
  360. }
  361. revents = sio_revents(driver->hdl, &pfd);
  362. if (revents & (POLLERR | POLLHUP | POLLNVAL))
  363. {
  364. jack_error("sndio_driver: poll() error: %s@%i",
  365. __FILE__, __LINE__);
  366. *status = -1;
  367. return 0;
  368. }
  369. if (revents & POLLIN)
  370. need_capture = 0;
  371. if (revents & POLLOUT)
  372. need_playback = 0;
  373. if (sio_eof(driver->hdl))
  374. {
  375. jack_error("sndio_driver: sio_eof(): %s@%i",
  376. __FILE__, __LINE__);
  377. *status = -1;
  378. return 0;
  379. }
  380. }
  381. poll_ret = jack_get_microseconds();
  382. if (driver->poll_next && poll_ret > driver->poll_next)
  383. *iodelay = poll_ret - driver->poll_next;
  384. driver->poll_next = poll_ret + driver->period_usecs;
  385. driver->engine->transport_cycle_start(driver->engine, poll_ret);
  386. driver->last_wait_ust = poll_ret;
  387. return driver->period_size;
  388. }
  389. static inline int
  390. sndio_driver_run_cycle (sndio_driver_t *driver)
  391. {
  392. jack_nframes_t nframes;
  393. int wait_status;
  394. float iodelay;
  395. nframes = sndio_driver_wait(driver, &wait_status, &iodelay);
  396. if (wait_status < 0)
  397. return -1;
  398. return driver->engine->run_cycle(driver->engine, nframes, iodelay);
  399. }
  400. static void
  401. copy_and_convert_in (jack_sample_t *dst, void *src,
  402. size_t nframes, int channel, int chcount, int bits)
  403. {
  404. int srcidx, dstidx;
  405. signed short *s16src = (signed short *)src;
  406. signed int *s32src = (signed int *)src;
  407. jack_sample_t scale;
  408. srcidx = channel;
  409. switch (bits)
  410. {
  411. case 16:
  412. scale = 1.0f / 0x7fff;
  413. for (dstidx = 0; dstidx < nframes; dstidx++)
  414. {
  415. dst[dstidx] = (jack_sample_t)
  416. s16src[srcidx] * scale;
  417. srcidx += chcount;
  418. }
  419. break;
  420. case 24:
  421. case 32:
  422. scale = 1.0f / 0x7fffffff;
  423. for (dstidx = 0; dstidx < nframes; dstidx++)
  424. {
  425. dst[dstidx] = (jack_sample_t)
  426. s32src[srcidx] * scale;
  427. srcidx += chcount;
  428. }
  429. break;
  430. }
  431. }
  432. static void
  433. copy_and_convert_out (void *dst, jack_sample_t *src,
  434. size_t nframes, int channel, int chcount, int bits)
  435. {
  436. int srcidx;
  437. int dstidx;
  438. signed short *s16dst = (signed short *)dst;
  439. signed int *s32dst = (signed int *)dst;
  440. jack_sample_t scale;
  441. dstidx = channel;
  442. switch (bits)
  443. {
  444. case 16:
  445. scale = 0x7fff;
  446. for (srcidx = 0; srcidx < nframes; srcidx++)
  447. {
  448. s16dst[dstidx] = (signed short)
  449. (src[srcidx] >= 0.0f) ?
  450. (src[srcidx] * scale + 0.5f) :
  451. (src[srcidx] * scale - 0.5f);
  452. dstidx += chcount;
  453. }
  454. break;
  455. case 24:
  456. case 32:
  457. scale = 0x7fffffff;
  458. for (srcidx = 0; srcidx < nframes; srcidx++)
  459. {
  460. s32dst[dstidx] = (signed int)
  461. (src[srcidx] >= 0.0f) ?
  462. (src[srcidx] * scale + 0.5f) :
  463. (src[srcidx] * scale - 0.5f);
  464. dstidx += chcount;
  465. }
  466. break;
  467. }
  468. }
  469. /* jack driver interface */
  470. static int
  471. sndio_driver_attach (sndio_driver_t *driver)
  472. {
  473. int port_flags;
  474. int channel;
  475. char channel_name[64];
  476. jack_port_t *port;
  477. jack_latency_range_t range;
  478. driver->engine->set_buffer_size(driver->engine, driver->period_size);
  479. driver->engine->set_sample_rate(driver->engine, driver->sample_rate);
  480. port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
  481. for (channel = 0; channel < driver->capture_channels; channel++)
  482. {
  483. snprintf(channel_name, sizeof(channel_name),
  484. "capture_%u", channel + 1);
  485. port = jack_port_register(driver->client, channel_name,
  486. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  487. if (port == NULL)
  488. {
  489. jack_error("sndio_driver: cannot register port for %s: "
  490. "%s@%i", channel_name, __FILE__, __LINE__);
  491. break;
  492. }
  493. range.min = range.max = driver->period_size +
  494. driver->sys_cap_latency;
  495. jack_port_set_latency_range(port, JackCaptureLatency, &range);
  496. driver->capture_ports =
  497. jack_slist_append(driver->capture_ports, port);
  498. }
  499. port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
  500. for (channel = 0; channel < driver->playback_channels; channel++)
  501. {
  502. snprintf(channel_name, sizeof(channel_name),
  503. "playback_%u", channel + 1);
  504. port = jack_port_register(driver->client, channel_name,
  505. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  506. if (port == NULL)
  507. {
  508. jack_error("sndio_driver: cannot register port for "
  509. "%s: %s@%i", channel_name, __FILE__, __LINE__);
  510. break;
  511. }
  512. range.min = range.max = driver->period_size +
  513. driver->sys_play_latency;
  514. jack_port_set_latency_range(port, JackPlaybackLatency, &range);
  515. driver->playback_ports =
  516. jack_slist_append(driver->playback_ports, port);
  517. }
  518. return jack_activate(driver->client);
  519. }
  520. static int
  521. sndio_driver_detach (sndio_driver_t *driver)
  522. {
  523. JSList *node;
  524. if (driver->engine == NULL)
  525. return 0;
  526. node = driver->capture_ports;
  527. while (node != NULL)
  528. {
  529. jack_port_unregister(driver->client,
  530. ((jack_port_t *) node->data));
  531. node = jack_slist_next(node);
  532. }
  533. if (driver->capture_ports != NULL)
  534. {
  535. jack_slist_free(driver->capture_ports);
  536. driver->capture_ports = NULL;
  537. }
  538. node = driver->playback_ports;
  539. while (node != NULL)
  540. {
  541. jack_port_unregister(driver->client,
  542. ((jack_port_t *) node->data));
  543. node = jack_slist_next(node);
  544. }
  545. if (driver->playback_ports != NULL)
  546. {
  547. jack_slist_free(driver->playback_ports);
  548. driver->playback_ports = NULL;
  549. }
  550. return 0;
  551. }
  552. static int
  553. sndio_driver_read (sndio_driver_t *driver, jack_nframes_t nframes)
  554. {
  555. jack_nframes_t nbytes, offset;
  556. int channel;
  557. size_t io_res;
  558. jack_sample_t *portbuf;
  559. JSList *node;
  560. jack_port_t *port;
  561. if (driver->engine->freewheeling || driver->capture_channels == 0)
  562. return 0;
  563. if (nframes > driver->period_size)
  564. {
  565. jack_error("sndio_driver: read failed: nframes > period_size: "
  566. "(%u/%u): %s@%i", nframes, driver->period_size,
  567. __FILE__, __LINE__);
  568. return -1;
  569. }
  570. node = driver->capture_ports;
  571. channel = 0;
  572. while (node != NULL)
  573. {
  574. port = (jack_port_t *)node->data;
  575. if (jack_port_connected(port))
  576. {
  577. portbuf = jack_port_get_buffer(port, nframes);
  578. copy_and_convert_in(portbuf, driver->capbuf,
  579. nframes, channel,
  580. driver->capture_channels,
  581. driver->bits);
  582. }
  583. node = jack_slist_next(node);
  584. channel++;
  585. }
  586. io_res = offset = 0;
  587. nbytes = nframes * driver->capture_channels * driver->sample_bytes;
  588. while (nbytes > 0)
  589. {
  590. io_res = sio_read(driver->hdl, driver->capbuf + offset, nbytes);
  591. if (io_res == 0)
  592. {
  593. jack_error("sndio_driver: sio_read() failed: %s@%i",
  594. __FILE__, __LINE__);
  595. break;
  596. }
  597. offset += io_res;
  598. nbytes -= io_res;
  599. }
  600. return 0;
  601. }
  602. static int
  603. sndio_driver_write (sndio_driver_t *driver, jack_nframes_t nframes)
  604. {
  605. jack_nframes_t nbytes;
  606. int channel;
  607. size_t io_res, offset;
  608. jack_sample_t *portbuf;
  609. JSList *node;
  610. jack_port_t *port;
  611. if (driver->engine->freewheeling || driver->playback_channels == 0)
  612. return 0;
  613. if (nframes > driver->period_size)
  614. {
  615. jack_error("sndio_driver: write failed: nframes > period_size "
  616. "(%u/%u): %s@%i", nframes, driver->period_size,
  617. __FILE__, __LINE__);
  618. return -1;
  619. }
  620. node = driver->playback_ports;
  621. channel = 0;
  622. while (node != NULL)
  623. {
  624. port = (jack_port_t *)node->data;
  625. if (jack_port_connected(port))
  626. {
  627. portbuf = jack_port_get_buffer(port, nframes);
  628. copy_and_convert_out(driver->playbuf, portbuf,
  629. nframes, channel,
  630. driver->playback_channels,
  631. driver->bits);
  632. }
  633. node = jack_slist_next(node);
  634. channel++;
  635. }
  636. io_res = offset = 0;
  637. nbytes = nframes * driver->playback_channels * driver->sample_bytes;
  638. while (nbytes > 0)
  639. {
  640. io_res = sio_write(driver->hdl, driver->playbuf + offset, nbytes);
  641. if (io_res == 0)
  642. {
  643. jack_error("sndio_driver: sio_write() failed: %s@%i",
  644. __FILE__, __LINE__);
  645. break;
  646. }
  647. offset += io_res;
  648. nbytes -= io_res;
  649. }
  650. memset(driver->playbuf, 0, driver->playbufsize);
  651. return 0;
  652. }
  653. static int
  654. sndio_driver_null_cycle (sndio_driver_t *driver, jack_nframes_t nframes)
  655. {
  656. if (nframes > driver->period_size)
  657. {
  658. jack_error("sndio_driver: null cycle failed: "
  659. "nframes > period_size (%u/%u): %s@%i", nframes,
  660. driver->period_size, __FILE__, __LINE__);
  661. return -1;
  662. }
  663. printf("sndio_driver: running null cycle\n");
  664. if (driver->playback_channels > 0)
  665. sndio_driver_write_silence (driver, nframes);
  666. if (driver->capture_channels > 0)
  667. sndio_driver_read_silence (driver, nframes);
  668. return 0;
  669. }
  670. static int
  671. sndio_driver_bufsize (sndio_driver_t *driver, jack_nframes_t nframes)
  672. {
  673. return sndio_driver_set_parameters(driver);
  674. }
  675. static void
  676. sndio_driver_delete (sndio_driver_t *driver)
  677. {
  678. if (driver->hdl != NULL)
  679. {
  680. sio_close(driver->hdl);
  681. driver->hdl = NULL;
  682. }
  683. if (driver->capbuf != NULL)
  684. {
  685. free(driver->capbuf);
  686. driver->capbuf = NULL;
  687. }
  688. if (driver->playbuf != NULL)
  689. {
  690. free(driver->playbuf);
  691. driver->playbuf = NULL;
  692. }
  693. if (driver->dev != NULL)
  694. {
  695. free(driver->dev);
  696. driver->dev = NULL;
  697. }
  698. jack_driver_nt_finish((jack_driver_nt_t *) driver);
  699. if (driver != NULL)
  700. {
  701. free(driver);
  702. driver = NULL;
  703. }
  704. }
  705. void
  706. driver_finish (jack_driver_t *driver)
  707. {
  708. sndio_driver_delete((sndio_driver_t *)driver);
  709. }
  710. static jack_driver_t *
  711. sndio_driver_new (char *dev, jack_client_t *client,
  712. jack_nframes_t sample_rate, jack_nframes_t period_size,
  713. jack_nframes_t nperiods, int bits,
  714. int capture_channels, int playback_channels,
  715. jack_nframes_t cap_latency, jack_nframes_t play_latency,
  716. int ignorehwbuf)
  717. {
  718. sndio_driver_t *driver;
  719. driver = (sndio_driver_t *)calloc(1, sizeof(sndio_driver_t));
  720. if (driver == NULL)
  721. {
  722. jack_error("sndio_driver: malloc() failed: %s: %s@%i",
  723. strerror(errno), __FILE__, __LINE__);
  724. return NULL;
  725. }
  726. driver->engine = NULL;
  727. jack_driver_nt_init((jack_driver_nt_t *)driver);
  728. driver->nt_attach = (JackDriverNTAttachFunction)sndio_driver_attach;
  729. driver->nt_detach = (JackDriverNTDetachFunction)sndio_driver_detach;
  730. driver->read = (JackDriverReadFunction)sndio_driver_read;
  731. driver->write = (JackDriverWriteFunction)sndio_driver_write;
  732. driver->null_cycle = (JackDriverNullCycleFunction)sndio_driver_null_cycle;
  733. driver->nt_bufsize = (JackDriverNTBufSizeFunction)sndio_driver_bufsize;
  734. driver->nt_start = (JackDriverNTStartFunction)sndio_driver_start;
  735. driver->nt_stop = (JackDriverNTStopFunction)sndio_driver_stop;
  736. driver->nt_run_cycle = (JackDriverNTRunCycleFunction)sndio_driver_run_cycle;
  737. if (dev != NULL)
  738. driver->dev = strdup(dev);
  739. else
  740. driver->dev = NULL;
  741. driver->ignorehwbuf = ignorehwbuf;
  742. driver->sample_rate = sample_rate;
  743. driver->period_size = period_size;
  744. driver->orig_period_size = period_size;
  745. driver->nperiods = nperiods;
  746. driver->bits = bits;
  747. driver->capture_channels = capture_channels;
  748. driver->playback_channels = playback_channels;
  749. driver->sys_cap_latency = cap_latency;
  750. driver->sys_play_latency = play_latency;
  751. set_period_size(driver, period_size);
  752. driver->hdl = NULL;
  753. driver->capbuf = driver->playbuf = NULL;
  754. driver->capture_ports = driver->playback_ports = NULL;
  755. driver->poll_next = 0;
  756. if (sndio_driver_set_parameters(driver) < 0)
  757. {
  758. free(driver);
  759. return NULL;
  760. }
  761. driver->client = client;
  762. return (jack_driver_t *)driver;
  763. }
  764. /* jack driver published interface */
  765. const char driver_client_name[] = "sndio";
  766. jack_driver_desc_t *
  767. driver_get_descriptor ()
  768. {
  769. jack_driver_desc_t *desc;
  770. jack_driver_param_desc_t *params;
  771. desc = (jack_driver_desc_t *)calloc(1, sizeof(jack_driver_desc_t));
  772. if (desc == NULL)
  773. {
  774. jack_error("sndio_driver: calloc() failed: %s: %s@%i",
  775. strerror(errno), __FILE__, __LINE__);
  776. return NULL;
  777. }
  778. strlcpy(desc->name, driver_client_name, sizeof(desc->name));
  779. desc->nparams = SNDIO_DRIVER_N_PARAMS;
  780. params = calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
  781. if (params == NULL)
  782. {
  783. jack_error("sndio_driver: calloc() failed: %s: %s@%i",
  784. strerror(errno), __FILE__, __LINE__);
  785. return NULL;
  786. }
  787. memcpy(params, sndio_params,
  788. desc->nparams * sizeof(jack_driver_param_desc_t));
  789. desc->params = params;
  790. return desc;
  791. }
  792. jack_driver_t *
  793. driver_initialize (jack_client_t *client, JSList * params)
  794. {
  795. int bits = SNDIO_DRIVER_DEF_BITS;
  796. jack_nframes_t sample_rate = SNDIO_DRIVER_DEF_FS;
  797. jack_nframes_t period_size = SNDIO_DRIVER_DEF_BLKSIZE;
  798. jack_nframes_t cap_latency = 0;
  799. jack_nframes_t play_latency = 0;
  800. unsigned int nperiods = SNDIO_DRIVER_DEF_NPERIODS;
  801. unsigned int capture_channels = SNDIO_DRIVER_DEF_INS;
  802. unsigned int playback_channels = SNDIO_DRIVER_DEF_OUTS;
  803. const JSList *pnode;
  804. const jack_driver_param_t *param;
  805. char *dev = NULL;
  806. int ignorehwbuf = 0;
  807. pnode = params;
  808. while (pnode != NULL)
  809. {
  810. param = (const jack_driver_param_t *)pnode->data;
  811. switch (param->character)
  812. {
  813. case 'r':
  814. sample_rate = param->value.ui;
  815. break;
  816. case 'p':
  817. period_size = param->value.ui;
  818. break;
  819. case 'n':
  820. nperiods = param->value.ui;
  821. break;
  822. case 'w':
  823. bits = param->value.i;
  824. break;
  825. case 'i':
  826. capture_channels = param->value.ui;
  827. break;
  828. case 'o':
  829. playback_channels = param->value.ui;
  830. break;
  831. case 'd':
  832. dev = strdup(param->value.str);
  833. break;
  834. case 'b':
  835. ignorehwbuf = 1;
  836. break;
  837. case 'I':
  838. cap_latency = param->value.ui;
  839. break;
  840. case 'O':
  841. play_latency = param->value.ui;
  842. break;
  843. }
  844. pnode = jack_slist_next(pnode);
  845. }
  846. return sndio_driver_new(dev, client, sample_rate, period_size,
  847. nperiods, bits, capture_channels, playback_channels,
  848. cap_latency, play_latency, ignorehwbuf);
  849. }