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.

1263 lines
29KB

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