audio_template.h revision 5164d3c53f57dfb468ab11136358b6e3b6cf0513
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU Audio subsystem header 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 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 */ 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NAME "playback" 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define HWBUF hw->mix_buf 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TYPE out 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define HW HWVoiceOut 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SW SWVoiceOut 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NAME "capture" 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define TYPE in 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define HW HWVoiceIn 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SW SWVoiceIn 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define HWBUF hw->conv_buf 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv) 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AudioState *s = &glob_audio_state; 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int max_voices = glue (drv->max_voices_, TYPE); 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int voice_size = glue (drv->voice_size_, TYPE); 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (glue (s->nb_hw_voices_, TYPE) > max_voices) { 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!max_voices) { 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Driver `%s' does not support " NAME "\n", drv->name); 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Driver `%s' does not support %d " NAME " voices, max %d\n", 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->name, 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (s->nb_hw_voices_, TYPE), 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project max_voices); 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (s->nb_hw_voices_, TYPE) = max_voices; 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (audio_bug (AUDIO_FUNC, !voice_size && max_voices)) { 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("drv=`%s' voice_size=0 max_voices=%d\n", 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->name, max_voices); 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (s->nb_hw_voices_, TYPE) = 0; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (audio_bug (AUDIO_FUNC, voice_size && !max_voices)) { 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("drv=`%s' voice_size=%d max_voices=0\n", 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->name, voice_size); 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw) 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (HWBUF) { 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (HWBUF); 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HWBUF = NULL; 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw) 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner HWBUF = audio_calloc (AUDIO_FUNC, hw->samples, sizeof (struct st_sample)); 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!HWBUF) { 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Could not allocate " NAME " buffer (%d samples)\n", 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->samples); 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw) 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sw->buf) { 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (sw->buf); 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sw->rate) { 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project st_rate_stop (sw->rate); 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->buf = NULL; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->rate = NULL; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int samples; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples = sw->hw->samples; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project samples = ((int64_t) sw->hw->samples << 32) / sw->ratio; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sw->buf = audio_calloc (AUDIO_FUNC, samples, sizeof (struct st_sample)); 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!sw->buf) { 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Could not allocate buffer for `%s' (%d samples)\n", 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SW_NAME (sw), samples); 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->rate = st_rate_start (sw->info.freq, sw->hw->info.freq); 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq); 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!sw->rate) { 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (sw->buf); 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->buf = NULL; 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int glue (audio_pcm_sw_init_, TYPE) ( 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SW *sw, 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HW *hw, 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *name, 1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings *as 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ) 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int err; 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audio_pcm_init_info (&sw->info, as); 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->hw = hw; 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->active = 0; 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->total_hw_samples_mixed = 0; 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->empty = 1; 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq; 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->conv = mixeng_conv 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->clip = mixeng_clip 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [sw->info.nchannels == 2] 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [sw->info.sign] 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [sw->info.swap_endianness] 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [audio_bits_to_index (sw->info.bits)]; 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->name = qemu_strdup (name); 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw); 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err) { 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (sw->name); 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->name = NULL; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return err; 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void glue (audio_pcm_sw_fini_, TYPE) (SW *sw) 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (audio_pcm_sw_free_resources_, TYPE) (sw); 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sw->name) { 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (sw->name); 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw->name = NULL; 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw) 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 187a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner QLIST_INSERT_HEAD (&hw->sw_head, sw, entries); 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void glue (audio_pcm_hw_del_sw_, TYPE) (SW *sw) 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 192a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner QLIST_REMOVE (sw, entries); 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp) 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AudioState *s = &glob_audio_state; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HW *hw = *hwp; 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!hw->sw_head.lh_first) { 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audio_detach_capture (hw); 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 204a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner QLIST_REMOVE (hw, entries); 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (s->nb_hw_voices_, TYPE) += 1; 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (audio_pcm_hw_free_resources_ ,TYPE) (hw); 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BEGIN_NOSIGALRM 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (hw->pcm_ops->fini_, TYPE) (hw); 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project END_NOSIGALRM 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (hw); 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *hwp = NULL; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic HW *glue (audio_pcm_hw_find_any_, TYPE) (HW *hw) 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AudioState *s = &glob_audio_state; 2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return hw ? hw->entries.le_next : glue (s->hw_head_, TYPE).lh_first; 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic HW *glue (audio_pcm_hw_find_any_enabled_, TYPE) (HW *hw) 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hw->enabled) { 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return hw; 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic HW *glue (audio_pcm_hw_find_specific_, TYPE) ( 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HW *hw, 2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings *as 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ) 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while ((hw = glue (audio_pcm_hw_find_any_, TYPE) (hw))) { 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (audio_pcm_info_eq (&hw->info, as)) { 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return hw; 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as) 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HW *hw; 2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AudioState *s = &glob_audio_state; 2485d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner struct audio_driver *drv = s->drv; 2495d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner int err; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!glue (s->nb_hw_voices_, TYPE)) { 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (audio_bug (AUDIO_FUNC, !drv)) { 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("No host audio driver\n"); 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (audio_bug (AUDIO_FUNC, !drv->pcm_ops)) { 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Host audio driver without pcm_ops\n"); 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw = audio_calloc (AUDIO_FUNC, 1, glue (drv->voice_size_, TYPE)); 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!hw) { 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Can not allocate voice `%s' size %d\n", 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project drv->name, glue (drv->voice_size_, TYPE)); 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->pcm_ops = drv->pcm_ops; 273a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner QLIST_INIT (&hw->sw_head); 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 275a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner QLIST_INIT (&hw->cap_head); 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BEGIN_NOSIGALRM 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err = glue (hw->pcm_ops->init_, TYPE) (hw, as); 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project END_NOSIGALRM 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (err) 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err0; 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (audio_bug (AUDIO_FUNC, hw->samples <= 0)) { 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("hw->samples=%d\n", hw->samples); 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err1; 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->clip = mixeng_clip 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw->conv = mixeng_conv 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [hw->info.nchannels == 2] 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [hw->info.sign] 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [hw->info.swap_endianness] 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project [audio_bits_to_index (hw->info.bits)]; 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (glue (audio_pcm_hw_alloc_resources_, TYPE) (hw)) { 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err1; 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 302a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner QLIST_INSERT_HEAD (&s->glue (hw_head_, TYPE), hw, entries); 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (s->nb_hw_voices_, TYPE) -= 1; 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner audio_attach_capture (hw); 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return hw; 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err1: 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BEGIN_NOSIGALRM 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (hw->pcm_ops->fini_, TYPE) (hw); 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project END_NOSIGALRM 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project err0: 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (hw); 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic HW *glue (audio_pcm_hw_add_, TYPE) (struct audsettings *as) 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HW *hw; 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (glue (conf.fixed_, TYPE).enabled && glue (conf.fixed_, TYPE).greedy) { 3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner hw = glue (audio_pcm_hw_add_new_, TYPE) (as); 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hw) { 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return hw; 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner hw = glue (audio_pcm_hw_find_specific_, TYPE) (NULL, as); 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hw) { 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return hw; 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner hw = glue (audio_pcm_hw_add_new_, TYPE) (as); 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (hw) { 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return hw; 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return glue (audio_pcm_hw_find_any_, TYPE) (NULL); 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SW *glue (audio_pcm_create_voice_pair_, TYPE) ( 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *sw_name, 3445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings *as 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ) 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SW *sw; 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HW *hw; 3495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings hw_as; 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (glue (conf.fixed_, TYPE).enabled) { 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw_as = glue (conf.fixed_, TYPE).settings; 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hw_as = *as; 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw = audio_calloc (AUDIO_FUNC, 1, sizeof (*sw)); 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!sw) { 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Could not allocate soft voice `%s' (%zu bytes)\n", 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw_name ? sw_name : "unknown", sizeof (*sw)); 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err1; 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner hw = glue (audio_pcm_hw_add_, TYPE) (&hw_as); 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!hw) { 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err2; 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (audio_pcm_hw_add_sw_, TYPE) (hw, sw); 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, sw_name, as)) { 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto err3; 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sw; 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecterr3: 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (audio_pcm_hw_del_sw_, TYPE) (sw); 3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner glue (audio_pcm_hw_gc_, TYPE) (&hw); 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecterr2: 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (sw); 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecterr1: 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void glue (audio_close_, TYPE) (SW *sw) 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (audio_pcm_sw_fini_, TYPE) (sw); 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (audio_pcm_hw_del_sw_, TYPE) (sw); 3915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner glue (audio_pcm_hw_gc_, TYPE) (&sw->hw); 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_free (sw); 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw) 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sw) { 3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (audio_bug (AUDIO_FUNC, !card)) { 3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dolog ("card=%p\n", card); 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner glue (audio_close_, TYPE) (sw); 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSW *glue (AUD_open_, TYPE) ( 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QEMUSoundCard *card, 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SW *sw, 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *name, 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project void *callback_opaque , 412a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner audio_callback_fn callback_fn, 4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct audsettings *as 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ) 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner AudioState *s = &glob_audio_state; 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int live = 0; 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SW *old_sw = NULL; 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ldebug ("open %s, freq %d, nchannels %d, fmt %d\n", 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project name, as->freq, as->nchannels, as->fmt); 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (audio_bug (AUDIO_FUNC, !card || !name || !callback_fn || !as)) { 4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dolog ("card=%p name=%p callback_fn=%p as=%p\n", 4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner card, name, callback_fn, as); 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto fail; 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) { 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project audio_print_settings (as); 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto fail; 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4365d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner if (audio_bug (AUDIO_FUNC, !s->drv)) { 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Can not open `%s' (no host audio driver)\n", name); 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto fail; 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sw && audio_pcm_info_eq (&sw->info, as)) { 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sw; 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (conf.plive && sw && (!sw->active && !sw->empty)) { 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project live = sw->total_hw_samples_mixed; 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_PLIVE 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Replacing voice %s with %d live samples\n", SW_NAME (sw), live); 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Old %s freq %d, bits %d, channels %d\n", 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SW_NAME (sw), sw->info.freq, sw->info.bits, sw->info.nchannels); 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("New %s freq %d, bits %d, channels %d\n", 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project name, 4555d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner as->freq, 4565d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner (as->fmt == AUD_FMT_S16 || as->fmt == AUD_FMT_U16) ? 16 : 8, 4575d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner as->nchannels); 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (live) { 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_sw = sw; 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_sw->callback.fn = NULL; 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw = NULL; 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!glue (conf.fixed_, TYPE).enabled && sw) { 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (AUD_close_, TYPE) (card, sw); 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sw = NULL; 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sw) { 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project HW *hw = sw->hw; 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!hw) { 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Internal logic error voice `%s' has no hardware store\n", 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SW_NAME (sw)); 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto fail; 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (audio_pcm_sw_fini_, TYPE) (sw); 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (glue (audio_pcm_sw_init_, TYPE) (sw, hw, name, as)) { 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto fail; 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sw = glue (audio_pcm_create_voice_pair_, TYPE) (name, as); 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!sw) { 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dolog ("Failed to create voice `%s'\n", name); 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 495a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner sw->card = card; 496a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner sw->vol = nominal_volume; 497a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner sw->callback.fn = callback_fn; 498a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner sw->callback.opaque = callback_opaque; 4995164d3c53f57dfb468ab11136358b6e3b6cf0513David 'Digit' Turner#ifdef DAC 5005164d3c53f57dfb468ab11136358b6e3b6cf0513David 'Digit' Turner sw->empty = 1; 5015164d3c53f57dfb468ab11136358b6e3b6cf0513David 'Digit' Turner#endif 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DAC 504a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner if (live) { 505a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner int mixed = 506a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner (live << old_sw->info.shift) 507a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner * old_sw->info.bytes_per_second 508a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner / sw->info.bytes_per_second; 5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_PLIVE 511a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner dolog ("Silence will be mixed %d\n", mixed); 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 513a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner sw->total_hw_samples_mixed += mixed; 514a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner } 5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_AUDIO 518a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner dolog ("%s\n", name); 519a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner audio_pcm_print_info ("hw", &sw->hw->info); 520a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner audio_pcm_print_info ("sw", &sw->info); 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sw; 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fail: 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project glue (AUD_close_, TYPE) (card, sw); 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint glue (AUD_is_active_, TYPE) (SW *sw) 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sw ? sw->active : 0; 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid glue (AUD_init_time_stamp_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts) 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!sw) { 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ts->old_ts = sw->hw->ts_helper; 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t glue (AUD_get_elapsed_usec_, TYPE) (SW *sw, QEMUAudioTimeStamp *ts) 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint64_t delta, cur_ts, old_ts; 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!sw) { 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cur_ts = sw->hw->ts_helper; 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project old_ts = ts->old_ts; 5545d0e37bc290d1743cb5acf76eb6608f1303f27ddDavid 'Digit' Turner /* dolog ("cur %" PRId64 " old %" PRId64 "\n", cur_ts, old_ts); */ 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (cur_ts >= old_ts) { 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project delta = cur_ts - old_ts; 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project delta = UINT64_MAX - old_ts + cur_ts; 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!delta) { 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 567a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner return muldiv64 (delta, sw->hw->info.freq, 1000000); 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef TYPE 5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef HW 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef SW 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef HWBUF 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NAME 575