18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU WAV audio driver 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2007 The Android Open Source Project 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2004-2005 Vassili Karpov (malc) 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions: 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software. 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE. 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "hw/hw.h" 267a78db75ad42aea283f5073f51891464104a9fc3David 'Digit' Turner#include "qemu/timer.h" 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "audio.h" 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define AUDIO_CAP "wav" 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "audio_int.h" 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define WAV_AUDIO_IN 1 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** VOICE OUT (Saving to a .WAV file) 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct WAVVoiceOut { 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HWVoiceOut hw; 380e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner FILE *f; 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t old_ticks; 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *pcm_buf; 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int total_samples; 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} WAVVoiceOut; 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic struct { 455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings settings; 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *wav_path; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} conf_out = { 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 44100, 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2, 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project AUD_FMT_S16, 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project }, 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "qemu.wav" 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 575d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turnerstatic int wav_out_run (HWVoiceOut *hw, int live) 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WAVVoiceOut *wav = (WAVVoiceOut *) hw; 605d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int rpos, decr, samples; 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *dst; 625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct st_sample *src; 63dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t ticks = now - wav->old_ticks; 65a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner int64_t bytes = 66a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ()); 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bytes > INT_MAX) { 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples = INT_MAX >> hw->info.shift; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples = bytes >> hw->info.shift; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->old_ticks = now; 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project decr = audio_MIN (live, samples); 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples = decr; 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rpos = hw->rpos; 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (samples) { 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int left_till_end_samples = hw->samples - rpos; 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int convert_samples = audio_MIN (samples, left_till_end_samples); 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project src = hw->mix_buf + rpos; 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst = advance (wav->pcm_buf, rpos << hw->info.shift); 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->clip (dst, src, convert_samples); 870e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner if (fwrite (dst, convert_samples << hw->info.shift, 1, wav->f) != 1) { 880e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner dolog ("wav_run_out: fwrite of %d bytes failed\nReaons: %s\n", 890e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner convert_samples << hw->info.shift, strerror (errno)); 900e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner } 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rpos = (rpos + convert_samples) % hw->samples; 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples -= convert_samples; 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->total_samples += convert_samples; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->rpos = rpos; 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return decr; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int wav_out_write (SWVoiceOut *sw, void *buf, int len) 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return audio_pcm_sw_write (sw, buf, len); 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* VICE code: Store number as little endian. */ 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void le_store (uint8_t *buf, uint32_t val, int len) 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < len; i++) { 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[i] = (uint8_t) (val & 0xff); 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val >>= 8; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int wav_out_init (HWVoiceOut *hw, struct audsettings *as) 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WAVVoiceOut *wav = (WAVVoiceOut *) hw; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int bits16 = 0, stereo = 0; 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t hdr[] = { 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project }; 1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings wav_as = conf_out.settings; 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) as; 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stereo = wav_as.nchannels == 2; 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (wav_as.fmt) { 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_S8: 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_U8: 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits16 = 0; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_S16: 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_U16: 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits16 = 1; 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_S32: 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AUD_FMT_U32: 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("WAVE files can not handle 32bit formats\n"); 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hdr[34] = bits16 ? 0x10 : 0x08; 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_as.endianness = 0; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audio_pcm_init_info (&hw->info, &wav_as); 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples = 1024; 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!wav->pcm_buf) { 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Could not allocate buffer (%d bytes)\n", 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples << hw->info.shift); 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project le_store (hdr + 22, hw->info.nchannels, 2); 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project le_store (hdr + 24, hw->info.freq, 4); 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project le_store (hdr + 28, hw->info.freq << (bits16 + stereo), 4); 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project le_store (hdr + 32, 1 << (bits16 + stereo), 2); 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1660e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner wav->f = fopen (conf_out.wav_path, "wb"); 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!wav->f) { 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Failed to open wave file `%s'\nReason: %s\n", 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project conf_out.wav_path, strerror (errno)); 170aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free (wav->pcm_buf); 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->pcm_buf = NULL; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1750e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) { 1760e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner dolog ("wav_init_out: failed to write header\nReason: %s\n", 1770e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner strerror(errno)); 1780e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner return -1; 1790e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner } 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void wav_out_fini (HWVoiceOut *hw) 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WAVVoiceOut *wav = (WAVVoiceOut *) hw; 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t rlen[4]; 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t dlen[4]; 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t datalen = wav->total_samples << hw->info.shift; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t rifflen = datalen + 36; 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!wav->f) { 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project le_store (rlen, rifflen, 4); 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project le_store (dlen, datalen, 4); 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1980e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner fseek (wav->f, 4, SEEK_SET); 1990e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner fwrite(rlen, 4, 1, wav->f); 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2010e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner fseek (wav->f, 32, SEEK_CUR); 2020e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner fwrite(dlen, 4, 1, wav->f); 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2040e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner fclose (wav->f); 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->f = NULL; 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 207aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free (wav->pcm_buf); 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->pcm_buf = NULL; 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int wav_out_ctl (HWVoiceOut *hw, int cmd, ...) 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) hw; 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) cmd; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if WAV_AUDIO_IN 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** WAV IN (Reading from a .WAV file) 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static struct { 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *wav_path; 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} conf_in = { 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "qemu.wav" 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct WAVVoiceIn { 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HWVoiceIn hw; 2320e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner FILE* f; 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t old_ticks; 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void* pcm_buf; 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int total_samples; 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int total_size; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} WAVVoiceIn; 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectle_read( const uint8_t* p, int size ) { 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int shift = 0; 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int result = 0; 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( ; size > 0; size-- ) { 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = result | (p[0] << shift); 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p += 1; 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift += 8; 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerwav_in_init (HWVoiceIn *hw, struct audsettings *as) 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WAVVoiceIn* wav = (WAVVoiceIn *) hw; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* path = conf_in.wav_path; 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t hdr[44]; 2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings wav_as = *as; 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nchannels, freq, format, bits; 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2610e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner wav->f = fopen (path, "rb"); 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (wav->f == NULL) { 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog("Failed to open wave file '%s'\nReason: %s\n", path, 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strerror(errno)); 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2680e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner if (fread(hdr, sizeof(hdr), 1, wav->f) != 1) { 2690e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner dolog("File '%s' doesn't seem to be a .wav file\n", path); 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check that this is a wave file */ 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( hdr[0] != 'R' || hdr[1] != 'I' || hdr[2] != 'F' || hdr[3] != 'F' || 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hdr[8] != 'W' || hdr[9] != 'A' || hdr[10]!= 'V' || hdr[11]!= 'E' || 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hdr[12]!= 'f' || hdr[13]!= 'm' || hdr[14]!= 't' || hdr[15]!= ' ' || 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hdr[40]!= 'd' || hdr[41]!= 'a' || hdr[42]!= 't' || hdr[43]!= 'a') { 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog("File '%s' is not a valid .wav file\n", path); 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nchannels = le_read( hdr+22, 2 ); 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project freq = le_read( hdr+24, 4 ); 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project format = le_read( hdr+32, 2 ); 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits = le_read( hdr+34, 2 ); 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->total_size = le_read( hdr+40, 4 ); 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* perform some sainty checks */ 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (nchannels) { 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: break; 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog("unsupported number of channels (%d) in '%s'\n", 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nchannels, path); 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (format) { 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 4: break; 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog("unsupported bytes per sample (%d) in '%s'\n", 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project format, path); 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (format*8/nchannels != bits) { 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog("invalid bits per sample (%d, expected %d) in '%s'\n", 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits, format*8/nchannels, path); 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_as.nchannels = nchannels; 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_as.fmt = (bits == 8) ? AUD_FMT_U8 : AUD_FMT_S16; 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_as.freq = freq; 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_as.endianness = 0; /* always little endian */ 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audio_pcm_init_info (&hw->info, &wav_as); 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples = 1024; 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift); 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!wav->pcm_buf) { 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto Fail; 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFail: 3300e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner fclose (wav->f); 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->f = NULL; 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void wav_in_fini (HWVoiceIn *hw) 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WAVVoiceIn *wav = (WAVVoiceIn *) hw; 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!wav->f) { 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3440e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner fclose (wav->f); 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->f = NULL; 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 347aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free (wav->pcm_buf); 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->pcm_buf = NULL; 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int wav_in_run (HWVoiceIn *hw) 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WAVVoiceIn* wav = (WAVVoiceIn *) hw; 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int wpos, live, decr, samples; 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t* src; 3565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct st_sample* dst; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 358dcda949f769a11b197f4784fe299a448d87e6e14David 'Digit' Turner int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t ticks = now - wav->old_ticks; 360a7fb77d6eca56e61e94f62e7deb4120b60b1e919David 'Digit' Turner int64_t bytes = muldiv64(ticks, hw->info.bytes_per_second, get_ticks_per_sec()); 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (bytes > INT_MAX) { 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples = INT_MAX >> hw->info.shift; 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples = bytes >> hw->info.shift; 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project live = audio_pcm_hw_get_live_in (hw); 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!live) { 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav->old_ticks = now; 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project decr = audio_MIN (live, samples); 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples = decr; 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wpos = hw->wpos; 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (samples) { 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int left_till_end_samples = hw->samples - wpos; 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int convert_samples = audio_MIN (samples, left_till_end_samples); 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst = hw->conv_buf + wpos; 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project src = advance (wav->pcm_buf, wpos << hw->info.shift); 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3860e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner clearerr(wav->f); 3870e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner size_t read_bytes = fread(src, 1, convert_samples << hw->info.shift, wav->f); 3880e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner if (read_bytes == 0 && ferror(wav->f) != EINTR) 3890e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner return 0; 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3910e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner size_t read_samples = read_bytes >> hw->info.shift; 3920e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner memcpy (dst, src, read_bytes); 3930e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner 3940e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner wpos = (wpos + read_samples) % hw->samples; 3950e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner samples -= read_samples; 3960e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner wav->total_samples += read_samples; 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->wpos = wpos; 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return decr; 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int wav_in_read (SWVoiceIn *sw, void *buf, int len) 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return audio_pcm_sw_read (sw, buf, len); 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int wav_in_ctl (HWVoiceIn *hw, int cmd, ...) 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) hw; 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) cmd; 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* WAV_AUDIO_IN */ 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/** COMMON CODE 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project **/ 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void *wav_audio_init (void) 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return &conf_out; 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void wav_audio_fini (void *opaque) 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (void) opaque; 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ldebug ("wav_fini"); 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic struct audio_option wav_options[] = { 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {"FREQUENCY", AUD_OPT_INT, &conf_out.settings.freq, 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Frequency", NULL, 0}, 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {"FORMAT", AUD_OPT_FMT, &conf_out.settings.fmt, 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Format", NULL, 0}, 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {"DAC_FIXED_CHANNELS", AUD_OPT_INT, &conf_out.settings.nchannels, 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Number of channels (1 - mono, 2 - stereo)", NULL, 0}, 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {"PATH", AUD_OPT_STR, &conf_out.wav_path, 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Path to output .wav file", NULL, 0}, 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if WAV_AUDIO_IN 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {"IN_PATH", AUD_OPT_STR, &conf_in.wav_path, 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "Path to input .wav file", NULL, 0}, 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {NULL, 0, NULL, NULL, NULL, 0} 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct audio_pcm_ops wav_pcm_ops = { 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_out_init, 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_out_fini, 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_out_run, 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_out_write, 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_out_ctl, 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if WAV_AUDIO_IN 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_in_init, 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_in_fini, 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_in_run, 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_in_read, 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wav_in_ctl 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL, 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NULL 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct audio_driver wav_audio_driver = { 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (name = ) "wav", 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (descr = ) 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "WAV file read/write (www.wikipedia.org/wiki/WAV)", 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (options = ) wav_options, 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (init = ) wav_audio_init, 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (fini = ) wav_audio_fini, 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (pcm_ops = ) &wav_pcm_ops, 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (can_be_default = ) 0, 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if WAV_AUDIO_IN 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (max_voices_in = ) 1, 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (max_voices_out = ) 1, 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (voice_size_out = ) sizeof (WAVVoiceOut), 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (voice_size_in = ) sizeof (WAVVoiceIn) 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (max_voices_out = ) 1, 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (max_voices_in = ) 0, 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (voice_size_out = ) sizeof (WAVVoiceOut), 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INIT_FIELD (voice_size_in = ) 0 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 493