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.

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