/media/libsydneyaudio/src/sydney_audio_sunaudio.c

http://github.com/zpao/v8monkey · C · 756 lines · 503 code · 94 blank · 159 comment · 118 complexity · 9b7ddb4e5748599672a7a523832b951d MD5 · raw file

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Initial Developer of the Original Code is
  15. * Copyright (C) 2008 Sun Microsystems, Inc.,
  16. * Brian Lu <brian.lu@sun.com>
  17. *
  18. * Contributor(s):
  19. * Ginn Chen <ginn.chen@sun.com>
  20. *
  21. * Alternatively, the contents of this file may be used under the terms of
  22. * either the GNU General Public License Version 2 or later (the "GPL"), or
  23. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  24. * in which case the provisions of the GPL or the LGPL are applicable instead
  25. * of those above. If you wish to allow use of your version of this file only
  26. * under the terms of either the GPL or the LGPL, and not to allow others to
  27. * use your version of this file under the terms of the MPL, indicate your
  28. * decision by deleting the provisions above and replace them with the notice
  29. * and other provisions required by the GPL or the LGPL. If you do not delete
  30. * the provisions above, a recipient may use your version of this file under
  31. * the terms of any one of the MPL, the GPL or the LGPL.
  32. *
  33. * ***** END LICENSE BLOCK ***** *
  34. */
  35. #include <errno.h>
  36. #include <fcntl.h>
  37. #include <pthread.h>
  38. #include <stdbool.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <stropts.h>
  43. #include <unistd.h>
  44. #include <sys/audio.h>
  45. #include <sys/stat.h>
  46. #include <sys/mixer.h>
  47. #include "sydney_audio.h"
  48. /* Sun Audio implementation based heavily on sydney_audio_mac.c */
  49. #define DEFAULT_AUDIO_DEVICE "/dev/audio"
  50. #define DEFAULT_DSP_DEVICE "/dev/dsp"
  51. /* Macros copied from audio_oss.h */
  52. /*
  53. * CDDL HEADER START
  54. *
  55. * The contents of this file are subject to the terms of the
  56. * Common Development and Distribution License (the "License").
  57. * You may not use this file except in compliance with the License.
  58. *
  59. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  60. * or http://www.opensolaris.org/os/licensing.
  61. * See the License for the specific language governing permissions
  62. * and limitations under the License.
  63. *
  64. * When distributing Covered Code, include this CDDL HEADER in each
  65. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  66. * If applicable, add the following below this CDDL HEADER, with the
  67. * fields enclosed by brackets "[]" replaced with your own identifying
  68. * information: Portions Copyright [yyyy] [name of copyright owner]
  69. *
  70. * CDDL HEADER END
  71. */
  72. /*
  73. * Copyright (C) 4Front Technologies 1996-2008.
  74. *
  75. * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
  76. * Use is subject to license terms.
  77. */
  78. #define OSSIOCPARM_MASK 0x1fff /* parameters must be < 8192 bytes */
  79. #define OSSIOC_VOID 0x00000000 /* no parameters */
  80. #define OSSIOC_OUT 0x20000000 /* copy out parameters */
  81. #define OSSIOC_IN 0x40000000 /* copy in parameters */
  82. #define OSSIOC_INOUT (OSSIOC_IN|OSSIOC_OUT)
  83. #define OSSIOC_SZ(t) ((sizeof (t) & OSSIOCPARM_MASK) << 16)
  84. #define __OSSIO(x, y) ((int)(OSSIOC_VOID|(x<<8)|y))
  85. #define __OSSIOR(x, y, t) ((int)(OSSIOC_OUT|OSSIOC_SZ(t)|(x<<8)|y))
  86. #define __OSSIOWR(x, y, t) ((int)(OSSIOC_INOUT|OSSIOC_SZ(t)|(x<<8)|y))
  87. #define SNDCTL_DSP_SPEED __OSSIOWR('P', 2, int)
  88. #define SNDCTL_DSP_CHANNELS __OSSIOWR('P', 6, int)
  89. #define SNDCTL_DSP_SETFMT __OSSIOWR('P', 5, int) /* Selects ONE fmt */
  90. #define SNDCTL_DSP_GETPLAYVOL __OSSIOR('P', 24, int)
  91. #define SNDCTL_DSP_SETPLAYVOL __OSSIOWR('P', 24, int)
  92. #define SNDCTL_DSP_HALT_OUTPUT __OSSIO('P', 34)
  93. #define AFMT_S16_LE 0x00000010
  94. #define AFMT_S16_BE 0x00000020
  95. #ifdef SA_LITTLE_ENDIAN
  96. #define AFMT_S16_NE AFMT_S16_LE
  97. #else
  98. #define AFMT_S16_NE AFMT_S16_BE
  99. #endif
  100. typedef struct sa_buf sa_buf;
  101. struct sa_buf {
  102. unsigned int size;
  103. unsigned int start;
  104. unsigned int end;
  105. sa_buf * next;
  106. unsigned char data[];
  107. };
  108. struct sa_stream {
  109. bool using_oss;
  110. int output_fd;
  111. pthread_t thread_id;
  112. pthread_mutex_t mutex;
  113. bool playing;
  114. int64_t bytes_played;
  115. /* audio format info */
  116. unsigned int rate;
  117. unsigned int n_channels;
  118. unsigned int bytes_per_ch;
  119. /* buffer list */
  120. sa_buf * bl_head;
  121. sa_buf * bl_tail;
  122. int n_bufs;
  123. };
  124. /* Use a default buffer size with enough room for one second of audio,
  125. * assuming stereo data at 44.1kHz with 32 bits per channel, and impose
  126. * a generous limit on the number of buffers.
  127. */
  128. #define BUF_SIZE (2 * 44100 * 4)
  129. #define BUF_LIMIT 5
  130. #if BUF_LIMIT < 2
  131. #error BUF_LIMIT must be at least 2!
  132. #endif
  133. static void *audio_callback(void *s);
  134. static sa_buf *new_buffer(void);
  135. static int shutdown_device(sa_stream_t *s);
  136. /*
  137. * -----------------------------------------------------------------------------
  138. * Startup and shutdown functions
  139. * -----------------------------------------------------------------------------
  140. */
  141. int
  142. sa_stream_create_pcm(
  143. sa_stream_t ** _s,
  144. const char * client_name,
  145. sa_mode_t mode,
  146. sa_pcm_format_t format,
  147. unsigned int rate,
  148. unsigned int n_channels
  149. ) {
  150. /*
  151. * Make sure we return a NULL stream pointer on failure.
  152. */
  153. if (_s == NULL) {
  154. return SA_ERROR_INVALID;
  155. }
  156. *_s = NULL;
  157. if (mode != SA_MODE_WRONLY) {
  158. return SA_ERROR_NOT_SUPPORTED;
  159. }
  160. if (format != SA_PCM_FORMAT_S16_NE) {
  161. return SA_ERROR_NOT_SUPPORTED;
  162. }
  163. /*
  164. * Allocate the instance and required resources.
  165. */
  166. sa_stream_t *s;
  167. if ((s = malloc(sizeof(sa_stream_t))) == NULL) {
  168. return SA_ERROR_OOM;
  169. }
  170. if ((s->bl_head = new_buffer()) == NULL) {
  171. free(s);
  172. return SA_ERROR_SYSTEM;
  173. }
  174. if (pthread_mutex_init(&s->mutex, NULL) != 0) {
  175. free(s->bl_head);
  176. free(s);
  177. return SA_ERROR_SYSTEM;
  178. }
  179. s->output_fd = -1;
  180. s->playing = false;
  181. s->bytes_played = 0;
  182. s->rate = rate;
  183. s->n_channels = n_channels;
  184. s->bytes_per_ch = 2;
  185. s->bl_tail = s->bl_head;
  186. s->n_bufs = 1;
  187. *_s = s;
  188. return SA_SUCCESS;
  189. }
  190. int
  191. sa_stream_open(sa_stream_t *s) {
  192. if (s == NULL) {
  193. return SA_ERROR_NO_INIT;
  194. }
  195. if (s->output_fd != -1) {
  196. return SA_ERROR_INVALID;
  197. }
  198. /*
  199. * Open the default audio output unit.
  200. */
  201. /* If UTAUDIODEV is set, use it with Sun Audio interface */
  202. char * sa_device_name = getenv("UTAUDIODEV");
  203. char * dsp_device_name = NULL;
  204. if (!sa_device_name) {
  205. dsp_device_name = getenv("AUDIODSP");
  206. if (!dsp_device_name) {
  207. dsp_device_name = DEFAULT_DSP_DEVICE;
  208. }
  209. sa_device_name = getenv("AUDIODEV");
  210. if (!sa_device_name) {
  211. sa_device_name = DEFAULT_AUDIO_DEVICE;
  212. }
  213. }
  214. int fd = -1;
  215. s->using_oss = false;
  216. /* Try to use OSS if available */
  217. if (dsp_device_name) {
  218. fd = open(dsp_device_name, O_WRONLY | O_NONBLOCK);
  219. if (fd >= 0) {
  220. s->using_oss = true;
  221. }
  222. }
  223. /* Try Sun Audio */
  224. if (!s->using_oss) {
  225. fd = open(sa_device_name, O_WRONLY | O_NONBLOCK);
  226. }
  227. if (fd < 0)
  228. {
  229. printf("Open %s failed:%s.\n", sa_device_name, strerror(errno));
  230. return SA_ERROR_NO_DEVICE;
  231. }
  232. if (s->using_oss) {
  233. /* set the playback rate */
  234. if (ioctl(fd, SNDCTL_DSP_SPEED, &(s->rate)) < 0) {
  235. close(fd);
  236. return SA_ERROR_NOT_SUPPORTED;
  237. }
  238. /* set the channel numbers */
  239. if (ioctl(fd, SNDCTL_DSP_CHANNELS, &(s->n_channels)) < 0) {
  240. close(fd);
  241. return SA_ERROR_NOT_SUPPORTED;
  242. }
  243. int format = AFMT_S16_NE;
  244. if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) < 0) {
  245. close(fd);
  246. return SA_ERROR_NOT_SUPPORTED;
  247. }
  248. s->output_fd = fd;
  249. return SA_SUCCESS;
  250. }
  251. audio_info_t audio_info;
  252. AUDIO_INITINFO(&audio_info)
  253. audio_info.play.sample_rate = s->rate;
  254. audio_info.play.channels = s->n_channels;
  255. audio_info.play.precision = s->bytes_per_ch * 8;
  256. /* Signed Linear PCM encoding */
  257. audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
  258. if (ioctl(fd, AUDIO_SETINFO, &audio_info) == -1) {
  259. printf("ioctl AUDIO_SETINFO failed.\n");
  260. close(fd);
  261. return SA_ERROR_NOT_SUPPORTED;
  262. }
  263. s->output_fd = fd;
  264. return SA_SUCCESS;
  265. }
  266. int
  267. sa_stream_destroy(sa_stream_t *s) {
  268. if (s == NULL) {
  269. return SA_SUCCESS;
  270. }
  271. /*
  272. * Join the thread.
  273. */
  274. bool thread_created = false;
  275. pthread_mutex_lock(&s->mutex);
  276. if (s->playing) {
  277. thread_created = true;
  278. s->playing = false;
  279. }
  280. pthread_mutex_unlock(&s->mutex);
  281. if (thread_created) {
  282. pthread_join(s->thread_id, NULL);
  283. }
  284. int result = SA_SUCCESS;
  285. /*
  286. * Shutdown the audio output device.
  287. */
  288. result = shutdown_device(s);
  289. /*
  290. * Release resouces.
  291. */
  292. if (pthread_mutex_destroy(&s->mutex) != 0) {
  293. result = SA_ERROR_SYSTEM;
  294. }
  295. while (s->bl_head != NULL) {
  296. sa_buf * next = s->bl_head->next;
  297. free(s->bl_head);
  298. s->bl_head = next;
  299. }
  300. free(s);
  301. return result;
  302. }
  303. /*
  304. * -----------------------------------------------------------------------------
  305. * Data read and write functions
  306. * -----------------------------------------------------------------------------
  307. */
  308. int
  309. sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
  310. if (s == NULL || s->output_fd == -1) {
  311. return SA_ERROR_NO_INIT;
  312. }
  313. if (nbytes == 0) {
  314. return SA_SUCCESS;
  315. }
  316. pthread_mutex_lock(&s->mutex);
  317. /*
  318. * Append the new data to the end of our buffer list.
  319. */
  320. int result = SA_SUCCESS;
  321. while (1) {
  322. unsigned int avail = s->bl_tail->size - s->bl_tail->end;
  323. if (nbytes <= avail) {
  324. /*
  325. * The new data will fit into the current tail buffer, so
  326. * just copy it in and we're done.
  327. */
  328. memcpy(s->bl_tail->data + s->bl_tail->end, data, nbytes);
  329. s->bl_tail->end += nbytes;
  330. break;
  331. } else {
  332. /*
  333. * Copy what we can into the tail and allocate a new buffer
  334. * for the rest.
  335. */
  336. memcpy(s->bl_tail->data + s->bl_tail->end, data, avail);
  337. s->bl_tail->end += avail;
  338. data = ((unsigned char *)data) + avail;
  339. nbytes -= avail;
  340. /*
  341. * If we still have data left to copy but we've hit the limit of
  342. * allowable buffer allocations, we need to spin for a bit to allow
  343. * the audio callback function to slurp some more data up.
  344. */
  345. if (nbytes > 0 && s->n_bufs == BUF_LIMIT) {
  346. #ifdef TIMING_TRACE
  347. printf("#"); /* too much audio data */
  348. #endif
  349. if (!s->playing) {
  350. /*
  351. * We haven't even started playing yet! That means the
  352. * BUF_SIZE/BUF_LIMIT values are too low... Not much we can
  353. * do here; spinning won't help because the audio callback
  354. * hasn't been enabled yet. Oh well, error time.
  355. */
  356. printf("Too much audio data received before audio device enabled!\n");
  357. result = SA_ERROR_SYSTEM;
  358. break;
  359. }
  360. while (s->n_bufs == BUF_LIMIT) {
  361. pthread_mutex_unlock(&s->mutex);
  362. struct timespec ts = {0, 1000000};
  363. nanosleep(&ts, NULL);
  364. pthread_mutex_lock(&s->mutex);
  365. }
  366. }
  367. /*
  368. * Allocate a new tail buffer, and go 'round again to fill it up.
  369. */
  370. if ((s->bl_tail->next = new_buffer()) == NULL) {
  371. result = SA_ERROR_OOM;
  372. break;
  373. }
  374. s->n_bufs++;
  375. s->bl_tail = s->bl_tail->next;
  376. } /* if (nbytes <= avail), else */
  377. } /* while (1) */
  378. /*
  379. * Once we have our first block of audio data, enable the audio callback
  380. * function.
  381. */
  382. if (!s->playing) {
  383. s->playing = true;
  384. if (pthread_create(&s->thread_id, NULL, audio_callback, s) != 0) {
  385. result = SA_ERROR_SYSTEM;
  386. }
  387. }
  388. pthread_mutex_unlock(&s->mutex);
  389. return result;
  390. }
  391. static void *
  392. audio_callback(void *data) {
  393. sa_stream_t *s = data;
  394. pthread_mutex_lock(&s->mutex);
  395. while (s->playing) {
  396. /*
  397. * Consume data from the start of the buffer list.
  398. */
  399. while (s->output_fd != -1) {
  400. unsigned int avail = s->bl_head->end - s->bl_head->start;
  401. if (avail > 0) {
  402. int written = write(s->output_fd, s->bl_head->data + s->bl_head->start, avail);
  403. if (written == -1) {
  404. break; /* Try again later. */
  405. }
  406. s->bl_head->start += written;
  407. s->bytes_played += written;
  408. if (written < avail) {
  409. break;
  410. }
  411. }
  412. sa_buf * next = s->bl_head->next;
  413. if (next == NULL) {
  414. #ifdef TIMING_TRACE
  415. printf("!"); /* not enough audio data */
  416. #endif
  417. break;
  418. }
  419. free(s->bl_head);
  420. s->bl_head = next;
  421. s->n_bufs--;
  422. } /* while (s->output_fd != -1) */
  423. pthread_mutex_unlock(&s->mutex);
  424. struct timespec ts = {0, 1000000};
  425. nanosleep(&ts, NULL);
  426. pthread_mutex_lock(&s->mutex);
  427. } /* s->playing */
  428. pthread_mutex_unlock(&s->mutex);
  429. return NULL;
  430. }
  431. /*
  432. * -----------------------------------------------------------------------------
  433. * General query and support functions
  434. * -----------------------------------------------------------------------------
  435. */
  436. int
  437. sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
  438. if (s == NULL || s->output_fd == -1) {
  439. return SA_ERROR_NO_INIT;
  440. }
  441. pthread_mutex_lock(&s->mutex);
  442. /*
  443. * The sum of the free space in the tail buffer plus the size of any new
  444. * buffers represents the write space available before blocking.
  445. */
  446. unsigned int avail = s->bl_tail->size - s->bl_tail->end;
  447. avail += (BUF_LIMIT - s->n_bufs) * BUF_SIZE;
  448. *size = avail;
  449. pthread_mutex_unlock(&s->mutex);
  450. return SA_SUCCESS;
  451. }
  452. /* ---------------------------------------------------------------------------
  453. * General query and support functions
  454. * -----------------------------------------------------------------------------
  455. */
  456. int
  457. sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) {
  458. if (s == NULL || s->output_fd == -1) {
  459. return SA_ERROR_NO_INIT;
  460. }
  461. if (position != SA_POSITION_WRITE_SOFTWARE) {
  462. return SA_ERROR_NOT_SUPPORTED;
  463. }
  464. pthread_mutex_lock(&s->mutex);
  465. *pos = s->bytes_played;
  466. pthread_mutex_unlock(&s->mutex);
  467. return SA_SUCCESS;
  468. }
  469. int
  470. sa_stream_drain(sa_stream_t *s) {
  471. if (s == NULL || s->output_fd == -1) {
  472. return SA_ERROR_NO_INIT;
  473. }
  474. while (1) {
  475. pthread_mutex_lock(&s->mutex);
  476. sa_buf * b;
  477. size_t used = 0;
  478. for (b = s->bl_head; b != NULL; b = b->next) {
  479. used += b->end - b->start;
  480. }
  481. pthread_mutex_unlock(&s->mutex);
  482. if (used == 0) {
  483. break;
  484. }
  485. struct timespec ts = {0, 1000000};
  486. nanosleep(&ts, NULL);
  487. }
  488. return SA_SUCCESS;
  489. }
  490. int
  491. sa_stream_pause(sa_stream_t *s) {
  492. if (s == NULL || s->output_fd == -1) {
  493. return SA_ERROR_NO_INIT;
  494. }
  495. pthread_mutex_lock(&s->mutex);
  496. int result = shutdown_device(s);
  497. if (result == SA_SUCCESS) {
  498. s->output_fd = -1;
  499. }
  500. pthread_mutex_unlock(&s->mutex);
  501. return result;
  502. }
  503. int
  504. sa_stream_resume(sa_stream_t *s) {
  505. if (s == NULL) {
  506. return SA_ERROR_NO_INIT;
  507. }
  508. pthread_mutex_lock(&s->mutex);
  509. int result = sa_stream_open(s);
  510. pthread_mutex_unlock(&s->mutex);
  511. return result;
  512. }
  513. static sa_buf *
  514. new_buffer(void) {
  515. sa_buf * b = malloc(sizeof(sa_buf) + BUF_SIZE);
  516. if (b != NULL) {
  517. b->size = BUF_SIZE;
  518. b->start = 0;
  519. b->end = 0;
  520. b->next = NULL;
  521. }
  522. return b;
  523. }
  524. static int
  525. shutdown_device(sa_stream_t *s) {
  526. if (s->output_fd != -1)
  527. {
  528. /* Flush buffer. */
  529. if (s->using_oss) {
  530. ioctl(s->output_fd, SNDCTL_DSP_HALT_OUTPUT);
  531. } else {
  532. ioctl(s->output_fd, I_FLUSH);
  533. }
  534. if (close(s->output_fd) < 0)
  535. {
  536. return SA_ERROR_SYSTEM;
  537. }
  538. }
  539. return SA_SUCCESS;
  540. }
  541. /*
  542. * -----------------------------------------------------------------------------
  543. * Extension functions
  544. * -----------------------------------------------------------------------------
  545. */
  546. int
  547. sa_stream_set_volume_abs(sa_stream_t *s, float vol) {
  548. if (s == NULL || s->output_fd == -1) {
  549. return SA_ERROR_NO_INIT;
  550. }
  551. if (s->using_oss) {
  552. int mvol = ((int)(100 * vol)) | ((int)(100 * vol) << 8);
  553. if (ioctl(s->output_fd, SNDCTL_DSP_SETPLAYVOL, &mvol) < 0) {
  554. return SA_ERROR_SYSTEM;
  555. }
  556. return SA_SUCCESS;
  557. }
  558. unsigned int newVolume = (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN) * vol + AUDIO_MIN_GAIN;
  559. /* Check if the new volume is valid or not */
  560. if ( newVolume < AUDIO_MIN_GAIN || newVolume > AUDIO_MAX_GAIN )
  561. return SA_ERROR_INVALID;
  562. pthread_mutex_lock(&s->mutex);
  563. audio_info_t audio_info;
  564. AUDIO_INITINFO(&audio_info);
  565. audio_info.play.gain = newVolume;
  566. int err = ioctl(s->output_fd, AUDIO_SETINFO, &audio_info);
  567. pthread_mutex_unlock(&s->mutex);
  568. if (err == -1)
  569. {
  570. perror("sa_stream_set_volume_abs failed\n");
  571. return SA_ERROR_SYSTEM;
  572. }
  573. return SA_SUCCESS;
  574. }
  575. int
  576. sa_stream_get_volume_abs(sa_stream_t *s, float *vol) {
  577. if (s == NULL || s->output_fd == -1) {
  578. return SA_ERROR_NO_INIT;
  579. }
  580. if (s->using_oss) {
  581. int mvol;
  582. if (ioctl(s->output_fd, SNDCTL_DSP_GETPLAYVOL, &mvol) < 0){
  583. return SA_ERROR_SYSTEM;
  584. }
  585. *vol = ((mvol & 0xFF) + (mvol >> 8)) / 200.0f;
  586. return SA_SUCCESS;
  587. }
  588. pthread_mutex_lock(&s->mutex);
  589. audio_info_t audio_info;
  590. AUDIO_INITINFO(&audio_info);
  591. int err = ioctl(s->output_fd, AUDIO_GETINFO, &audio_info);
  592. pthread_mutex_unlock(&s->mutex);
  593. if (err == -1)
  594. {
  595. perror("sa_stream_get_volume_abs failed\n");
  596. return SA_ERROR_SYSTEM;
  597. }
  598. *vol = (float)((audio_info.play.gain - AUDIO_MIN_GAIN))/(AUDIO_MAX_GAIN - AUDIO_MIN_GAIN);
  599. return SA_SUCCESS;
  600. }
  601. /*
  602. * -----------------------------------------------------------------------------
  603. * Unsupported functions
  604. * -----------------------------------------------------------------------------
  605. */
  606. #define UNSUPPORTED(func) func { return SA_ERROR_NOT_SUPPORTED; }
  607. UNSUPPORTED(int sa_stream_create_opaque(sa_stream_t **s, const char *client_name, sa_mode_t mode, const char *codec))
  608. UNSUPPORTED(int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size))
  609. UNSUPPORTED(int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size))
  610. UNSUPPORTED(int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size))
  611. UNSUPPORTED(int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size))
  612. UNSUPPORTED(int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t map[], unsigned int n))
  613. UNSUPPORTED(int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode))
  614. UNSUPPORTED(int sa_stream_set_non_interleaved(sa_stream_t *s, int enable))
  615. UNSUPPORTED(int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable))
  616. UNSUPPORTED(int sa_stream_set_driver(sa_stream_t *s, const char *driver))
  617. UNSUPPORTED(int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback))
  618. UNSUPPORTED(int sa_stream_stop_thread(sa_stream_t *s))
  619. UNSUPPORTED(int sa_stream_change_device(sa_stream_t *s, const char *device_name))
  620. UNSUPPORTED(int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
  621. UNSUPPORTED(int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned int n))
  622. UNSUPPORTED(int sa_stream_change_rate(sa_stream_t *s, unsigned int rate))
  623. UNSUPPORTED(int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size))
  624. UNSUPPORTED(int sa_stream_change_user_data(sa_stream_t *s, const void *value))
  625. UNSUPPORTED(int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction))
  626. UNSUPPORTED(int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction))
  627. UNSUPPORTED(int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction))
  628. UNSUPPORTED(int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction))
  629. UNSUPPORTED(int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode))
  630. UNSUPPORTED(int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size))
  631. UNSUPPORTED(int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *format))
  632. UNSUPPORTED(int sa_stream_get_rate(sa_stream_t *s, unsigned int *rate))
  633. UNSUPPORTED(int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels))
  634. UNSUPPORTED(int sa_stream_get_user_data(sa_stream_t *s, void **value))
  635. UNSUPPORTED(int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size))
  636. UNSUPPORTED(int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size))
  637. UNSUPPORTED(int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size))
  638. UNSUPPORTED(int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size))
  639. UNSUPPORTED(int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t map[], unsigned int *n))
  640. UNSUPPORTED(int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode))
  641. UNSUPPORTED(int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled))
  642. UNSUPPORTED(int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled))
  643. UNSUPPORTED(int sa_stream_get_driver(sa_stream_t *s, char *driver_name, size_t *size))
  644. UNSUPPORTED(int sa_stream_get_device(sa_stream_t *s, char *device_name, size_t *size))
  645. UNSUPPORTED(int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
  646. UNSUPPORTED(int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned int *n))
  647. UNSUPPORTED(int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void*data, size_t *size))
  648. UNSUPPORTED(int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction))
  649. UNSUPPORTED(int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction))
  650. UNSUPPORTED(int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction))
  651. UNSUPPORTED(int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction))
  652. UNSUPPORTED(int sa_stream_get_state(sa_stream_t *s, sa_state_t *state))
  653. UNSUPPORTED(int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error))
  654. UNSUPPORTED(int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify))
  655. UNSUPPORTED(int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes))
  656. UNSUPPORTED(int sa_stream_read_ni(sa_stream_t *s, unsigned int channel, void *data, size_t nbytes))
  657. UNSUPPORTED(int sa_stream_write_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes))
  658. UNSUPPORTED(int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
  659. UNSUPPORTED(int sa_stream_pwrite_ni(sa_stream_t *s, unsigned int channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence))
  660. UNSUPPORTED(int sa_stream_get_read_size(sa_stream_t *s, size_t *size))
  661. UNSUPPORTED(int sa_stream_get_min_write(sa_stream_t *s, size_t *size))
  662. const char *sa_strerror(int code) { return NULL; }