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.

1244 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. jack_info ("oss_driver: %s : 0x%x/%i/%i (%i)", indev,
  508. format, channels, samplerate, get_fragment (infd));
  509. period_size = get_fragment (infd) / samplesize / channels;
  510. if (period_size != driver->period_size &&
  511. !driver->ignorehwbuf) {
  512. jack_info ("oss_driver: period size update: %u",
  513. period_size);
  514. driver->period_size = period_size;
  515. driver->period_usecs =
  516. ((double)driver->period_size /
  517. (double)driver->sample_rate) * 1e6;
  518. if (driver->engine->set_buffer_size (driver->engine,
  519. driver->period_size)) {
  520. jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  521. return -1;
  522. }
  523. }
  524. }
  525. if (outfd >= 0 && infd != outfd) {
  526. format = driver->format;
  527. if (ioctl (outfd, SNDCTL_DSP_SETFMT, &format) < 0) {
  528. jack_error (
  529. "OSS: failed to set format for %s: %s@%i, errno=%d",
  530. outdev, __FILE__, __LINE__, errno);
  531. }
  532. channels = driver->playback_channels;
  533. if (ioctl (outfd, SNDCTL_DSP_CHANNELS, &channels) < 0) {
  534. jack_error (
  535. "OSS: failed to set channels for %s: %s@%i, errno=%d",
  536. outdev, __FILE__, __LINE__, errno);
  537. }
  538. samplerate = driver->sample_rate;
  539. if (ioctl (outfd, SNDCTL_DSP_SPEED, &samplerate) < 0) {
  540. jack_error (
  541. "OSS: failed to set samplerate for %s: %s@%i, errno=%d",
  542. outdev, __FILE__, __LINE__, errno);
  543. }
  544. jack_info ("oss_driver: %s : 0x%x/%i/%i (%i)", outdev,
  545. format, channels, samplerate,
  546. get_fragment (outfd));
  547. period_size = get_fragment (outfd) / samplesize / channels;
  548. if (period_size != driver->period_size &&
  549. !driver->ignorehwbuf) {
  550. jack_info ("oss_driver: period size update: %u",
  551. period_size);
  552. driver->period_size = period_size;
  553. driver->period_usecs =
  554. ((double)driver->period_size /
  555. (double)driver->sample_rate) * 1e6;
  556. if (driver->engine->set_buffer_size (driver->engine,
  557. driver->period_size)) {
  558. jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  559. return -1;
  560. }
  561. }
  562. }
  563. if (driver->capture_channels > 0) {
  564. driver->indevbufsize = driver->period_size *
  565. driver->capture_channels * samplesize;
  566. driver->indevbuf = malloc (driver->indevbufsize);
  567. if (driver->indevbuf == NULL) {
  568. jack_error ( "OSS: malloc() failed: %s@%i",
  569. __FILE__, __LINE__);
  570. return -1;
  571. }
  572. memset (driver->indevbuf, 0x00, driver->indevbufsize);
  573. } else {
  574. driver->indevbufsize = 0;
  575. driver->indevbuf = NULL;
  576. }
  577. if (driver->playback_channels > 0) {
  578. driver->outdevbufsize = driver->period_size *
  579. driver->playback_channels * samplesize;
  580. driver->outdevbuf = malloc (driver->outdevbufsize);
  581. if (driver->outdevbuf == NULL) {
  582. jack_error ("OSS: malloc() failed: %s@%i",
  583. __FILE__, __LINE__);
  584. return -1;
  585. }
  586. memset (driver->outdevbuf, 0x00, driver->outdevbufsize);
  587. } else {
  588. driver->outdevbufsize = 0;
  589. driver->outdevbuf = NULL;
  590. }
  591. jack_info ("oss_driver: indevbuf %zd B, outdevbuf %zd B",
  592. driver->indevbufsize, driver->outdevbufsize);
  593. pthread_mutex_init (&driver->mutex_in, NULL);
  594. pthread_mutex_init (&driver->mutex_out, NULL);
  595. # ifdef USE_BARRIER
  596. puts ("oss_driver: using barrier mode, (dual thread)");
  597. pthread_barrier_init (&driver->barrier, NULL, 2);
  598. # else
  599. puts ("oss_driver: not using barrier mode, (single thread)");
  600. # endif
  601. sem_init (&driver->sem_start, 0, 0);
  602. driver->run = 1;
  603. driver->threads = 0;
  604. if (infd >= 0) {
  605. if (jack_client_create_thread (NULL, &driver->thread_in,
  606. driver->engine->rtpriority,
  607. driver->engine->control->real_time,
  608. io_thread, driver) < 0) {
  609. jack_error ("OSS: jack_client_create_thread() failed: %s@%i",
  610. __FILE__, __LINE__);
  611. return -1;
  612. }
  613. driver->threads |= 1;
  614. }
  615. # ifdef USE_BARRIER
  616. if (outfd >= 0) {
  617. if (jack_client_create_thread (NULL, &driver->thread_out,
  618. driver->engine->rtpriority,
  619. driver->engine->control->real_time,
  620. io_thread, driver) < 0) {
  621. jack_error ("OSS: jack_client_create_thread() failed: %s@%i",
  622. __FILE__, __LINE__);
  623. return -1;
  624. }
  625. driver->threads |= 2;
  626. }
  627. # endif
  628. if (driver->threads & 1) {
  629. sem_post (&driver->sem_start);
  630. }
  631. if (driver->threads & 2) {
  632. sem_post (&driver->sem_start);
  633. }
  634. driver->last_periodtime = driver->engine->get_microseconds ();
  635. driver->next_periodtime = 0;
  636. driver->iodelay = 0.0F;
  637. return 0;
  638. }
  639. static int oss_driver_stop (oss_driver_t *driver)
  640. {
  641. void *retval;
  642. driver->run = 0;
  643. if (driver->threads & 1) {
  644. if (pthread_join (driver->thread_in, &retval) < 0) {
  645. jack_error ("OSS: pthread_join() failed: %s@%i",
  646. __FILE__, __LINE__);
  647. return -1;
  648. }
  649. }
  650. if (driver->threads & 2) {
  651. if (pthread_join (driver->thread_out, &retval) < 0) {
  652. jack_error ("OSS: pthread_join() failed: %s@%i",
  653. __FILE__, __LINE__);
  654. return -1;
  655. }
  656. }
  657. sem_destroy (&driver->sem_start);
  658. # ifdef USE_BARRIER
  659. pthread_barrier_destroy (&driver->barrier);
  660. # endif
  661. pthread_mutex_destroy (&driver->mutex_in);
  662. pthread_mutex_destroy (&driver->mutex_out);
  663. if (driver->outfd >= 0 && driver->outfd != driver->infd) {
  664. close (driver->outfd);
  665. driver->outfd = -1;
  666. }
  667. if (driver->infd >= 0) {
  668. close (driver->infd);
  669. driver->infd = -1;
  670. }
  671. if (driver->indevbuf != NULL) {
  672. free (driver->indevbuf);
  673. driver->indevbuf = NULL;
  674. }
  675. if (driver->outdevbuf != NULL) {
  676. free (driver->outdevbuf);
  677. driver->outdevbuf = NULL;
  678. }
  679. return 0;
  680. }
  681. static int oss_driver_read (oss_driver_t *driver, jack_nframes_t nframes)
  682. {
  683. int channel;
  684. jack_sample_t *portbuf;
  685. JSList *node;
  686. jack_port_t *port;
  687. if (!driver->run) {
  688. return 0;
  689. }
  690. if (nframes != driver->period_size) {
  691. jack_error (
  692. "OSS: read failed nframes != period_size (%u/%u): %s@%i",
  693. nframes, driver->period_size, __FILE__, __LINE__);
  694. return -1;
  695. }
  696. pthread_mutex_lock (&driver->mutex_in);
  697. node = driver->capture_ports;
  698. channel = 0;
  699. while (node != NULL) {
  700. port = (jack_port_t*)node->data;
  701. if (jack_port_connected (port)) {
  702. portbuf = jack_port_get_buffer (port, nframes);
  703. copy_and_convert_in (portbuf, driver->indevbuf,
  704. nframes, channel,
  705. driver->capture_channels,
  706. driver->bits);
  707. }
  708. node = jack_slist_next (node);
  709. channel++;
  710. }
  711. pthread_mutex_unlock (&driver->mutex_in);
  712. return 0;
  713. }
  714. static int oss_driver_write (oss_driver_t *driver, jack_nframes_t nframes)
  715. {
  716. int channel;
  717. jack_sample_t *portbuf;
  718. JSList *node;
  719. jack_port_t *port;
  720. if (!driver->run) {
  721. return 0;
  722. }
  723. if (nframes != driver->period_size) {
  724. jack_error (
  725. "OSS: write failed nframes != period_size (%u/%u): %s@%i",
  726. nframes, driver->period_size, __FILE__, __LINE__);
  727. return -1;
  728. }
  729. pthread_mutex_lock (&driver->mutex_out);
  730. node = driver->playback_ports;
  731. channel = 0;
  732. while (node != NULL) {
  733. port = (jack_port_t*)node->data;
  734. if (jack_port_connected (port)) {
  735. portbuf = jack_port_get_buffer (port, nframes);
  736. copy_and_convert_out (driver->outdevbuf, portbuf,
  737. nframes, channel,
  738. driver->playback_channels,
  739. driver->bits);
  740. }
  741. node = jack_slist_next (node);
  742. channel++;
  743. }
  744. pthread_mutex_unlock (&driver->mutex_out);
  745. return 0;
  746. }
  747. static int oss_driver_null_cycle (oss_driver_t *driver, jack_nframes_t nframes)
  748. {
  749. pthread_mutex_lock (&driver->mutex_in);
  750. memset (driver->indevbuf, 0x00, driver->indevbufsize);
  751. pthread_mutex_unlock (&driver->mutex_in);
  752. pthread_mutex_lock (&driver->mutex_out);
  753. memset (driver->outdevbuf, 0x00, driver->outdevbufsize);
  754. pthread_mutex_unlock (&driver->mutex_out);
  755. return 0;
  756. }
  757. static int oss_driver_bufsize (oss_driver_t *driver, jack_nframes_t nframes)
  758. {
  759. oss_driver_stop (driver);
  760. set_period_size (driver, nframes);
  761. if (driver->engine->set_buffer_size (driver->engine, driver->period_size)) {
  762. jack_error ("OSS: cannot set engine buffer size to %d (check MIDI)", driver->period_size);
  763. return -1;
  764. }
  765. jack_info ("oss_driver: period size update: %u", nframes);
  766. oss_driver_start (driver);
  767. return 0;
  768. }
  769. /* internal driver thread */
  770. #ifdef USE_BARRIER
  771. static inline void synchronize (oss_driver_t *driver)
  772. {
  773. if (driver->threads == 3) {
  774. if (pthread_barrier_wait (&driver->barrier) ==
  775. PTHREAD_BARRIER_SERIAL_THREAD) {
  776. driver_cycle (driver);
  777. }
  778. } else {
  779. driver_cycle (driver);
  780. }
  781. }
  782. #endif
  783. static void *io_thread (void *param)
  784. {
  785. size_t localsize;
  786. ssize_t io_res;
  787. void *localbuf;
  788. oss_driver_t *driver = (oss_driver_t*)param;
  789. sem_wait (&driver->sem_start);
  790. # ifdef USE_BARRIER
  791. if (pthread_self () == driver->thread_in) {
  792. localsize = driver->indevbufsize;
  793. localbuf = malloc (localsize);
  794. if (localbuf == NULL) {
  795. jack_error ("OSS: malloc() failed: %s@%i",
  796. __FILE__, __LINE__);
  797. return NULL;
  798. }
  799. while (driver->run) {
  800. io_res = read (driver->infd, localbuf, localsize);
  801. if (io_res < (ssize_t)localsize) {
  802. jack_error (
  803. "OSS: read() failed: %s@%i, count=%d/%d, errno=%d",
  804. __FILE__, __LINE__, io_res, localsize,
  805. errno);
  806. break;
  807. }
  808. pthread_mutex_lock (&driver->mutex_in);
  809. memcpy (driver->indevbuf, localbuf, localsize);
  810. pthread_mutex_unlock (&driver->mutex_in);
  811. synchronize (driver);
  812. }
  813. free (localbuf);
  814. } else if (pthread_self () == driver->thread_out) {
  815. localsize = driver->outdevbufsize;
  816. localbuf = malloc (localsize);
  817. if (localbuf == NULL) {
  818. jack_error ("OSS: malloc() failed: %s@%i",
  819. __FILE__, __LINE__);
  820. return NULL;
  821. }
  822. if (driver->trigger) {
  823. /* don't care too much if this fails */
  824. memset (localbuf, 0x00, localsize);
  825. write (driver->outfd, localbuf, localsize);
  826. ioctl (driver->outfd, SNDCTL_DSP_SETTRIGGER, &driver->trigger);
  827. }
  828. while (driver->run) {
  829. pthread_mutex_lock (&driver->mutex_out);
  830. memcpy (localbuf, driver->outdevbuf, localsize);
  831. pthread_mutex_unlock (&driver->mutex_out);
  832. io_res = write (driver->outfd, localbuf, localsize);
  833. if (io_res < (ssize_t)localsize) {
  834. jack_error (
  835. "OSS: write() failed: %s@%i, count=%d/%d, errno=%d",
  836. __FILE__, __LINE__, io_res, localsize,
  837. errno);
  838. break;
  839. }
  840. synchronize (driver);
  841. }
  842. free (localbuf);
  843. }
  844. # else
  845. localsize = (driver->indevbufsize >= driver->outdevbufsize) ?
  846. driver->indevbufsize : driver->outdevbufsize;
  847. localbuf = malloc (localsize);
  848. if (localbuf == NULL) {
  849. jack_error ("OSS: malloc() failed: %s@%i", __FILE__, __LINE__);
  850. return NULL;
  851. }
  852. if (driver->trigger) {
  853. /* don't care too much if this fails */
  854. memset (localbuf, 0x00, localsize);
  855. write (driver->outfd, localbuf, driver->outdevbufsize);
  856. ioctl (driver->outfd, SNDCTL_DSP_SETTRIGGER, &driver->trigger);
  857. }
  858. while (driver->run) {
  859. if (driver->playback_channels > 0) {
  860. pthread_mutex_lock (&driver->mutex_out);
  861. memcpy (localbuf, driver->outdevbuf,
  862. driver->outdevbufsize);
  863. pthread_mutex_unlock (&driver->mutex_out);
  864. io_res = write (driver->outfd, localbuf,
  865. driver->outdevbufsize);
  866. if (io_res < (ssize_t)driver->outdevbufsize) {
  867. jack_error (
  868. "OSS: write() failed: %s@%i, count=%d/%d, errno=%d",
  869. __FILE__, __LINE__, io_res,
  870. driver->outdevbufsize, errno);
  871. break;
  872. }
  873. }
  874. if (driver->capture_channels > 0) {
  875. io_res = read (driver->infd, localbuf,
  876. driver->indevbufsize);
  877. if (io_res < (ssize_t)driver->indevbufsize) {
  878. jack_error (
  879. "OSS: read() failed: %s@%i, count=%d/%d, errno=%d",
  880. __FILE__, __LINE__, io_res,
  881. driver->indevbufsize, errno);
  882. break;
  883. }
  884. pthread_mutex_lock (&driver->mutex_in);
  885. memcpy (driver->indevbuf, localbuf,
  886. driver->indevbufsize);
  887. pthread_mutex_unlock (&driver->mutex_in);
  888. }
  889. driver_cycle (driver);
  890. }
  891. free (localbuf);
  892. # endif
  893. return NULL;
  894. }
  895. /* jack driver published interface */
  896. const char driver_client_name[] = "oss";
  897. void driver_finish(jack_driver_t *);
  898. jack_driver_desc_t * driver_get_descriptor ()
  899. {
  900. jack_driver_desc_t *desc;
  901. jack_driver_param_desc_t *params;
  902. desc = (jack_driver_desc_t*)calloc (1, sizeof(jack_driver_desc_t));
  903. if (desc == NULL) {
  904. jack_error ("oss_driver: calloc() failed: %s@%i, errno=%d",
  905. __FILE__, __LINE__, errno);
  906. return NULL;
  907. }
  908. strcpy (desc->name, driver_client_name);
  909. desc->nparams = OSS_DRIVER_N_PARAMS;
  910. params = calloc (desc->nparams, sizeof(jack_driver_param_desc_t));
  911. if (params == NULL) {
  912. jack_error ("oss_driver: calloc() failed: %s@%i, errno=%d",
  913. __FILE__, __LINE__, errno);
  914. return NULL;
  915. }
  916. memcpy (params, oss_params,
  917. desc->nparams * sizeof(jack_driver_param_desc_t));
  918. desc->params = params;
  919. return desc;
  920. }
  921. jack_driver_t * driver_initialize (jack_client_t *client,
  922. JSList * params)
  923. {
  924. int bits = OSS_DRIVER_DEF_BITS;
  925. jack_nframes_t sample_rate = OSS_DRIVER_DEF_FS;
  926. jack_nframes_t period_size = OSS_DRIVER_DEF_BLKSIZE;
  927. jack_nframes_t in_latency = 0;
  928. jack_nframes_t out_latency = 0;
  929. unsigned int nperiods = OSS_DRIVER_DEF_NPERIODS;
  930. unsigned int capture_channels = OSS_DRIVER_DEF_INS;
  931. unsigned int playback_channels = OSS_DRIVER_DEF_OUTS;
  932. const JSList *pnode;
  933. const jack_driver_param_t *param;
  934. oss_driver_t *driver;
  935. driver = (oss_driver_t*)malloc (sizeof(oss_driver_t));
  936. if (driver == NULL) {
  937. jack_error ("OSS: malloc() failed: %s@%i, errno=%d",
  938. __FILE__, __LINE__, errno);
  939. return NULL;
  940. }
  941. memset (driver, 0x00, sizeof(oss_driver_t));
  942. jack_driver_init ((jack_driver_t*)driver);
  943. driver->attach = (JackDriverAttachFunction)oss_driver_attach;
  944. driver->detach = (JackDriverDetachFunction)oss_driver_detach;
  945. driver->start = (JackDriverStartFunction)oss_driver_start;
  946. driver->stop = (JackDriverStopFunction)oss_driver_stop;
  947. driver->read = (JackDriverReadFunction)oss_driver_read;
  948. driver->write = (JackDriverWriteFunction)oss_driver_write;
  949. driver->null_cycle = (JackDriverNullCycleFunction)
  950. oss_driver_null_cycle;
  951. driver->bufsize = (JackDriverBufSizeFunction)oss_driver_bufsize;
  952. driver->indev = NULL;
  953. driver->outdev = NULL;
  954. driver->ignorehwbuf = 0;
  955. driver->trigger = 0;
  956. pnode = params;
  957. while (pnode != NULL) {
  958. param = (const jack_driver_param_t*)pnode->data;
  959. switch (param->character) {
  960. case 'r':
  961. sample_rate = param->value.ui;
  962. break;
  963. case 'p':
  964. period_size = param->value.ui;
  965. break;
  966. case 'n':
  967. nperiods = param->value.ui;
  968. break;
  969. case 'w':
  970. bits = param->value.i;
  971. break;
  972. case 'i':
  973. capture_channels = param->value.ui;
  974. break;
  975. case 'o':
  976. playback_channels = param->value.ui;
  977. break;
  978. case 'C':
  979. driver->indev = strdup (param->value.str);
  980. break;
  981. case 'P':
  982. driver->outdev = strdup (param->value.str);
  983. break;
  984. case 'b':
  985. driver->ignorehwbuf = 1;
  986. break;
  987. case 'I':
  988. in_latency = param->value.ui;
  989. break;
  990. case 'O':
  991. out_latency = param->value.ui;
  992. break;
  993. }
  994. pnode = jack_slist_next (pnode);
  995. }
  996. driver->sample_rate = sample_rate;
  997. driver->period_size = period_size;
  998. driver->nperiods = nperiods;
  999. driver->bits = bits;
  1000. driver->capture_channels = capture_channels;
  1001. driver->playback_channels = playback_channels;
  1002. driver->sys_in_latency = in_latency;
  1003. driver->sys_out_latency = out_latency;
  1004. /* setting driver->period_usecs & co is delayed until attach */
  1005. driver->finish = driver_finish;
  1006. if (driver->indev == NULL) {
  1007. driver->indev = strdup (OSS_DRIVER_DEF_DEV);
  1008. }
  1009. if (driver->outdev == NULL) {
  1010. driver->outdev = strdup (OSS_DRIVER_DEF_DEV);
  1011. }
  1012. driver->infd = -1;
  1013. driver->outfd = -1;
  1014. switch (driver->bits) {
  1015. # ifndef OSS_ENDIAN
  1016. # ifdef __GNUC__
  1017. # if (defined(__i386__) || defined(__alpha__) || defined(__arm__) || defined(__x86_64__) || (defined(__sh__) && !defined(__LITTLE_ENDIAN__)))
  1018. # define OSS_LITTLE_ENDIAN 1234
  1019. # define OSS_ENDIAN OSS_LITTLE_ENDIAN
  1020. # else
  1021. # define OSS_BIG_ENDIAN 4321
  1022. # define OSS_ENDIAN OSS_BIG_ENDIAN
  1023. # endif
  1024. # else /* __GNUC__ */
  1025. # if (defined(_AIX) || defined(AIX) || defined(sparc) || defined(__hppa) || defined(PPC) || defined(__powerpc__) && !defined(i386) && !defined(__i386) && !defined(__i386__))
  1026. # define OSS_BIG_ENDIAN 4321
  1027. # define OSS_ENDIAN OSS_BIG_ENDIAN
  1028. # else
  1029. # define OSS_LITTLE_ENDIAN 1234
  1030. # define OSS_ENDIAN OSS_LITTLE_ENDIAN
  1031. # endif
  1032. # endif /* __GNUC__ */
  1033. # endif /* OSS_ENDIAN */
  1034. # if (OSS_ENDIAN == 1234)
  1035. /* little-endian architectures */
  1036. case 24: /* little-endian LSB aligned 24-bits in 32-bits integer */
  1037. driver->format = 0x00008000;
  1038. break;
  1039. case 32: /* little-endian 32-bit integer */
  1040. driver->format = 0x00001000;
  1041. break;
  1042. case 64: /* native-endian 64-bit float */
  1043. driver->format = 0x00004000;
  1044. break;
  1045. case 16: /* little-endian 16-bit integer */
  1046. default:
  1047. driver->format = 0x00000010;
  1048. break;
  1049. /* big-endian architectures */
  1050. # else
  1051. case 24: /* big-endian LSB aligned 24-bits in 32-bits integer */
  1052. break;
  1053. driver->format = 0x00010000;
  1054. case 32: /* big-endian 32-bit integer */
  1055. driver->format = 0x00002000;
  1056. break;
  1057. case 64: /* native-endian 64-bit float */
  1058. driver->format = 0x00004000;
  1059. break;
  1060. case 16: /* big-endian 16-bit integer */
  1061. default:
  1062. driver->format = 0x00000020;
  1063. # endif
  1064. }
  1065. driver->indevbuf = driver->outdevbuf = NULL;
  1066. driver->capture_ports = NULL;
  1067. driver->playback_ports = NULL;
  1068. driver->engine = NULL;
  1069. driver->client = client;
  1070. return (jack_driver_t*)driver;
  1071. }
  1072. void driver_finish (jack_driver_t *driver)
  1073. {
  1074. oss_driver_t *oss_driver = (oss_driver_t*)driver;
  1075. oss_driver = (oss_driver_t*)driver;
  1076. if (oss_driver->indev != NULL) {
  1077. free (oss_driver->indev);
  1078. }
  1079. if (oss_driver->outdev != NULL) {
  1080. free (oss_driver->outdev);
  1081. }
  1082. free (driver);
  1083. }