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.

1306 lines
30KB

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