1 /* 2 * QEMU Timer based audio emulation 3 * 4 * Copyright (c) 2004-2005 Vassili Karpov (malc) 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "qemu/host-utils.h" 27 #include "qemu/module.h" 28 #include "audio.h" 29 #include "qemu/timer.h" 30 31 #define AUDIO_CAP "noaudio" 32 #include "audio_int.h" 33 34 typedef struct NoVoiceOut { 35 HWVoiceOut hw; 36 RateCtl rate; 37 } NoVoiceOut; 38 39 typedef struct NoVoiceIn { 40 HWVoiceIn hw; 41 RateCtl rate; 42 } NoVoiceIn; 43 44 static size_t no_write(HWVoiceOut *hw, void *buf, size_t len) 45 { 46 NoVoiceOut *no = (NoVoiceOut *) hw; 47 return audio_rate_get_bytes(&no->rate, &hw->info, len); 48 } 49 50 static int no_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque) 51 { 52 NoVoiceOut *no = (NoVoiceOut *) hw; 53 54 audio_pcm_init_info (&hw->info, as); 55 hw->samples = 1024; 56 audio_rate_start(&no->rate); 57 return 0; 58 } 59 60 static void no_fini_out (HWVoiceOut *hw) 61 { 62 (void) hw; 63 } 64 65 static void no_enable_out(HWVoiceOut *hw, bool enable) 66 { 67 NoVoiceOut *no = (NoVoiceOut *) hw; 68 69 if (enable) { 70 audio_rate_start(&no->rate); 71 } 72 } 73 74 static int no_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque) 75 { 76 NoVoiceIn *no = (NoVoiceIn *) hw; 77 78 audio_pcm_init_info (&hw->info, as); 79 hw->samples = 1024; 80 audio_rate_start(&no->rate); 81 return 0; 82 } 83 84 static void no_fini_in (HWVoiceIn *hw) 85 { 86 (void) hw; 87 } 88 89 static size_t no_read(HWVoiceIn *hw, void *buf, size_t size) 90 { 91 NoVoiceIn *no = (NoVoiceIn *) hw; 92 int64_t bytes = audio_rate_get_bytes(&no->rate, &hw->info, size); 93 94 audio_pcm_info_clear_buf(&hw->info, buf, bytes / hw->info.bytes_per_frame); 95 return bytes; 96 } 97 98 static void no_enable_in(HWVoiceIn *hw, bool enable) 99 { 100 NoVoiceIn *no = (NoVoiceIn *) hw; 101 102 if (enable) { 103 audio_rate_start(&no->rate); 104 } 105 } 106 107 static void *no_audio_init(Audiodev *dev, Error **errp) 108 { 109 return &no_audio_init; 110 } 111 112 static void no_audio_fini (void *opaque) 113 { 114 (void) opaque; 115 } 116 117 static struct audio_pcm_ops no_pcm_ops = { 118 .init_out = no_init_out, 119 .fini_out = no_fini_out, 120 .write = no_write, 121 .buffer_get_free = audio_generic_buffer_get_free, 122 .run_buffer_out = audio_generic_run_buffer_out, 123 .enable_out = no_enable_out, 124 125 .init_in = no_init_in, 126 .fini_in = no_fini_in, 127 .read = no_read, 128 .run_buffer_in = audio_generic_run_buffer_in, 129 .enable_in = no_enable_in 130 }; 131 132 static struct audio_driver no_audio_driver = { 133 .name = "none", 134 .descr = "Timer based audio emulation", 135 .init = no_audio_init, 136 .fini = no_audio_fini, 137 .pcm_ops = &no_pcm_ops, 138 .max_voices_out = INT_MAX, 139 .max_voices_in = INT_MAX, 140 .voice_size_out = sizeof (NoVoiceOut), 141 .voice_size_in = sizeof (NoVoiceIn) 142 }; 143 144 static void register_audio_none(void) 145 { 146 audio_driver_register(&no_audio_driver); 147 } 148 type_init(register_audio_none); 149