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.

1281 lines
29KB

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