18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU OSS audio driver 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2003-2005 Vassili Karpov (malc) 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions: 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software. 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE. 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <stdlib.h> 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/mman.h> 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/types.h> 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/ioctl.h> 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __OpenBSD__ 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <soundcard.h> 305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/soundcard.h> 325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h" 34e90d665cd63a0bc5c3306e1ee3e98ad362546b16David 'Digit' Turner#include "qemu/host-utils.h" 35e7216d82dbaa19892ad62b07402d512234559a6eDavid 'Digit' Turner#include "sysemu/char.h" 365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "audio.h" 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define AUDIO_CAP "oss" 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "audio_int.h" 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 415d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#if defined OSS_GETVERSION && defined SNDCTL_DSP_POLICY 425d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#define USE_DSP_POLICY 435d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#endif 444e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct OSSVoiceOut { 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HWVoiceOut hw; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *pcm_buf; 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 495d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int wpos; 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nfrags; 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fragsize; 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int mmapped; 535d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int pending; 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} OSSVoiceOut; 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct OSSVoiceIn { 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HWVoiceIn hw; 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *pcm_buf; 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nfrags; 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fragsize; 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} OSSVoiceIn; 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic struct { 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int try_mmap; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nfrags; 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fragsize; 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *devpath_out; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *devpath_in; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int debug; 715d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int exclusive; 725d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int policy; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} conf = { 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project .try_mmap = 0, 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project .nfrags = 4, 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project .fragsize = 4096, 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project .devpath_out = "/dev/dsp", 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project .devpath_in = "/dev/dsp", 795d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .debug = 0, 805d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .exclusive = 0, 815d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .policy = 5 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct oss_params { 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int freq; 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audfmt_e fmt; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nchannels; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nfrags; 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fragsize; 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void GCC_FMT_ATTR (2, 3) oss_logerr (int err, const char *fmt, ...) 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_list ap; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_start (ap, fmt); 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AUD_vlog (AUDIO_CAP, fmt, ap); 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_end (ap); 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err)); 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void GCC_FMT_ATTR (3, 4) oss_logerr2 ( 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err, 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *typ, 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *fmt, 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ... 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ) 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_list ap; 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ); 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_start (ap, fmt); 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AUD_vlog (AUDIO_CAP, fmt, ap); 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project va_end (ap); 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AUD_log (AUDIO_CAP, "Reason: %s\n", strerror (err)); 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void oss_anal_close (int *fdp) 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1235d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int err; 1245d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 1255d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner qemu_set_fd_handler (*fdp, NULL, NULL, NULL); 1265d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner err = close (*fdp); 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err) { 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr (errno, "Failed to close file(fd=%d)\n", *fdp); 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fdp = -1; 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1335d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerstatic void oss_helper_poll_out (void *opaque) 1345d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner{ 1355d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner (void) opaque; 1365d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner audio_run ("oss_poll_out"); 1375d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner} 1385d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 1395d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerstatic void oss_helper_poll_in (void *opaque) 1405d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner{ 1415d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner (void) opaque; 1425d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner audio_run ("oss_poll_in"); 1435d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner} 1445d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 1455d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerstatic int oss_poll_out (HWVoiceOut *hw) 1465d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner{ 1475d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner OSSVoiceOut *oss = (OSSVoiceOut *) hw; 1485d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 1495d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL); 1505d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner} 1515d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 1525d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerstatic int oss_poll_in (HWVoiceIn *hw) 1535d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner{ 1545d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner OSSVoiceIn *oss = (OSSVoiceIn *) hw; 1555d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 1565d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL); 1575d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner} 1585d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int oss_write (SWVoiceOut *sw, void *buf, int len) 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return audio_pcm_sw_write (sw, buf, len); 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int aud_to_ossfmt (audfmt_e fmt) 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (fmt) { 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_S8: 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return AFMT_S8; 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_U8: 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return AFMT_U8; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_S16: 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return AFMT_S16_LE; 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_U16: 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return AFMT_U16_LE; 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Internal logic error: Bad audio format %d\n", fmt); 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_AUDIO 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project abort (); 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return AFMT_U8; 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int oss_to_audfmt (int ossfmt, audfmt_e *fmt, int *endianness) 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (ossfmt) { 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AFMT_S8: 1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *endianness = 0; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fmt = AUD_FMT_S8; 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AFMT_U8: 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *endianness = 0; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fmt = AUD_FMT_U8; 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AFMT_S16_LE: 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *endianness = 0; 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fmt = AUD_FMT_S16; 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AFMT_U16_LE: 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *endianness = 0; 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fmt = AUD_FMT_U16; 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AFMT_S16_BE: 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *endianness = 1; 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fmt = AUD_FMT_S16; 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AFMT_U16_BE: 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *endianness = 1; 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fmt = AUD_FMT_U16; 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Unrecognized audio format %d\n", ossfmt); 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined DEBUG_MISMATCHES || defined DEBUG 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void oss_dump_info (struct oss_params *req, struct oss_params *obt) 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("parameter | requested value | obtained value\n"); 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("format | %10d | %10d\n", req->fmt, obt->fmt); 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("channels | %10d | %10d\n", 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req->nchannels, obt->nchannels); 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("frequency | %10d | %10d\n", req->freq, obt->freq); 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("nfrags | %10d | %10d\n", req->nfrags, obt->nfrags); 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("fragsize | %10d | %10d\n", 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req->fragsize, obt->fragsize); 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2435d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#ifdef USE_DSP_POLICY 2445d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerstatic int oss_get_version (int fd, int *version, const char *typ) 2455d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner{ 2465d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (ioctl (fd, OSS_GETVERSION, &version)) { 2475d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 2485d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner /* 2495d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner * Looks like atm (20100109) FreeBSD knows OSS_GETVERSION 2505d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner * since 7.x, but currently only on the mixer device (or in 2515d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner * the Linuxolator), and in the native version that part of 2525d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner * the code is in fact never reached so the ioctl fails anyway. 2535d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner * Until this is fixed, just check the errno and if its what 2545d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner * FreeBSD's sound drivers return atm assume they are new enough. 2555d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner */ 2565d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (errno == EINVAL) { 2575d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner *version = 0x040000; 2585d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return 0; 2595d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 2605d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#endif 2615d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss_logerr2 (errno, typ, "Failed to get OSS version\n"); 2625d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return -1; 2635d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 2645d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return 0; 2655d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner} 2665d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#endif 2675d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int oss_open (int in, struct oss_params *req, 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct oss_params *obt, int *pfd) 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 2725d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int oflags = conf.exclusive ? O_EXCL : 0; 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audio_buf_info abinfo; 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fmt, freq, nchannels; 2755d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int setfragment = 1; 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *dspname = in ? conf.devpath_in : conf.devpath_out; 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *typ = in ? "ADC" : "DAC"; 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2795d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner /* Kludge needed to have working mmap on Linux */ 2805d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oflags |= conf.try_mmap ? O_RDWR : (in ? O_RDONLY : O_WRONLY); 2815d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 2825d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner fd = open (dspname, oflags | O_NONBLOCK); 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (-1 == fd) { 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr2 (errno, typ, "Failed to open `%s'\n", dspname); 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project freq = req->freq; 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nchannels = req->nchannels; 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fmt = req->fmt; 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) { 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt); 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err; 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) { 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr2 (errno, typ, "Failed to set number of channels %d\n", 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req->nchannels); 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err; 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) { 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr2 (errno, typ, "Failed to set frequency %d\n", req->freq); 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err; 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl (fd, SNDCTL_DSP_NONBLOCK, NULL)) { 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr2 (errno, typ, "Failed to set non-blocking mode\n"); 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err; 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3135d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#ifdef USE_DSP_POLICY 3145d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (conf.policy >= 0) { 3155d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int version; 3165d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 3175d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (!oss_get_version (fd, &version, typ)) { 3185d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (conf.debug) { 3195d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner dolog ("OSS version = %#x\n", version); 3205d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 3215d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 3225d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (version >= 0x040000) { 3235d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int policy = conf.policy; 3245d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (ioctl (fd, SNDCTL_DSP_POLICY, &policy)) { 3255d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss_logerr2 (errno, typ, 3265d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner "Failed to set timing policy to %d\n", 3275d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner conf.policy); 3285d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner goto err; 3295d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 3305d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner setfragment = 0; 3315d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 3325d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 3335d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 3345d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#endif 3355d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 3365d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (setfragment) { 3375d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int mmmmssss = (req->nfrags << 16) | ctz32 (req->fragsize); 3385d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) { 3395d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss_logerr2 (errno, typ, "Failed to set buffer length (%d, %d)\n", 3405d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner req->nfrags, req->fragsize); 3415d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner goto err; 3425d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl (fd, in ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo)) { 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr2 (errno, typ, "Failed to get buffer length\n"); 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err; 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!abinfo.fragstotal || !abinfo.fragsize) { 3515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AUD_log (AUDIO_CAP, "Returned bogus buffer information(%d, %d) for %s\n", 3525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner abinfo.fragstotal, abinfo.fragsize, typ); 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err; 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt->fmt = fmt; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt->nchannels = nchannels; 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt->freq = freq; 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt->nfrags = abinfo.fragstotal; 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt->fragsize = abinfo.fragsize; 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *pfd = fd; 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_MISMATCHES 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((req->fmt != obt->fmt) || 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (req->nchannels != obt->nchannels) || 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (req->freq != obt->freq) || 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (req->fragsize != obt->fragsize) || 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (req->nfrags != obt->nfrags)) { 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Audio parameters mismatch\n"); 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_dump_info (req, obt); 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_dump_info (req, obt); 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err: 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_anal_close (&fd); 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3845d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerstatic void oss_write_pending (OSSVoiceOut *oss) 3855d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner{ 3865d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner HWVoiceOut *hw = &oss->hw; 3875d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 3885d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (oss->mmapped) { 3895d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return; 3905d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 3915d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 3925d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner while (oss->pending) { 3935d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int samples_written; 3945d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner ssize_t bytes_written; 3955d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int samples_till_end = hw->samples - oss->wpos; 3965d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int samples_to_write = audio_MIN (oss->pending, samples_till_end); 3975d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int bytes_to_write = samples_to_write << hw->info.shift; 3985d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner void *pcm = advance (oss->pcm_buf, oss->wpos << hw->info.shift); 3995d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 4005d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner bytes_written = write (oss->fd, pcm, bytes_to_write); 4015d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (bytes_written < 0) { 4025d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (errno != EAGAIN) { 4035d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss_logerr (errno, "failed to write %d bytes\n", 4045d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner bytes_to_write); 4055d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 4065d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner break; 4075d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 4085d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 4095d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (bytes_written & hw->info.align) { 4105d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner dolog ("misaligned write asked for %d, but got %zd\n", 4115d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner bytes_to_write, bytes_written); 4125d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return; 4135d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 4145d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 4155d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner samples_written = bytes_written >> hw->info.shift; 4165d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss->pending -= samples_written; 4175d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss->wpos = (oss->wpos + samples_written) % hw->samples; 4185d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (bytes_written - bytes_to_write) { 4195d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner break; 4205d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 4215d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 4225d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner} 4235d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 4245d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerstatic int oss_run_out (HWVoiceOut *hw, int live) 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OSSVoiceOut *oss = (OSSVoiceOut *) hw; 4275d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int err, decr; 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct audio_buf_info abinfo; 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct count_info cntinfo; 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int bufsize; 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bufsize = hw->samples << hw->info.shift; 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (oss->mmapped) { 4355d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int bytes, pos; 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo); 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err < 0) { 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n"); 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4435d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner pos = hw->rpos << hw->info.shift; 4445d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner bytes = audio_ring_dist (cntinfo.ptr, pos, bufsize); 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project decr = audio_MIN (bytes >> hw->info.shift, live); 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo); 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err < 0) { 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr (errno, "SNDCTL_DSP_GETOPTR failed\n"); 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (abinfo.bytes > bufsize) { 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (conf.debug) { 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("warning: Invalid available size, size=%d bufsize=%d\n" 4575d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner "please report your OS/audio hw to av1474@comtv.ru\n", 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project abinfo.bytes, bufsize); 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project abinfo.bytes = bufsize; 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (abinfo.bytes < 0) { 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (conf.debug) { 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("warning: Invalid available size, size=%d bufsize=%d\n", 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project abinfo.bytes, bufsize); 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project decr = audio_MIN (abinfo.bytes >> hw->info.shift, live); 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!decr) { 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4775d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner decr = audio_pcm_hw_clip_out (hw, oss->pcm_buf, decr, oss->pending); 4785d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss->pending += decr; 4795d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss_write_pending (oss); 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return decr; 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void oss_fini_out (HWVoiceOut *hw) 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err; 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OSSVoiceOut *oss = (OSSVoiceOut *) hw; 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ldebug ("oss_fini\n"); 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_anal_close (&oss->fd); 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (oss->pcm_buf) { 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (oss->mmapped) { 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = munmap (oss->pcm_buf, hw->samples << hw->info.shift); 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err) { 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr (errno, "Failed to unmap buffer %p, size %d\n", 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->pcm_buf, hw->samples << hw->info.shift); 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 501aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free (oss->pcm_buf); 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->pcm_buf = NULL; 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int oss_init_out (HWVoiceOut *hw, struct audsettings *as) 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OSSVoiceOut *oss = (OSSVoiceOut *) hw; 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct oss_params req, obt; 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int endianness; 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err; 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audfmt_e effective_fmt; 5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings obt_as; 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->fd = -1; 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.fmt = aud_to_ossfmt (as->fmt); 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.freq = as->freq; 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.nchannels = as->nchannels; 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.fragsize = conf.fragsize; 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.nfrags = conf.nfrags; 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (oss_open (0, &req, &obt, &fd)) { 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness); 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err) { 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_anal_close (&fd); 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt_as.freq = obt.freq; 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt_as.nchannels = obt.nchannels; 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt_as.fmt = effective_fmt; 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt_as.endianness = endianness; 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audio_pcm_init_info (&hw->info, &obt_as); 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->nfrags = obt.nfrags; 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->fragsize = obt.fragsize; 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (obt.nfrags * obt.fragsize & hw->info.align) { 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n", 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt.nfrags * obt.fragsize, hw->info.align + 1); 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->mmapped = 0; 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (conf.try_mmap) { 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->pcm_buf = mmap ( 5545d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner NULL, 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples << hw->info.shift, 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PROT_READ | PROT_WRITE, 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project MAP_SHARED, 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fd, 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ); 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (oss->pcm_buf == MAP_FAILED) { 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr (errno, "Failed to map %d bytes of DAC\n", 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples << hw->info.shift); 5645d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 5655d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner else { 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err; 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int trig = 0; 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n"); 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trig = PCM_ENABLE_OUTPUT; 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr ( 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno, 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n" 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ); 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->mmapped = 1; 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!oss->mmapped) { 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = munmap (oss->pcm_buf, hw->samples << hw->info.shift); 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err) { 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr (errno, "Failed to unmap buffer %p size %d\n", 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->pcm_buf, hw->samples << hw->info.shift); 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!oss->mmapped) { 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->pcm_buf = audio_calloc ( 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AUDIO_FUNC, 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples, 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1 << hw->info.shift 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ); 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!oss->pcm_buf) { 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ( 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Could not allocate DAC buffer (%d samples, each %d bytes)\n", 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples, 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1 << hw->info.shift 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ); 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_anal_close (&fd); 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->fd = fd; 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int trig; 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OSSVoiceOut *oss = (OSSVoiceOut *) hw; 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (cmd) { 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case VOICE_ENABLE: 6225d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 6235d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner va_list ap; 6245d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int poll_mode; 6255d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 6265d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner va_start (ap, cmd); 6275d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner poll_mode = va_arg (ap, int); 6285d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner va_end (ap); 6295d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 6305d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner ldebug ("enabling voice\n"); 6315d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (poll_mode && oss_poll_out (hw)) { 6325d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner poll_mode = 0; 6335d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 6345d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner hw->poll_mode = poll_mode; 6355d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 6365d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (!oss->mmapped) { 6375d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return 0; 6385d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 6395d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 6405d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples); 6415d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner trig = PCM_ENABLE_OUTPUT; 6425d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { 6435d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner oss_logerr ( 6445d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner errno, 6455d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n" 6465d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner ); 6475d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return -1; 6485d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case VOICE_DISABLE: 6535d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (hw->poll_mode) { 6545d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner qemu_set_fd_handler (oss->fd, NULL, NULL, NULL); 6555d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner hw->poll_mode = 0; 6565d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 6575d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 6585d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (!oss->mmapped) { 6595d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner return 0; 6605d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 6615d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ldebug ("disabling voice\n"); 6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project trig = 0; 6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) { 6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n"); 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int oss_init_in (HWVoiceIn *hw, struct audsettings *as) 6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OSSVoiceIn *oss = (OSSVoiceIn *) hw; 6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct oss_params req, obt; 6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int endianness; 6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err; 6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audfmt_e effective_fmt; 6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings obt_as; 6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->fd = -1; 6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.fmt = aud_to_ossfmt (as->fmt); 6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.freq = as->freq; 6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.nchannels = as->nchannels; 6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.fragsize = conf.fragsize; 6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project req.nfrags = conf.nfrags; 6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (oss_open (1, &req, &obt, &fd)) { 6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness); 6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err) { 6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_anal_close (&fd); 6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt_as.freq = obt.freq; 7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt_as.nchannels = obt.nchannels; 7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt_as.fmt = effective_fmt; 7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt_as.endianness = endianness; 7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audio_pcm_init_info (&hw->info, &obt_as); 7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->nfrags = obt.nfrags; 7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->fragsize = obt.fragsize; 7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (obt.nfrags * obt.fragsize & hw->info.align) { 7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n", 7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obt.nfrags * obt.fragsize, hw->info.align + 1); 7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift; 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!oss->pcm_buf) { 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n", 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples, 1 << hw->info.shift); 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_anal_close (&fd); 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->fd = fd; 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void oss_fini_in (HWVoiceIn *hw) 7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OSSVoiceIn *oss = (OSSVoiceIn *) hw; 7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_anal_close (&oss->fd); 7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (oss->pcm_buf) { 734aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free (oss->pcm_buf); 7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss->pcm_buf = NULL; 7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int oss_run_in (HWVoiceIn *hw) 7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OSSVoiceIn *oss = (OSSVoiceIn *) hw; 7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int hwshift = hw->info.shift; 7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int live = audio_pcm_hw_get_live_in (hw); 7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int dead = hw->samples - live; 7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size_t read_samples = 0; 7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct { 7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int add; 7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len; 7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } bufs[2] = { 7515d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { .add = hw->wpos, .len = 0 }, 7525d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { .add = 0, .len = 0 } 7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project }; 7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!dead) { 7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hw->wpos + dead > hw->samples) { 7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bufs[0].len = (hw->samples - hw->wpos) << hwshift; 7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bufs[1].len = (dead - (hw->samples - hw->wpos)) << hwshift; 7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bufs[0].len = dead << hwshift; 7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < 2; ++i) { 7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ssize_t nread; 7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bufs[i].len) { 7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *p = advance (oss->pcm_buf, bufs[i].add << hwshift); 7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nread = read (oss->fd, p, bufs[i].len); 7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nread > 0) { 7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nread & hw->info.align) { 7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("warning: Misaligned read %zd (requested %d), " 7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "alignment %d\n", nread, bufs[i].add << hwshift, 7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->info.align + 1); 7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project read_samples += nread >> hwshift; 7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift, 7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &nominal_volume); 7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bufs[i].len - nread) { 7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nread == -1) { 7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (errno) { 7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EINTR: 7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case EAGAIN: 7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oss_logerr ( 7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno, 7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Failed to read %d bytes of audio (to %p)\n", 7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bufs[i].len, p 7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ); 7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->wpos = (hw->wpos + read_samples) % hw->samples; 8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return read_samples; 8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int oss_read (SWVoiceIn *sw, void *buf, int size) 8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return audio_pcm_sw_read (sw, buf, size); 8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int oss_ctl_in (HWVoiceIn *hw, int cmd, ...) 8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8165d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner OSSVoiceIn *oss = (OSSVoiceIn *) hw; 8175d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 8185d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner switch (cmd) { 8195d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner case VOICE_ENABLE: 8205d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 8215d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner va_list ap; 8225d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int poll_mode; 8235d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 8245d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner va_start (ap, cmd); 8255d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner poll_mode = va_arg (ap, int); 8265d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner va_end (ap); 8275d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 8285d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (poll_mode && oss_poll_in (hw)) { 8295d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner poll_mode = 0; 8305d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 8315d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner hw->poll_mode = poll_mode; 8325d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 8335d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner break; 8345d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 8355d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner case VOICE_DISABLE: 8365d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (hw->poll_mode) { 8375d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner hw->poll_mode = 0; 8385d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner qemu_set_fd_handler (oss->fd, NULL, NULL, NULL); 8395d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 8405d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner break; 8415d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner } 8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void *oss_audio_init (void) 8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &conf; 8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void oss_audio_fini (void *opaque) 8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) opaque; 8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic struct audio_option oss_options[] = { 8565d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 8575d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "FRAGSIZE", 8585d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .tag = AUD_OPT_INT, 8595d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .valp = &conf.fragsize, 8605d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "Fragment size in bytes" 8615d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner }, 8625d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 8635d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "NFRAGS", 8645d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .tag = AUD_OPT_INT, 8655d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .valp = &conf.nfrags, 8665d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "Number of fragments" 8675d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner }, 8685d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 8695d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "MMAP", 8705d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .tag = AUD_OPT_BOOL, 8715d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .valp = &conf.try_mmap, 8725d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "Try using memory mapped access" 8735d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner }, 8745d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 8755d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "DAC_DEV", 8765d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .tag = AUD_OPT_STR, 8775d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .valp = &conf.devpath_out, 8785d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "Path to DAC device" 8795d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner }, 8805d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 8815d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "ADC_DEV", 8825d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .tag = AUD_OPT_STR, 8835d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .valp = &conf.devpath_in, 8845d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "Path to ADC device" 8855d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner }, 8865d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 8875d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "EXCLUSIVE", 8885d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .tag = AUD_OPT_BOOL, 8895d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .valp = &conf.exclusive, 8905d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "Open device in exclusive mode (vmix wont work)" 8915d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner }, 8925d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#ifdef USE_DSP_POLICY 8935d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 8945d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "POLICY", 8955d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .tag = AUD_OPT_INT, 8965d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .valp = &conf.policy, 8975d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "Set the timing policy of the device, -1 to use fragment mode", 8985d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner }, 8995d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner#endif 9005d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { 9015d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "DEBUG", 9025d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .tag = AUD_OPT_BOOL, 9035d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .valp = &conf.debug, 9045d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "Turn on some debugging messages" 9055d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner }, 9065d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner { /* End of list */ } 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic struct audio_pcm_ops oss_pcm_ops = { 9105d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .init_out = oss_init_out, 9115d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .fini_out = oss_fini_out, 9125d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .run_out = oss_run_out, 9135d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .write = oss_write, 9145d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .ctl_out = oss_ctl_out, 9155d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner 9165d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .init_in = oss_init_in, 9175d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .fini_in = oss_fini_in, 9185d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .run_in = oss_run_in, 9195d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .read = oss_read, 9205d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .ctl_in = oss_ctl_in 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct audio_driver oss_audio_driver = { 9245d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .name = "oss", 9255d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .descr = "OSS http://www.opensound.com", 9265d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .options = oss_options, 9275d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .init = oss_audio_init, 9285d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .fini = oss_audio_fini, 9295d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .pcm_ops = &oss_pcm_ops, 9305d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .can_be_default = 1, 9315d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .max_voices_out = INT_MAX, 9325d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .max_voices_in = INT_MAX, 9335d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .voice_size_out = sizeof (OSSVoiceOut), 9345d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner .voice_size_in = sizeof (OSSVoiceIn) 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 936