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.

1318 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. if (engine->set_buffer_size(engine, driver->period_size)) {
  315. jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  316. return -1;
  317. }
  318. engine->set_sample_rate(engine, driver->sample_rate);
  319. port_flags = JackPortIsOutput|JackPortIsPhysical|JackPortIsTerminal;
  320. for (channel = 0; channel < driver->capture_channels; channel++)
  321. {
  322. snprintf(channel_name, sizeof(channel_name),
  323. "capture_%u", channel + 1);
  324. port = jack_port_register(driver->client, channel_name,
  325. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  326. if (port == NULL)
  327. {
  328. jack_error("OSS: cannot register port for %s: %s@%i",
  329. channel_name, __FILE__, __LINE__);
  330. break;
  331. }
  332. jack_port_set_latency(port,
  333. driver->period_size + driver->sys_in_latency);
  334. driver->capture_ports =
  335. jack_slist_append(driver->capture_ports, port);
  336. }
  337. port_flags = JackPortIsInput|JackPortIsPhysical|JackPortIsTerminal;
  338. for (channel = 0; channel < driver->playback_channels; channel++)
  339. {
  340. snprintf(channel_name, sizeof(channel_name),
  341. "playback_%u", channel + 1);
  342. port = jack_port_register(driver->client, channel_name,
  343. JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
  344. if (port == NULL)
  345. {
  346. jack_error("OSS: cannot register port for %s: %s@%i",
  347. channel_name, __FILE__, __LINE__);
  348. break;
  349. }
  350. jack_port_set_latency(port,
  351. driver->period_size + driver->sys_out_latency);
  352. driver->playback_ports =
  353. jack_slist_append(driver->playback_ports, port);
  354. }
  355. jack_activate(driver->client);
  356. return 0;
  357. }
  358. static int oss_driver_detach (oss_driver_t *driver, jack_engine_t *engine)
  359. {
  360. JSList *node;
  361. if (driver->engine == NULL)
  362. return -1;
  363. /*jack_deactivate(driver->client);*/ /* ? */
  364. node = driver->capture_ports;
  365. while (node != NULL)
  366. {
  367. jack_port_unregister(driver->client,
  368. ((jack_port_t *) node->data));
  369. node = jack_slist_next(node);
  370. }
  371. jack_slist_free(driver->capture_ports);
  372. driver->capture_ports = NULL;
  373. node = driver->playback_ports;
  374. while (node != NULL)
  375. {
  376. jack_port_unregister(driver->client,
  377. ((jack_port_t *) node->data));
  378. node = jack_slist_next(node);
  379. }
  380. jack_slist_free(driver->playback_ports);
  381. driver->playback_ports = NULL;
  382. driver->engine = NULL;
  383. return 0;
  384. }
  385. static int oss_driver_start (oss_driver_t *driver)
  386. {
  387. int flags = 0;
  388. int format;
  389. int channels;
  390. int samplerate;
  391. int infd = driver->infd;
  392. int outfd = driver->outfd;
  393. unsigned int period_size;
  394. size_t samplesize;
  395. size_t fragsize;
  396. const char *indev = driver->indev;
  397. const char *outdev = driver->outdev;
  398. switch (driver->bits)
  399. {
  400. case 24:
  401. case 32:
  402. samplesize = sizeof(int);
  403. break;
  404. case 64:
  405. samplesize = sizeof(double);
  406. break;
  407. case 16:
  408. default:
  409. samplesize = sizeof(short);
  410. break;
  411. }
  412. driver->trigger = 0;
  413. if (strcmp(indev, outdev) != 0)
  414. {
  415. if (driver->capture_channels > 0)
  416. {
  417. infd = open(indev, O_RDONLY|O_EXCL);
  418. if (infd < 0)
  419. {
  420. jack_error(
  421. "OSS: failed to open input device %s: %s@%i, errno=%d",
  422. indev, __FILE__, __LINE__, errno);
  423. }
  424. #ifndef OSS_NO_COOKED_MODE
  425. ioctl(infd, SNDCTL_DSP_COOKEDMODE, &flags);
  426. #endif
  427. fragsize = driver->period_size *
  428. driver->capture_channels * samplesize;
  429. set_fragment(infd, fragsize, driver->nperiods);
  430. }
  431. else infd = -1;
  432. if (driver->playback_channels > 0)
  433. {
  434. outfd = open(outdev, O_WRONLY|O_EXCL);
  435. if (outfd < 0)
  436. {
  437. jack_error(
  438. "OSS: failed to open output device %s: %s@%i, errno=%d",
  439. outdev, __FILE__, __LINE__, errno);
  440. }
  441. #ifndef OSS_NO_COOKED_MODE
  442. ioctl(outfd, SNDCTL_DSP_COOKEDMODE, &flags);
  443. #endif
  444. fragsize = driver->period_size *
  445. driver->playback_channels * samplesize;
  446. set_fragment(outfd, fragsize, driver->nperiods);
  447. }
  448. else outfd = -1;
  449. }
  450. else
  451. {
  452. if (driver->capture_channels != 0 &&
  453. driver->playback_channels == 0)
  454. {
  455. infd = open(indev, O_RDWR|O_EXCL);
  456. outfd = -1;
  457. if (infd < 0)
  458. {
  459. jack_error(
  460. "OSS: failed to open device %s: %s@%i, errno=%d",
  461. indev, __FILE__, __LINE__, errno);
  462. return -1;
  463. }
  464. #ifndef OSS_NO_COOKED_MODE
  465. ioctl(infd, SNDCTL_DSP_COOKEDMODE, &flags);
  466. #endif
  467. }
  468. else if (driver->capture_channels == 0 &&
  469. driver->playback_channels != 0)
  470. {
  471. infd = -1;
  472. outfd = open(outdev, O_RDWR|O_EXCL);
  473. if (outfd < 0)
  474. {
  475. jack_error(
  476. "OSS: failed to open device %s: %s@%i, errno=%d",
  477. outdev, __FILE__, __LINE__, errno);
  478. return -1;
  479. }
  480. #ifndef OSS_NO_COOKED_MODE
  481. ioctl(outfd, SNDCTL_DSP_COOKEDMODE, &flags);
  482. #endif
  483. }
  484. else
  485. {
  486. infd = outfd = open(indev, O_RDWR|O_EXCL);
  487. if (infd < 0)
  488. {
  489. jack_error(
  490. "OSS: failed to open device %s: %s@%i, errno=%d",
  491. indev, __FILE__, __LINE__, errno);
  492. return -1;
  493. }
  494. #ifndef OSS_NO_COOKED_MODE
  495. ioctl(infd, SNDCTL_DSP_COOKEDMODE, &flags);
  496. #endif
  497. }
  498. if (infd >= 0 && outfd >= 0)
  499. {
  500. ioctl(outfd, SNDCTL_DSP_SETTRIGGER, &driver->trigger);
  501. driver->trigger = (PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT);
  502. if (ioctl(infd, SNDCTL_DSP_SETDUPLEX, 0) < 0)
  503. {
  504. if (errno != EINVAL) /* Dont care */
  505. jack_error(
  506. "OSS: failed to enable full duplex for %s: %s@%i, errno=%d",
  507. indev, __FILE__, __LINE__,
  508. errno);
  509. }
  510. }
  511. if (infd >= 0)
  512. {
  513. fragsize = driver->period_size *
  514. driver->capture_channels * samplesize;
  515. set_fragment(infd, fragsize, driver->nperiods);
  516. }
  517. if (outfd >= 0 && infd < 0)
  518. {
  519. fragsize = driver->period_size *
  520. driver->playback_channels * samplesize;
  521. set_fragment(outfd, fragsize, driver->nperiods);
  522. }
  523. }
  524. driver->infd = infd;
  525. driver->outfd = outfd;
  526. if (infd >= 0)
  527. {
  528. format = driver->format;
  529. if (ioctl(infd, SNDCTL_DSP_SETFMT, &format) < 0)
  530. jack_error(
  531. "OSS: failed to set format for %s: %s@%i, errno=%d",
  532. indev, __FILE__, __LINE__, errno);
  533. channels = driver->capture_channels;
  534. if (ioctl(infd, SNDCTL_DSP_CHANNELS, &channels) < 0)
  535. jack_error(
  536. "OSS: failed to set channels for %s: %s@%i, errno=%d",
  537. indev, __FILE__, __LINE__, errno);
  538. samplerate = driver->sample_rate;
  539. if (ioctl(infd, SNDCTL_DSP_SPEED, &samplerate) < 0)
  540. jack_error(
  541. "OSS: failed to set samplerate for %s: %s@%i, errno=%d",
  542. indev, __FILE__, __LINE__, errno);
  543. jack_info("oss_driver: %s : 0x%x/%i/%i (%i)", indev,
  544. format, channels, samplerate, get_fragment(infd));
  545. period_size = get_fragment(infd) / samplesize / channels;
  546. if (period_size != driver->period_size &&
  547. !driver->ignorehwbuf)
  548. {
  549. jack_info("oss_driver: period size update: %u",
  550. period_size);
  551. driver->period_size = period_size;
  552. driver->period_usecs =
  553. ((double) driver->period_size /
  554. (double) driver->sample_rate) * 1e6;
  555. if (driver->engine->set_buffer_size(driver->engine,
  556. driver->period_size)) {
  557. jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  558. return -1;
  559. }
  560. }
  561. }
  562. if (outfd >= 0 && infd != outfd)
  563. {
  564. format = driver->format;
  565. if (ioctl(outfd, SNDCTL_DSP_SETFMT, &format) < 0)
  566. jack_error(
  567. "OSS: failed to set format for %s: %s@%i, errno=%d",
  568. outdev, __FILE__, __LINE__, errno);
  569. channels = driver->playback_channels;
  570. if (ioctl(outfd, SNDCTL_DSP_CHANNELS, &channels) < 0)
  571. jack_error(
  572. "OSS: failed to set channels for %s: %s@%i, errno=%d",
  573. outdev, __FILE__, __LINE__, errno);
  574. samplerate = driver->sample_rate;
  575. if (ioctl(outfd, SNDCTL_DSP_SPEED, &samplerate) < 0)
  576. jack_error(
  577. "OSS: failed to set samplerate for %s: %s@%i, errno=%d",
  578. outdev, __FILE__, __LINE__, errno);
  579. jack_info("oss_driver: %s : 0x%x/%i/%i (%i)", outdev,
  580. format, channels, samplerate,
  581. get_fragment(outfd));
  582. period_size = get_fragment(outfd) / samplesize / channels;
  583. if (period_size != driver->period_size &&
  584. !driver->ignorehwbuf)
  585. {
  586. jack_info("oss_driver: period size update: %u",
  587. period_size);
  588. driver->period_size = period_size;
  589. driver->period_usecs =
  590. ((double) driver->period_size /
  591. (double) driver->sample_rate) * 1e6;
  592. if (driver->engine->set_buffer_size(driver->engine,
  593. driver->period_size)) {
  594. jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  595. return -1;
  596. }
  597. }
  598. }
  599. if (driver->capture_channels > 0)
  600. {
  601. driver->indevbufsize = driver->period_size *
  602. driver->capture_channels * samplesize;
  603. driver->indevbuf = malloc(driver->indevbufsize);
  604. if (driver->indevbuf == NULL)
  605. {
  606. jack_error( "OSS: malloc() failed: %s@%i",
  607. __FILE__, __LINE__);
  608. return -1;
  609. }
  610. memset(driver->indevbuf, 0x00, driver->indevbufsize);
  611. }
  612. else
  613. {
  614. driver->indevbufsize = 0;
  615. driver->indevbuf = NULL;
  616. }
  617. if (driver->playback_channels > 0)
  618. {
  619. driver->outdevbufsize = driver->period_size *
  620. driver->playback_channels * samplesize;
  621. driver->outdevbuf = malloc(driver->outdevbufsize);
  622. if (driver->outdevbuf == NULL)
  623. {
  624. jack_error("OSS: malloc() failed: %s@%i",
  625. __FILE__, __LINE__);
  626. return -1;
  627. }
  628. memset(driver->outdevbuf, 0x00, driver->outdevbufsize);
  629. }
  630. else
  631. {
  632. driver->outdevbufsize = 0;
  633. driver->outdevbuf = NULL;
  634. }
  635. jack_info("oss_driver: indevbuf %zd B, outdevbuf %zd B",
  636. driver->indevbufsize, driver->outdevbufsize);
  637. pthread_mutex_init(&driver->mutex_in, NULL);
  638. pthread_mutex_init(&driver->mutex_out, NULL);
  639. # ifdef USE_BARRIER
  640. puts("oss_driver: using barrier mode, (dual thread)");
  641. pthread_barrier_init(&driver->barrier, NULL, 2);
  642. # else
  643. puts("oss_driver: not using barrier mode, (single thread)");
  644. # endif
  645. sem_init(&driver->sem_start, 0, 0);
  646. driver->run = 1;
  647. driver->threads = 0;
  648. if (infd >= 0)
  649. {
  650. if (jack_client_create_thread(NULL, &driver->thread_in,
  651. driver->engine->rtpriority,
  652. driver->engine->control->real_time,
  653. io_thread, driver) < 0)
  654. {
  655. jack_error("OSS: jack_client_create_thread() failed: %s@%i",
  656. __FILE__, __LINE__);
  657. return -1;
  658. }
  659. driver->threads |= 1;
  660. }
  661. # ifdef USE_BARRIER
  662. if (outfd >= 0)
  663. {
  664. if (jack_client_create_thread(NULL, &driver->thread_out,
  665. driver->engine->rtpriority,
  666. driver->engine->control->real_time,
  667. io_thread, driver) < 0)
  668. {
  669. jack_error("OSS: jack_client_create_thread() failed: %s@%i",
  670. __FILE__, __LINE__);
  671. return -1;
  672. }
  673. driver->threads |= 2;
  674. }
  675. # endif
  676. if (driver->threads & 1) sem_post(&driver->sem_start);
  677. if (driver->threads & 2) sem_post(&driver->sem_start);
  678. driver->last_periodtime = jack_get_microseconds();
  679. driver->next_periodtime = 0;
  680. driver->iodelay = 0.0F;
  681. return 0;
  682. }
  683. static int oss_driver_stop (oss_driver_t *driver)
  684. {
  685. void *retval;
  686. driver->run = 0;
  687. if (driver->threads & 1)
  688. {
  689. if (pthread_join(driver->thread_in, &retval) < 0)
  690. {
  691. jack_error("OSS: pthread_join() failed: %s@%i",
  692. __FILE__, __LINE__);
  693. return -1;
  694. }
  695. }
  696. if (driver->threads & 2)
  697. {
  698. if (pthread_join(driver->thread_out, &retval) < 0)
  699. {
  700. jack_error("OSS: pthread_join() failed: %s@%i",
  701. __FILE__, __LINE__);
  702. return -1;
  703. }
  704. }
  705. sem_destroy(&driver->sem_start);
  706. # ifdef USE_BARRIER
  707. pthread_barrier_destroy(&driver->barrier);
  708. # endif
  709. pthread_mutex_destroy(&driver->mutex_in);
  710. pthread_mutex_destroy(&driver->mutex_out);
  711. if (driver->outfd >= 0 && driver->outfd != driver->infd)
  712. {
  713. close(driver->outfd);
  714. driver->outfd = -1;
  715. }
  716. if (driver->infd >= 0)
  717. {
  718. close(driver->infd);
  719. driver->infd = -1;
  720. }
  721. if (driver->indevbuf != NULL)
  722. {
  723. free(driver->indevbuf);
  724. driver->indevbuf = NULL;
  725. }
  726. if (driver->outdevbuf != NULL)
  727. {
  728. free(driver->outdevbuf);
  729. driver->outdevbuf = NULL;
  730. }
  731. return 0;
  732. }
  733. static int oss_driver_read (oss_driver_t *driver, jack_nframes_t nframes)
  734. {
  735. int channel;
  736. jack_sample_t *portbuf;
  737. JSList *node;
  738. jack_port_t *port;
  739. if (!driver->run) return 0;
  740. if (nframes != driver->period_size)
  741. {
  742. jack_error(
  743. "OSS: read failed nframes != period_size (%u/%u): %s@%i",
  744. nframes, driver->period_size, __FILE__, __LINE__);
  745. return -1;
  746. }
  747. pthread_mutex_lock(&driver->mutex_in);
  748. node = driver->capture_ports;
  749. channel = 0;
  750. while (node != NULL)
  751. {
  752. port = (jack_port_t *) node->data;
  753. if (jack_port_connected(port))
  754. {
  755. portbuf = jack_port_get_buffer(port, nframes);
  756. copy_and_convert_in(portbuf, driver->indevbuf,
  757. nframes, channel,
  758. driver->capture_channels,
  759. driver->bits);
  760. }
  761. node = jack_slist_next(node);
  762. channel++;
  763. }
  764. pthread_mutex_unlock(&driver->mutex_in);
  765. return 0;
  766. }
  767. static int oss_driver_write (oss_driver_t *driver, jack_nframes_t nframes)
  768. {
  769. int channel;
  770. jack_sample_t *portbuf;
  771. JSList *node;
  772. jack_port_t *port;
  773. if (!driver->run) return 0;
  774. if (nframes != driver->period_size)
  775. {
  776. jack_error(
  777. "OSS: write failed nframes != period_size (%u/%u): %s@%i",
  778. nframes, driver->period_size, __FILE__, __LINE__);
  779. return -1;
  780. }
  781. pthread_mutex_lock(&driver->mutex_out);
  782. node = driver->playback_ports;
  783. channel = 0;
  784. while (node != NULL)
  785. {
  786. port = (jack_port_t *) node->data;
  787. if (jack_port_connected(port))
  788. {
  789. portbuf = jack_port_get_buffer(port, nframes);
  790. copy_and_convert_out(driver->outdevbuf, portbuf,
  791. nframes, channel,
  792. driver->playback_channels,
  793. driver->bits);
  794. }
  795. node = jack_slist_next(node);
  796. channel++;
  797. }
  798. pthread_mutex_unlock(&driver->mutex_out);
  799. return 0;
  800. }
  801. static int oss_driver_null_cycle (oss_driver_t *driver, jack_nframes_t nframes)
  802. {
  803. pthread_mutex_lock(&driver->mutex_in);
  804. memset(driver->indevbuf, 0x00, driver->indevbufsize);
  805. pthread_mutex_unlock(&driver->mutex_in);
  806. pthread_mutex_lock(&driver->mutex_out);
  807. memset(driver->outdevbuf, 0x00, driver->outdevbufsize);
  808. pthread_mutex_unlock(&driver->mutex_out);
  809. return 0;
  810. }
  811. static int oss_driver_bufsize (oss_driver_t *driver, jack_nframes_t nframes)
  812. {
  813. oss_driver_stop(driver);
  814. set_period_size(driver, nframes);
  815. if (driver->engine->set_buffer_size(driver->engine, driver->period_size)) {
  816. jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  817. return -1;
  818. }
  819. jack_info("oss_driver: period size update: %u", nframes);
  820. oss_driver_start(driver);
  821. return 0;
  822. }
  823. /* internal driver thread */
  824. #ifdef USE_BARRIER
  825. static inline void synchronize (oss_driver_t *driver)
  826. {
  827. if (driver->threads == 3)
  828. {
  829. if (pthread_barrier_wait(&driver->barrier) ==
  830. PTHREAD_BARRIER_SERIAL_THREAD)
  831. {
  832. driver_cycle(driver);
  833. }
  834. }
  835. else
  836. {
  837. driver_cycle(driver);
  838. }
  839. }
  840. #endif
  841. static void *io_thread (void *param)
  842. {
  843. size_t localsize;
  844. ssize_t io_res;
  845. void *localbuf;
  846. oss_driver_t *driver = (oss_driver_t *) param;
  847. sem_wait(&driver->sem_start);
  848. # ifdef USE_BARRIER
  849. if (pthread_self() == driver->thread_in)
  850. {
  851. localsize = driver->indevbufsize;
  852. localbuf = malloc(localsize);
  853. if (localbuf == NULL)
  854. {
  855. jack_error("OSS: malloc() failed: %s@%i",
  856. __FILE__, __LINE__);
  857. return NULL;
  858. }
  859. while (driver->run)
  860. {
  861. io_res = read(driver->infd, localbuf, localsize);
  862. if (io_res < (ssize_t) localsize)
  863. {
  864. jack_error(
  865. "OSS: read() failed: %s@%i, count=%d/%d, errno=%d",
  866. __FILE__, __LINE__, io_res, localsize,
  867. errno);
  868. break;
  869. }
  870. pthread_mutex_lock(&driver->mutex_in);
  871. memcpy(driver->indevbuf, localbuf, localsize);
  872. pthread_mutex_unlock(&driver->mutex_in);
  873. synchronize(driver);
  874. }
  875. free(localbuf);
  876. }
  877. else if (pthread_self() == driver->thread_out)
  878. {
  879. localsize = driver->outdevbufsize;
  880. localbuf = malloc(localsize);
  881. if (localbuf == NULL)
  882. {
  883. jack_error("OSS: malloc() failed: %s@%i",
  884. __FILE__, __LINE__);
  885. return NULL;
  886. }
  887. if (driver->trigger)
  888. {
  889. /* don't care too much if this fails */
  890. memset(localbuf, 0x00, localsize);
  891. write(driver->outfd, localbuf, localsize);
  892. ioctl(driver->outfd, SNDCTL_DSP_SETTRIGGER, &driver->trigger);
  893. }
  894. while (driver->run)
  895. {
  896. pthread_mutex_lock(&driver->mutex_out);
  897. memcpy(localbuf, driver->outdevbuf, localsize);
  898. pthread_mutex_unlock(&driver->mutex_out);
  899. io_res = write(driver->outfd, localbuf, localsize);
  900. if (io_res < (ssize_t) localsize)
  901. {
  902. jack_error(
  903. "OSS: write() failed: %s@%i, count=%d/%d, errno=%d",
  904. __FILE__, __LINE__, io_res, localsize,
  905. errno);
  906. break;
  907. }
  908. synchronize(driver);
  909. }
  910. free(localbuf);
  911. }
  912. # else
  913. localsize = (driver->indevbufsize >= driver->outdevbufsize) ?
  914. driver->indevbufsize : driver->outdevbufsize;
  915. localbuf = malloc(localsize);
  916. if (localbuf == NULL)
  917. {
  918. jack_error("OSS: malloc() failed: %s@%i", __FILE__, __LINE__);
  919. return NULL;
  920. }
  921. if (driver->trigger)
  922. {
  923. /* don't care too much if this fails */
  924. memset(localbuf, 0x00, localsize);
  925. write(driver->outfd, localbuf, driver->outdevbufsize);
  926. ioctl(driver->outfd, SNDCTL_DSP_SETTRIGGER, &driver->trigger);
  927. }
  928. while (driver->run)
  929. {
  930. if (driver->playback_channels > 0)
  931. {
  932. pthread_mutex_lock(&driver->mutex_out);
  933. memcpy(localbuf, driver->outdevbuf,
  934. driver->outdevbufsize);
  935. pthread_mutex_unlock(&driver->mutex_out);
  936. io_res = write(driver->outfd, localbuf,
  937. driver->outdevbufsize);
  938. if (io_res < (ssize_t) driver->outdevbufsize)
  939. {
  940. jack_error(
  941. "OSS: write() failed: %s@%i, count=%d/%d, errno=%d",
  942. __FILE__, __LINE__, io_res,
  943. driver->outdevbufsize, errno);
  944. break;
  945. }
  946. }
  947. if (driver->capture_channels > 0)
  948. {
  949. io_res = read(driver->infd, localbuf,
  950. driver->indevbufsize);
  951. if (io_res < (ssize_t) driver->indevbufsize)
  952. {
  953. jack_error(
  954. "OSS: read() failed: %s@%i, count=%d/%d, errno=%d",
  955. __FILE__, __LINE__, io_res,
  956. driver->indevbufsize, errno);
  957. break;
  958. }
  959. pthread_mutex_lock(&driver->mutex_in);
  960. memcpy(driver->indevbuf, localbuf,
  961. driver->indevbufsize);
  962. pthread_mutex_unlock(&driver->mutex_in);
  963. }
  964. driver_cycle(driver);
  965. }
  966. free(localbuf);
  967. # endif
  968. return NULL;
  969. }
  970. /* jack driver published interface */
  971. const char driver_client_name[] = "oss";
  972. void driver_finish (jack_driver_t *);
  973. jack_driver_desc_t * driver_get_descriptor ()
  974. {
  975. jack_driver_desc_t *desc;
  976. jack_driver_param_desc_t *params;
  977. desc = (jack_driver_desc_t *) calloc(1, sizeof(jack_driver_desc_t));
  978. if (desc == NULL)
  979. {
  980. jack_error("oss_driver: calloc() failed: %s@%i, errno=%d",
  981. __FILE__, __LINE__, errno);
  982. return NULL;
  983. }
  984. strcpy(desc->name, driver_client_name);
  985. desc->nparams = OSS_DRIVER_N_PARAMS;
  986. params = calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
  987. if (params == NULL)
  988. {
  989. jack_error("oss_driver: calloc() failed: %s@%i, errno=%d",
  990. __FILE__, __LINE__, errno);
  991. return NULL;
  992. }
  993. memcpy(params, oss_params,
  994. desc->nparams * sizeof(jack_driver_param_desc_t));
  995. desc->params = params;
  996. return desc;
  997. }
  998. jack_driver_t * driver_initialize (jack_client_t *client,
  999. JSList * params)
  1000. {
  1001. int bits = OSS_DRIVER_DEF_BITS;
  1002. jack_nframes_t sample_rate = OSS_DRIVER_DEF_FS;
  1003. jack_nframes_t period_size = OSS_DRIVER_DEF_BLKSIZE;
  1004. jack_nframes_t in_latency = 0;
  1005. jack_nframes_t out_latency = 0;
  1006. unsigned int nperiods = OSS_DRIVER_DEF_NPERIODS;
  1007. unsigned int capture_channels = OSS_DRIVER_DEF_INS;
  1008. unsigned int playback_channels = OSS_DRIVER_DEF_OUTS;
  1009. const JSList *pnode;
  1010. const jack_driver_param_t *param;
  1011. oss_driver_t *driver;
  1012. driver = (oss_driver_t *) malloc(sizeof(oss_driver_t));
  1013. if (driver == NULL)
  1014. {
  1015. jack_error("OSS: malloc() failed: %s@%i, errno=%d",
  1016. __FILE__, __LINE__, errno);
  1017. return NULL;
  1018. }
  1019. jack_driver_init((jack_driver_t *) driver);
  1020. driver->attach = (JackDriverAttachFunction) oss_driver_attach;
  1021. driver->detach = (JackDriverDetachFunction) oss_driver_detach;
  1022. driver->start = (JackDriverStartFunction) oss_driver_start;
  1023. driver->stop = (JackDriverStopFunction) oss_driver_stop;
  1024. driver->read = (JackDriverReadFunction) oss_driver_read;
  1025. driver->write = (JackDriverWriteFunction) oss_driver_write;
  1026. driver->null_cycle = (JackDriverNullCycleFunction)
  1027. oss_driver_null_cycle;
  1028. driver->bufsize = (JackDriverBufSizeFunction) oss_driver_bufsize;
  1029. driver->indev = NULL;
  1030. driver->outdev = NULL;
  1031. driver->ignorehwbuf = 0;
  1032. driver->trigger = 0;
  1033. pnode = params;
  1034. while (pnode != NULL)
  1035. {
  1036. param = (const jack_driver_param_t *) pnode->data;
  1037. switch (param->character)
  1038. {
  1039. case 'r':
  1040. sample_rate = param->value.ui;
  1041. break;
  1042. case 'p':
  1043. period_size = param->value.ui;
  1044. break;
  1045. case 'n':
  1046. nperiods = param->value.ui;
  1047. break;
  1048. case 'w':
  1049. bits = param->value.i;
  1050. break;
  1051. case 'i':
  1052. capture_channels = param->value.ui;
  1053. break;
  1054. case 'o':
  1055. playback_channels = param->value.ui;
  1056. break;
  1057. case 'C':
  1058. driver->indev = strdup(param->value.str);
  1059. break;
  1060. case 'P':
  1061. driver->outdev = strdup(param->value.str);
  1062. break;
  1063. case 'b':
  1064. driver->ignorehwbuf = 1;
  1065. break;
  1066. case 'I':
  1067. in_latency = param->value.ui;
  1068. break;
  1069. case 'O':
  1070. out_latency = param->value.ui;
  1071. break;
  1072. }
  1073. pnode = jack_slist_next(pnode);
  1074. }
  1075. driver->sample_rate = sample_rate;
  1076. driver->period_size = period_size;
  1077. driver->nperiods = nperiods;
  1078. driver->bits = bits;
  1079. driver->capture_channels = capture_channels;
  1080. driver->playback_channels = playback_channels;
  1081. driver->sys_in_latency = in_latency;
  1082. driver->sys_out_latency = out_latency;
  1083. set_period_size(driver, period_size);
  1084. driver->finish = driver_finish;
  1085. if (driver->indev == NULL)
  1086. driver->indev = strdup(OSS_DRIVER_DEF_DEV);
  1087. if (driver->outdev == NULL)
  1088. driver->outdev = strdup(OSS_DRIVER_DEF_DEV);
  1089. driver->infd = -1;
  1090. driver->outfd = -1;
  1091. switch (driver->bits)
  1092. {
  1093. # ifndef OSS_ENDIAN
  1094. # ifdef __GNUC__
  1095. # if (defined(__i386__) || defined(__alpha__) || defined(__arm__) || defined(__x86_64__))
  1096. # define OSS_LITTLE_ENDIAN 1234
  1097. # define OSS_ENDIAN OSS_LITTLE_ENDIAN
  1098. # else
  1099. # define OSS_BIG_ENDIAN 4321
  1100. # define OSS_ENDIAN OSS_BIG_ENDIAN
  1101. # endif
  1102. # else /* __GNUC__ */
  1103. # if (defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__))
  1104. # define OSS_BIG_ENDIAN 4321
  1105. # define OSS_ENDIAN OSS_BIG_ENDIAN
  1106. # else
  1107. # define OSS_LITTLE_ENDIAN 1234
  1108. # define OSS_ENDIAN OSS_LITTLE_ENDIAN
  1109. # endif
  1110. # endif /* __GNUC__ */
  1111. # endif /* OSS_ENDIAN */
  1112. # if (OSS_ENDIAN == 1234)
  1113. /* little-endian architectures */
  1114. case 24: /* little-endian LSB aligned 24-bits in 32-bits integer */
  1115. driver->format = 0x00008000;
  1116. break;
  1117. case 32: /* little-endian 32-bit integer */
  1118. driver->format = 0x00001000;
  1119. break;
  1120. case 64: /* native-endian 64-bit float */
  1121. driver->format = 0x00004000;
  1122. break;
  1123. case 16: /* little-endian 16-bit integer */
  1124. default:
  1125. driver->format = 0x00000010;
  1126. break;
  1127. /* big-endian architectures */
  1128. # else
  1129. case 24: /* big-endian LSB aligned 24-bits in 32-bits integer */
  1130. break;
  1131. driver->format = 0x00010000;
  1132. case 32: /* big-endian 32-bit integer */
  1133. driver->format = 0x00002000;
  1134. break;
  1135. case 64: /* native-endian 64-bit float */
  1136. driver->format = 0x00004000;
  1137. break;
  1138. case 16: /* big-endian 16-bit integer */
  1139. default:
  1140. driver->format = 0x00000020;
  1141. # endif
  1142. }
  1143. driver->indevbuf = driver->outdevbuf = NULL;
  1144. driver->capture_ports = NULL;
  1145. driver->playback_ports = NULL;
  1146. driver->engine = NULL;
  1147. driver->client = client;
  1148. return ((jack_driver_t *) driver);
  1149. }
  1150. void driver_finish (jack_driver_t *driver)
  1151. {
  1152. oss_driver_t *oss_driver = (oss_driver_t *) driver;
  1153. oss_driver = (oss_driver_t *) driver;
  1154. if (oss_driver->indev != NULL)
  1155. free(oss_driver->indev);
  1156. if (oss_driver->outdev != NULL)
  1157. free(oss_driver->outdev);
  1158. free(driver);
  1159. }