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.

1175 lines
26KB

  1. /*
  2. OSS driver for Jack
  3. Copyright (C) 2003-2004 Jussi Laako <jussi@sonarnerd.net>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  15. MA 02111-1307 USA
  16. */
  17. #include <config.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <fcntl.h>
  23. #include <errno.h>
  24. #include <math.h>
  25. #include <float.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <sys/ioctl.h>
  29. #include <sys/soundcard.h>
  30. #include <stdarg.h>
  31. #include <getopt.h>
  32. #include <pthread.h>
  33. #ifdef USE_BARRIER
  34. #include <semaphore.h>
  35. #endif
  36. #include <jack/types.h>
  37. #include <jack/internal.h>
  38. #include <jack/engine.h>
  39. #include <jack/time.h>
  40. #include "oss_driver.h"
  41. #define OSS_DRIVER_N_PARAMS 9
  42. const static jack_driver_param_desc_t oss_params[OSS_DRIVER_N_PARAMS] = {
  43. { "samplerate",
  44. 's',
  45. JackDriverParamUInt,
  46. { .ui = OSS_DRIVER_DEF_FS },
  47. "sample rate",
  48. "sample rate"
  49. },
  50. { "periodsize",
  51. 'b',
  52. JackDriverParamUInt,
  53. { .ui = OSS_DRIVER_DEF_BLKSIZE },
  54. "period size",
  55. "period size"
  56. },
  57. { "wordlength",
  58. 'w',
  59. JackDriverParamInt,
  60. { .i = OSS_DRIVER_DEF_BITS },
  61. "word length",
  62. "word length"
  63. },
  64. { "capturech",
  65. 'c',
  66. JackDriverParamUInt,
  67. { .ui = OSS_DRIVER_DEF_INS },
  68. "capture channels",
  69. "capture channels"
  70. },
  71. { "playbackch",
  72. 'p',
  73. JackDriverParamUInt,
  74. { .ui = OSS_DRIVER_DEF_OUTS },
  75. "playback channels",
  76. "playback channels"
  77. },
  78. { "inputdev",
  79. 'i',
  80. JackDriverParamString,
  81. { .str = "" },
  82. "input device",
  83. "input device"
  84. },
  85. { "outputdev",
  86. 'o',
  87. JackDriverParamString,
  88. { .str = "" },
  89. "output device",
  90. "output device"
  91. },
  92. { "ignorehwbuf",
  93. 'd',
  94. JackDriverParamBool,
  95. { },
  96. "ignore hardware period size",
  97. "ignore hardware period size"
  98. },
  99. { "help",
  100. 'h',
  101. JackDriverParamBool,
  102. { },
  103. "help",
  104. "help"
  105. }
  106. };
  107. /* internal functions */
  108. static void copy_and_convert_in (jack_sample_t *dst, void *src,
  109. size_t nframes, int channel, int chcount, int bits)
  110. {
  111. int srcidx;
  112. int dstidx;
  113. signed short *s16src = (signed short *) src;
  114. signed int *s32src = (signed int *) src;
  115. double *f64src = (double *) src;
  116. jack_sample_t scale;
  117. srcidx = channel;
  118. switch (bits)
  119. {
  120. case 16:
  121. scale = 1.0f / 0x7fff;
  122. for (dstidx = 0; dstidx < nframes; dstidx++)
  123. {
  124. dst[dstidx] = (jack_sample_t)
  125. s16src[srcidx] * scale;
  126. srcidx += chcount;
  127. }
  128. break;
  129. case 24:
  130. scale = 1.0f / 0x7fffff;
  131. for (dstidx = 0; dstidx < nframes; dstidx++)
  132. {
  133. dst[dstidx] = (jack_sample_t)
  134. s32src[srcidx] * scale;
  135. srcidx += chcount;
  136. }
  137. break;
  138. case 32:
  139. scale = 1.0f / 0x7fffffff;
  140. for (dstidx = 0; dstidx < nframes; dstidx++)
  141. {
  142. dst[dstidx] = (jack_sample_t)
  143. s32src[srcidx] * scale;
  144. srcidx += chcount;
  145. }
  146. break;
  147. case 64:
  148. for (dstidx = 0; dstidx < nframes; dstidx++)
  149. {
  150. dst[dstidx] = (jack_sample_t) f64src[srcidx];
  151. srcidx += chcount;
  152. }
  153. break;
  154. }
  155. }
  156. static void copy_and_convert_out (void *dst, jack_sample_t *src,
  157. size_t nframes, int channel, int chcount, int bits)
  158. {
  159. int srcidx;
  160. int dstidx;
  161. signed short *s16dst = (signed short *) dst;
  162. signed int *s32dst = (signed int *) dst;
  163. double *f64dst = (double *) dst;
  164. jack_sample_t scale;
  165. dstidx = channel;
  166. switch (bits)
  167. {
  168. case 16:
  169. scale = 0x7fff;
  170. for (srcidx = 0; srcidx < nframes; srcidx++)
  171. {
  172. s16dst[dstidx] = (signed short)
  173. (src[srcidx] * scale + 0.5f);
  174. dstidx += chcount;
  175. }
  176. break;
  177. case 24:
  178. scale = 0x7fffff;
  179. for (srcidx = 0; srcidx < nframes; srcidx++)
  180. {
  181. s32dst[dstidx] = (signed int)
  182. (src[srcidx] * scale + 0.5f);
  183. dstidx += chcount;
  184. }
  185. break;
  186. case 32:
  187. scale = 0x7fffffff;
  188. for (srcidx = 0; srcidx < nframes; srcidx++)
  189. {
  190. s32dst[dstidx] = (signed int)
  191. (src[srcidx] * scale + 0.5f);
  192. dstidx += chcount;
  193. }
  194. break;
  195. case 64:
  196. for (srcidx = 0; srcidx < nframes; srcidx++)
  197. {
  198. f64dst[dstidx] = (double) src[srcidx];
  199. dstidx += chcount;
  200. }
  201. break;
  202. }
  203. }
  204. static void set_fragment (int fd, int fragsize)
  205. {
  206. int fragcount;
  207. int fragsize_2p;
  208. int fragments;
  209. fragcount = 2;
  210. //fragcount = 3;
  211. //fragcount = 0xffff / fragsize;
  212. fragsize_2p = (int) (log(fragsize) / log(2.0) + 0.5);
  213. fragments = ((fragcount << 16) | (fragsize_2p & 0xffff));
  214. if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragments) < 0)
  215. {
  216. jack_error("OSS: failed to set fragment size: %s@%i",
  217. __FILE__, __LINE__);
  218. }
  219. }
  220. static int get_fragment (int fd)
  221. {
  222. int fragsize;
  223. if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &fragsize) < 0)
  224. {
  225. jack_error("OSS: failed to get fragment size: %s@%i",
  226. __FILE__, __LINE__);
  227. return 0;
  228. }
  229. return fragsize;
  230. }
  231. static void *io_thread (void *);
  232. /* jack driver interface */
  233. static int oss_driver_attach (oss_driver_t *driver, jack_engine_t *engine)
  234. {
  235. int port_flags;
  236. unsigned int channel;
  237. char channel_name[64];
  238. jack_port_t *port;
  239. driver->engine = engine;
  240. engine->set_buffer_size(engine, driver->period_size);
  241. engine->set_sample_rate(engine, driver->sample_rate);
  242. port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
  243. for (channel = 0; channel < driver->capture_channels; channel++)
  244. {
  245. snprintf(channel_name, sizeof(channel_name),
  246. "capture_%u", channel + 1);
  247. port = jack_port_register(driver->client, channel_name,
  248. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  249. if (port == NULL)
  250. {
  251. jack_error("OSS: cannot register port for %s: %s@%i",
  252. channel_name, __FILE__, __LINE__);
  253. break;
  254. }
  255. driver->capture_ports =
  256. jack_slist_append(driver->capture_ports, port);
  257. }
  258. port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
  259. for (channel = 0; channel < driver->playback_channels; channel++)
  260. {
  261. snprintf(channel_name, sizeof(channel_name),
  262. "playback_%u", channel + 1);
  263. port = jack_port_register(driver->client, channel_name,
  264. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  265. if (port == NULL)
  266. {
  267. jack_error("OSS: cannot register port for %s: %s@%i",
  268. channel_name, __FILE__, __LINE__);
  269. break;
  270. }
  271. driver->playback_ports =
  272. jack_slist_append(driver->playback_ports, port);
  273. }
  274. jack_activate(driver->client);
  275. return 0;
  276. }
  277. static int oss_driver_detach (oss_driver_t *driver, jack_engine_t *engine)
  278. {
  279. JSList *node;
  280. if (driver->engine == NULL)
  281. return -1;
  282. node = driver->capture_ports;
  283. while (node != NULL)
  284. {
  285. jack_port_unregister(driver->client,
  286. ((jack_port_t *) node->data));
  287. node = jack_slist_next(node);
  288. }
  289. jack_slist_free(driver->capture_ports);
  290. driver->capture_ports = NULL;
  291. node = driver->playback_ports;
  292. while (node != NULL)
  293. {
  294. jack_port_unregister(driver->client,
  295. ((jack_port_t *) node->data));
  296. node = jack_slist_next(node);
  297. }
  298. jack_slist_free(driver->playback_ports);
  299. driver->playback_ports = NULL;
  300. driver->engine = NULL;
  301. return 0;
  302. }
  303. static int oss_driver_start (oss_driver_t *driver)
  304. {
  305. int format;
  306. int channels;
  307. int samplerate;
  308. int infd = driver->infd;
  309. int outfd = driver->outfd;
  310. unsigned int period_size;
  311. size_t samplesize;
  312. size_t fragsize;
  313. const char *indev = driver->indev;
  314. const char *outdev = driver->outdev;
  315. switch (driver->bits)
  316. {
  317. case 24:
  318. case 32:
  319. samplesize = sizeof(int);
  320. break;
  321. case 64:
  322. samplesize = sizeof(double);
  323. break;
  324. case 16:
  325. default:
  326. samplesize = sizeof(short);
  327. break;
  328. }
  329. if (strcmp(indev, outdev) != 0)
  330. {
  331. if (driver->capture_channels > 0)
  332. {
  333. infd = open(indev, O_RDONLY);
  334. if (infd < 0)
  335. {
  336. jack_error(
  337. "OSS: failed to open input device %s: %s@%i",
  338. indev, __FILE__, __LINE__);
  339. }
  340. fragsize = driver->period_size *
  341. driver->capture_channels * samplesize;
  342. set_fragment(infd, fragsize);
  343. }
  344. else infd = -1;
  345. if (driver->playback_channels > 0)
  346. {
  347. outfd = open(outdev, O_WRONLY);
  348. if (outfd < 0)
  349. {
  350. jack_error(
  351. "OSS: failed to open output device %s: %s@%i",
  352. outdev, __FILE__, __LINE__);
  353. }
  354. fragsize = driver->period_size *
  355. driver->playback_channels * samplesize;
  356. set_fragment(outfd, fragsize);
  357. }
  358. else outfd = -1;
  359. }
  360. else
  361. {
  362. if (driver->capture_channels != 0 &&
  363. driver->playback_channels == 0)
  364. {
  365. infd = open(indev, O_RDWR);
  366. outfd = -1;
  367. if (infd < 0)
  368. {
  369. jack_error(
  370. "OSS: failed to open device %s: %s@%i",
  371. indev, __FILE__, __LINE__);
  372. return -1;
  373. }
  374. }
  375. else if (driver->capture_channels == 0 &&
  376. driver->playback_channels != 0)
  377. {
  378. infd = -1;
  379. outfd = open(outdev, O_RDWR);
  380. if (outfd < 0)
  381. {
  382. jack_error(
  383. "OSS: failed to open device %s: %s@%i",
  384. outdev, __FILE__, __LINE__);
  385. return -1;
  386. }
  387. }
  388. else
  389. {
  390. infd = outfd = open(indev, O_RDWR);
  391. if (infd < 0)
  392. {
  393. jack_error(
  394. "OSS: failed to open device %s: %s@%i",
  395. indev, __FILE__, __LINE__);
  396. return -1;
  397. }
  398. }
  399. if (infd >= 0 && outfd >= 0)
  400. {
  401. if (ioctl(infd, SNDCTL_DSP_SETDUPLEX, 0) < 0)
  402. {
  403. jack_error(
  404. "OSS: failed to enable full duplex for %s: %s@%i",
  405. indev, __FILE__, __LINE__);
  406. }
  407. }
  408. if (infd >= 0)
  409. {
  410. fragsize = driver->period_size *
  411. driver->capture_channels * samplesize;
  412. set_fragment(infd, fragsize);
  413. }
  414. if (outfd >= 0 && infd < 0)
  415. {
  416. fragsize = driver->period_size *
  417. driver->playback_channels * samplesize;
  418. set_fragment(outfd, fragsize);
  419. }
  420. }
  421. driver->infd = infd;
  422. driver->outfd = outfd;
  423. if (infd >= 0)
  424. {
  425. format = driver->format;
  426. if (ioctl(infd, SNDCTL_DSP_SETFMT, &format) < 0)
  427. jack_error(
  428. "OSS: failed to set format for %s: %s@%i",
  429. indev, __FILE__, __LINE__);
  430. channels = driver->capture_channels;
  431. if (ioctl(infd, SNDCTL_DSP_CHANNELS, &channels) < 0)
  432. jack_error(
  433. "OSS: failed to set channels for %s: %s@%i",
  434. indev, __FILE__, __LINE__);
  435. samplerate = driver->sample_rate;
  436. if (ioctl(infd, SNDCTL_DSP_SPEED, &samplerate) < 0)
  437. jack_error(
  438. "OSS: failed to set samplerate for %s: %s@%i",
  439. indev, __FILE__, __LINE__);
  440. printf("oss_driver: %s : 0x%x/%i/%i (%i)\n", indev,
  441. format, channels, samplerate, get_fragment(infd));
  442. period_size = get_fragment(infd) / samplesize / channels;
  443. if (period_size != driver->period_size &&
  444. !driver->ignorehwbuf)
  445. {
  446. printf("oss_driver: period size update: %u\n",
  447. period_size);
  448. driver->period_size = period_size;
  449. driver->period_usecs =
  450. ((double) driver->period_size /
  451. (double) driver->sample_rate) * 1e6;
  452. driver->engine->set_buffer_size(driver->engine,
  453. driver->period_size);
  454. }
  455. }
  456. if (outfd >= 0 && infd != outfd)
  457. {
  458. format = driver->format;
  459. if (ioctl(outfd, SNDCTL_DSP_SETFMT, &format) < 0)
  460. jack_error(
  461. "OSS: failed to set format for %s: %s@%i",
  462. outdev, __FILE__, __LINE__);
  463. channels = driver->playback_channels;
  464. if (ioctl(outfd, SNDCTL_DSP_CHANNELS, &channels) < 0)
  465. jack_error(
  466. "OSS: failed to set channels for %s: %s@%i",
  467. outdev, __FILE__, __LINE__);
  468. samplerate = driver->sample_rate;
  469. if (ioctl(outfd, SNDCTL_DSP_SPEED, &samplerate) < 0)
  470. jack_error(
  471. "OSS: failed to set samplerate for %s: %s@%i",
  472. outdev, __FILE__, __LINE__);
  473. printf("oss_driver: %s : 0x%x/%i/%i (%i)\n", outdev,
  474. format, channels, samplerate,
  475. get_fragment(outfd));
  476. period_size = get_fragment(outfd) / samplesize / channels;
  477. if (period_size != driver->period_size &&
  478. !driver->ignorehwbuf)
  479. {
  480. printf("oss_driver: period size update: %u\n",
  481. period_size);
  482. driver->period_size = period_size;
  483. driver->period_usecs =
  484. ((double) driver->period_size /
  485. (double) driver->sample_rate) * 1e6;
  486. driver->engine->set_buffer_size(driver->engine,
  487. driver->period_size);
  488. }
  489. }
  490. if (driver->capture_channels > 0)
  491. {
  492. driver->indevbufsize = driver->period_size *
  493. driver->capture_channels * samplesize;
  494. driver->indevbuf = malloc(driver->indevbufsize);
  495. if (driver->indevbuf == NULL)
  496. {
  497. jack_error( "OSS: malloc() failed: %s@%i",
  498. __FILE__, __LINE__);
  499. return -1;
  500. }
  501. memset(driver->indevbuf, 0x00, driver->indevbufsize);
  502. }
  503. else
  504. {
  505. driver->indevbufsize = 0;
  506. driver->indevbuf = NULL;
  507. }
  508. if (driver->playback_channels > 0)
  509. {
  510. driver->outdevbufsize = driver->period_size *
  511. driver->playback_channels * samplesize;
  512. driver->outdevbuf = malloc(driver->outdevbufsize);
  513. if (driver->outdevbuf == NULL)
  514. {
  515. jack_error("OSS: malloc() failed: %s@%i",
  516. __FILE__, __LINE__);
  517. return -1;
  518. }
  519. memset(driver->outdevbuf, 0x00, driver->outdevbufsize);
  520. }
  521. else
  522. {
  523. driver->outdevbufsize = 0;
  524. driver->outdevbuf = NULL;
  525. }
  526. printf("oss_driver: indevbuf %u B, outdevbuf %u B\n",
  527. driver->indevbufsize, driver->outdevbufsize);
  528. pthread_mutex_init(&driver->mutex_in, NULL);
  529. pthread_mutex_init(&driver->mutex_out, NULL);
  530. # ifdef USE_BARRIER
  531. pthread_barrier_init(&driver->barrier, NULL, 2);
  532. sem_init(&driver->sem_start, 0, 0);
  533. # endif
  534. driver->run = 1;
  535. driver->threads = 0;
  536. if (infd >= 0)
  537. {
  538. if (pthread_create(&driver->thread_in, NULL, io_thread,
  539. driver) < 0)
  540. {
  541. jack_error("OSS: pthread_create() failed: %s@%i",
  542. __FILE__, __LINE__);
  543. return -1;
  544. }
  545. driver->threads |= 1;
  546. }
  547. # ifdef USE_BARRIER
  548. if (outfd >= 0)
  549. # else
  550. if (outfd >= 0 && infd != outfd)
  551. # endif
  552. {
  553. if (pthread_create(&driver->thread_out, NULL, io_thread,
  554. driver) < 0)
  555. {
  556. jack_error("OSS: pthread_create() failed: %s@%i",
  557. __FILE__, __LINE__);
  558. return -1;
  559. }
  560. driver->threads |= 2;
  561. }
  562. # ifdef USE_BARRIER
  563. sem_post(&driver->sem_start);
  564. sem_post(&driver->sem_start);
  565. # endif
  566. return 0;
  567. }
  568. static int oss_driver_stop (oss_driver_t *driver)
  569. {
  570. void *retval;
  571. driver->run = 0;
  572. if (driver->threads & 1)
  573. {
  574. if (pthread_join(driver->thread_in, &retval) < 0)
  575. {
  576. jack_error("OSS: pthread_join() failed: %s@%i",
  577. __FILE__, __LINE__);
  578. return -1;
  579. }
  580. }
  581. if (driver->threads & 2)
  582. {
  583. if (pthread_join(driver->thread_out, &retval) < 0)
  584. {
  585. jack_error("OSS: pthread_join() failed: %s@%i",
  586. __FILE__, __LINE__);
  587. return -1;
  588. }
  589. }
  590. # ifdef USE_BARRIER
  591. sem_destroy(&driver->sem_start);
  592. pthread_barrier_destroy(&driver->barrier);
  593. # endif
  594. pthread_mutex_destroy(&driver->mutex_in);
  595. pthread_mutex_destroy(&driver->mutex_out);
  596. if (driver->outfd >= 0 && driver->outfd != driver->infd)
  597. {
  598. close(driver->outfd);
  599. driver->outfd = -1;
  600. }
  601. if (driver->infd >= 0)
  602. {
  603. close(driver->infd);
  604. driver->infd = -1;
  605. }
  606. if (driver->indevbuf != NULL)
  607. {
  608. free(driver->indevbuf);
  609. driver->indevbuf = NULL;
  610. }
  611. if (driver->outdevbuf != NULL)
  612. {
  613. free(driver->outdevbuf);
  614. driver->outdevbuf = NULL;
  615. }
  616. return 0;
  617. }
  618. static int oss_driver_read (oss_driver_t *driver, jack_nframes_t nframes)
  619. {
  620. int channel;
  621. jack_sample_t *portbuf;
  622. JSList *node;
  623. jack_port_t *port;
  624. if (nframes != driver->period_size)
  625. {
  626. jack_error(
  627. "OSS: read failed nframes != period_size (%u/%u): %s@%i",
  628. nframes, driver->period_size, __FILE__, __LINE__);
  629. return -1;
  630. }
  631. pthread_mutex_lock(&driver->mutex_in);
  632. node = driver->capture_ports;
  633. channel = 0;
  634. while (node != NULL)
  635. {
  636. port = (jack_port_t *) node->data;
  637. if (jack_port_connected(port))
  638. {
  639. portbuf = jack_port_get_buffer(port, nframes);
  640. copy_and_convert_in(portbuf, driver->indevbuf,
  641. nframes, channel,
  642. driver->capture_channels,
  643. driver->bits);
  644. }
  645. node = jack_slist_next(node);
  646. channel++;
  647. }
  648. pthread_mutex_unlock(&driver->mutex_in);
  649. return 0;
  650. }
  651. static int oss_driver_write (oss_driver_t *driver, jack_nframes_t nframes)
  652. {
  653. int channel;
  654. jack_sample_t *portbuf;
  655. JSList *node;
  656. jack_port_t *port;
  657. if (nframes != driver->period_size)
  658. {
  659. jack_error(
  660. "OSS: write failed nframes != period_size (%u/%u): %s@%i",
  661. nframes, driver->period_size, __FILE__, __LINE__);
  662. return -1;
  663. }
  664. pthread_mutex_lock(&driver->mutex_out);
  665. node = driver->playback_ports;
  666. channel = 0;
  667. while (node != NULL)
  668. {
  669. port = (jack_port_t *) node->data;
  670. if (jack_port_connected(port))
  671. {
  672. portbuf = jack_port_get_buffer(port, nframes);
  673. copy_and_convert_out(driver->outdevbuf, portbuf,
  674. nframes, channel,
  675. driver->playback_channels,
  676. driver->bits);
  677. }
  678. node = jack_slist_next(node);
  679. channel++;
  680. }
  681. pthread_mutex_unlock(&driver->mutex_out);
  682. return 0;
  683. }
  684. static int oss_driver_null_cycle (oss_driver_t *driver, jack_nframes_t nframes)
  685. {
  686. pthread_mutex_lock(&driver->mutex_in);
  687. memset(driver->indevbuf, 0x00, driver->indevbufsize);
  688. pthread_mutex_unlock(&driver->mutex_in);
  689. pthread_mutex_lock(&driver->mutex_out);
  690. memset(driver->outdevbuf, 0x00, driver->outdevbufsize);
  691. pthread_mutex_unlock(&driver->mutex_out);
  692. return 0;
  693. }
  694. static int oss_driver_bufsize (oss_driver_t *driver, jack_nframes_t nframes)
  695. {
  696. oss_driver_stop(driver);
  697. driver->period_size = nframes;
  698. driver->period_usecs =
  699. ((double) driver->period_size /
  700. (double) driver->sample_rate) * 1e6;
  701. printf("oss_driver: period size update: %u\n", driver->period_size);
  702. oss_driver_start(driver);
  703. return 0;
  704. }
  705. /* internal driver thread */
  706. static inline void start_process_cycle (oss_driver_t *driver)
  707. {
  708. driver->last_wait_ust = jack_get_microseconds();
  709. driver->engine->transport_cycle_start(driver->engine,
  710. driver->last_wait_ust);
  711. /* what is the actual delay value? (not zero) */
  712. driver->engine->run_cycle(driver->engine,
  713. driver->period_size, 0);
  714. }
  715. #ifdef USE_BARRIER
  716. static inline void synchronize (oss_driver_t *driver)
  717. {
  718. if (driver->threads == 3)
  719. {
  720. if (pthread_barrier_wait(&driver->barrier) ==
  721. PTHREAD_BARRIER_SERIAL_THREAD)
  722. {
  723. start_process_cycle(driver);
  724. }
  725. }
  726. else
  727. {
  728. start_process_cycle(driver);
  729. }
  730. }
  731. #endif
  732. static void *io_thread (void *param)
  733. {
  734. int schedpol;
  735. size_t localsize;
  736. void *localbuf;
  737. oss_driver_t *driver = (oss_driver_t *) param;
  738. struct sched_param schedp;
  739. if (pthread_getschedparam(pthread_self(), &schedpol, &schedp) == 0)
  740. {
  741. schedpol = SCHED_FIFO;
  742. schedp.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
  743. if (pthread_setschedparam(pthread_self(), schedpol,
  744. &schedp) < 0)
  745. {
  746. puts("oss_driver: pthread_setschedparam() failed\n");
  747. }
  748. }
  749. else
  750. {
  751. puts("oss_driver: pthread_getschedparam() failed\n");
  752. }
  753. # ifdef USE_BARRIER
  754. sem_wait(&driver->sem_start);
  755. if (pthread_self() == driver->thread_in)
  756. {
  757. localsize = driver->indevbufsize;
  758. localbuf = malloc(localsize);
  759. if (localbuf == NULL)
  760. {
  761. jack_error("OSS: malloc() failed: %s@%i",
  762. __FILE__, __LINE__);
  763. return NULL;
  764. }
  765. while (driver->run)
  766. {
  767. if (read(driver->infd, localbuf, localsize) <
  768. (ssize_t) localsize)
  769. {
  770. /*jack_error("OSS: read() failed: %s@%i",
  771. __FILE__, __LINE__);*/
  772. break;
  773. }
  774. pthread_mutex_lock(&driver->mutex_in);
  775. memcpy(driver->indevbuf, localbuf, localsize);
  776. pthread_mutex_unlock(&driver->mutex_in);
  777. synchronize(driver);
  778. }
  779. free(localbuf);
  780. }
  781. else if (pthread_self() == driver->thread_out)
  782. {
  783. localsize = driver->outdevbufsize;
  784. localbuf = malloc(localsize);
  785. if (localbuf == NULL)
  786. {
  787. jack_error("OSS: malloc() failed: %s@%i",
  788. __FILE__, __LINE__);
  789. return NULL;
  790. }
  791. while (driver->run)
  792. {
  793. pthread_mutex_lock(&driver->mutex_out);
  794. memcpy(localbuf, driver->outdevbuf, localsize);
  795. pthread_mutex_unlock(&driver->mutex_out);
  796. if (write(driver->outfd, localbuf, localsize) <
  797. (ssize_t) localsize)
  798. {
  799. /*jack_error("OSS: write() failed: %s@%i",
  800. __FILE__, __LINE__);*/
  801. break;
  802. }
  803. synchronize(driver);
  804. }
  805. free(localbuf);
  806. }
  807. # else
  808. localsize = (driver->indevbufsize >= driver->outdevbufsize) ?
  809. driver->indevbufsize : driver->outdevbufsize;
  810. localbuf = malloc(localsize);
  811. if (localbuf == NULL)
  812. {
  813. jack_error("OSS: malloc() failed: %s@%i", __FILE__, __LINE__);
  814. return NULL;
  815. }
  816. while (driver->run)
  817. {
  818. if (driver->playback_channels > 0)
  819. {
  820. pthread_mutex_lock(&driver->mutex_out);
  821. memcpy(localbuf, driver->outdevbuf,
  822. driver->outdevbufsize);
  823. pthread_mutex_unlock(&driver->mutex_out);
  824. if (write(driver->outfd, localbuf,
  825. driver->outdevbufsize) <
  826. (ssize_t) driver->outdevbufsize)
  827. {
  828. jack_error("OSS: write() failed: %s@%i",
  829. __FILE__, __LINE__);
  830. break;
  831. }
  832. }
  833. if (driver->capture_channels > 0)
  834. {
  835. if (read(driver->infd, localbuf,
  836. driver->indevbufsize) <
  837. (ssize_t) driver->indevbufsize)
  838. {
  839. jack_error("OSS: read() failed: %s@%i",
  840. __FILE__, __LINE__);
  841. break;
  842. }
  843. pthread_mutex_lock(&driver->mutex_in);
  844. memcpy(driver->indevbuf, localbuf,
  845. driver->indevbufsize);
  846. pthread_mutex_unlock(&driver->mutex_in);
  847. }
  848. start_process_cycle(driver);
  849. }
  850. free(localbuf);
  851. # endif
  852. return NULL;
  853. }
  854. /* jack driver published interface */
  855. const char driver_client_name[] = "oss";
  856. void driver_finish (jack_driver_t *);
  857. jack_driver_desc_t * driver_get_descriptor ()
  858. {
  859. jack_driver_desc_t *desc;
  860. jack_driver_param_desc_t *params;
  861. desc = (jack_driver_desc_t *) calloc(1, sizeof(jack_driver_desc_t));
  862. if (desc == NULL)
  863. {
  864. printf("oss_driver: malloc() failed: %s@%i\n",
  865. __FILE__, __LINE__);
  866. return NULL;
  867. }
  868. strcpy(desc->name, driver_client_name);
  869. desc->nparams = 8;
  870. params = calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
  871. memcpy(params, oss_params,
  872. OSS_DRIVER_N_PARAMS * sizeof(jack_driver_param_desc_t));
  873. desc->params = params;
  874. return desc;
  875. }
  876. jack_driver_t * driver_initialize (jack_client_t *client,
  877. JSList * params)
  878. {
  879. int bits = OSS_DRIVER_DEF_BITS;
  880. jack_nframes_t sample_rate = OSS_DRIVER_DEF_FS;
  881. jack_nframes_t period_size = OSS_DRIVER_DEF_BLKSIZE;
  882. unsigned int capture_channels = OSS_DRIVER_DEF_INS;
  883. unsigned int playback_channels = OSS_DRIVER_DEF_OUTS;
  884. const JSList *pnode;
  885. const jack_driver_param_t *param;
  886. oss_driver_t *driver;
  887. driver = (oss_driver_t *) malloc(sizeof(oss_driver_t));
  888. if (driver == NULL)
  889. {
  890. jack_error("OSS: malloc() failed: %s@%i", __FILE__, __LINE__);
  891. return NULL;
  892. }
  893. jack_driver_init((jack_driver_t *) driver);
  894. driver->attach = (JackDriverAttachFunction) oss_driver_attach;
  895. driver->detach = (JackDriverDetachFunction) oss_driver_detach;
  896. driver->start = (JackDriverStartFunction) oss_driver_start;
  897. driver->stop = (JackDriverStopFunction) oss_driver_stop;
  898. driver->read = (JackDriverReadFunction) oss_driver_read;
  899. driver->write = (JackDriverWriteFunction) oss_driver_write;
  900. driver->null_cycle = (JackDriverNullCycleFunction)
  901. oss_driver_null_cycle;
  902. driver->bufsize = (JackDriverBufSizeFunction) oss_driver_bufsize;
  903. driver->indev = NULL;
  904. driver->outdev = NULL;
  905. driver->ignorehwbuf = 0;
  906. pnode = params;
  907. while (pnode != NULL)
  908. {
  909. param = (const jack_driver_param_t *) pnode->data;
  910. switch (param->character)
  911. {
  912. case 's':
  913. sample_rate = param->value.ui;
  914. break;
  915. case 'b':
  916. period_size = param->value.ui;
  917. break;
  918. case 'w':
  919. bits = param->value.i;
  920. break;
  921. case 'c':
  922. capture_channels = param->value.ui;
  923. break;
  924. case 'p':
  925. playback_channels = param->value.ui;
  926. break;
  927. case 'i':
  928. driver->indev = strdup(param->value.str);
  929. break;
  930. case 'o':
  931. driver->outdev = strdup(param->value.str);
  932. break;
  933. case 'd':
  934. driver->ignorehwbuf = 1;
  935. break;
  936. case 'h':
  937. puts("-s <fs>\tsample rate");
  938. puts("-b <size>\tperiod size");
  939. puts("-w <bits>\tword length");
  940. puts("-c <chs>\tcapture channels");
  941. puts("-p <chs>\tplayback channels");
  942. puts("-i <dev>\tcapture device");
  943. puts("-o <dev>\tplayback device");
  944. puts("-h\tthis help");
  945. break;
  946. }
  947. pnode = jack_slist_next(pnode);
  948. }
  949. driver->sample_rate = sample_rate;
  950. driver->period_size = period_size;
  951. driver->bits = bits;
  952. driver->capture_channels = capture_channels;
  953. driver->playback_channels = playback_channels;
  954. driver->period_usecs =
  955. ((double) period_size / (double) sample_rate) * 1e6;
  956. driver->last_wait_ust = 0;
  957. driver->finish = driver_finish;
  958. if (driver->indev == NULL)
  959. driver->indev = strdup("/dev/dsp");
  960. if (driver->outdev == NULL)
  961. driver->outdev = strdup(driver->indev);
  962. driver->infd = -1;
  963. driver->outfd = -1;
  964. switch (driver->bits)
  965. {
  966. # ifndef OSS_ENDIAN
  967. # ifdef __GNUC__
  968. # if (defined(__i386__) || defined(__alpha__) || defined(__arm__) || defined(__x86_64__))
  969. # define OSS_LITTLE_ENDIAN 1234
  970. # define OSS_ENDIAN OSS_LITTLE_ENDIAN
  971. # else
  972. # define OSS_BIG_ENDIAN 4321
  973. # define OSS_ENDIAN OSS_BIG_ENDIAN
  974. # endif
  975. # else /* __GNUC__ */
  976. # if (defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__))
  977. # define OSS_BIG_ENDIAN 4321
  978. # define OSS_ENDIAN OSS_BIG_ENDIAN
  979. # else
  980. # define OSS_LITTLE_ENDIAN 1234
  981. # define OSS_ENDIAN OSS_LITTLE_ENDIAN
  982. # endif
  983. # endif /* __GNUC__ */
  984. # endif /* OSS_ENDIAN */
  985. # if (OSS_ENDIAN == 1234)
  986. /* little-endian architectures */
  987. case 24: /* little-endian LSB aligned 24-bits in 32-bits integer */
  988. driver->format = 0x00008000;
  989. break;
  990. case 32: /* little-endian 32-bit integer */
  991. driver->format = 0x00001000;
  992. break;
  993. case 64: /* native-endian 64-bit float */
  994. driver->format = 0x00004000;
  995. break;
  996. case 16: /* little-endian 16-bit integer */
  997. default:
  998. driver->format = 0x00000010;
  999. break;
  1000. /* big-endian architectures */
  1001. # else
  1002. case 24: /* big-endian LSB aligned 24-bits in 32-bits integer */
  1003. break;
  1004. driver->format = 0x00010000;
  1005. case 32: /* big-endian 32-bit integer */
  1006. driver->format = 0x00002000;
  1007. break;
  1008. case 64: /* native-endian 64-bit float */
  1009. driver->format = 0x00004000;
  1010. break;
  1011. case 16: /* big-endian 16-bit integer */
  1012. default:
  1013. driver->format = 0x00000020;
  1014. # endif
  1015. }
  1016. driver->indevbuf = driver->outdevbuf = NULL;
  1017. driver->capture_ports = NULL;
  1018. driver->playback_ports = NULL;
  1019. driver->engine = NULL;
  1020. driver->client = client;
  1021. return ((jack_driver_t *) driver);
  1022. }
  1023. void driver_finish (jack_driver_t *driver)
  1024. {
  1025. free(((oss_driver_t *) driver)->indev);
  1026. free(((oss_driver_t *) driver)->outdev);
  1027. free(driver);
  1028. }