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.

1258 lines
32KB

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