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.

1197 lines
27KB

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