master
h 285 lines 8.73 KB
Raw
1 /*
2 * QEMU Audio subsystem header
3 *
4 * Copyright (c) 2003-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 #ifndef QEMU_AUDIO_INT_H
26 #define QEMU_AUDIO_INT_H
27
28 #ifdef CONFIG_AUDIO_COREAUDIO
29 #define FLOAT_MIXENG
30 /* #define RECIPROCAL */
31 #endif
32 #include "qemu/audio.h"
33 #include "qemu/audio-capture.h"
34 #include "mixeng.h"
35
36 struct audio_callback {
37 void *opaque;
38 audio_callback_fn fn;
39 };
40
41 struct audio_pcm_info {
42 AudioFormat af;
43 int freq;
44 int nchannels;
45 int bytes_per_frame;
46 int bytes_per_second;
47 int swap_endianness;
48 };
49
50 typedef struct AudioMixengBackend AudioMixengBackend;
51 typedef struct SWVoiceCap SWVoiceCap;
52
53 typedef struct STSampleBuffer {
54 size_t pos, size;
55 st_sample *buffer;
56 } STSampleBuffer;
57
58 typedef struct HWVoiceOut {
59 AudioMixengBackend *s;
60 bool enabled;
61 int poll_mode;
62 bool pending_disable;
63 struct audio_pcm_info info;
64
65 f_sample *clip;
66
67 STSampleBuffer mix_buf;
68 void *buf_emul;
69 size_t pos_emul, pending_emul, size_emul;
70
71 size_t samples;
72 QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
73 QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
74 QLIST_ENTRY (HWVoiceOut) entries;
75 } HWVoiceOut;
76
77 typedef struct HWVoiceIn {
78 AudioMixengBackend *s;
79 bool enabled;
80 int poll_mode;
81 struct audio_pcm_info info;
82
83 t_sample *conv;
84
85 size_t total_samples_captured;
86
87 STSampleBuffer conv_buf;
88 void *buf_emul;
89 size_t pos_emul, pending_emul, size_emul;
90
91 size_t samples;
92 QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
93 QLIST_ENTRY (HWVoiceIn) entries;
94 } HWVoiceIn;
95
96 struct SWVoiceOut {
97 AudioMixengBackend *s;
98 struct audio_pcm_info info;
99 t_sample *conv;
100 STSampleBuffer resample_buf;
101 void *rate;
102 size_t total_hw_samples_mixed;
103 bool active;
104 bool empty;
105 HWVoiceOut *hw;
106 char *name;
107 struct mixeng_volume vol;
108 struct audio_callback callback;
109 QLIST_ENTRY (SWVoiceOut) entries;
110 };
111
112 struct SWVoiceIn {
113 AudioMixengBackend *s;
114 bool active;
115 struct audio_pcm_info info;
116 void *rate;
117 size_t total_hw_samples_acquired;
118 STSampleBuffer resample_buf;
119 f_sample *clip;
120 HWVoiceIn *hw;
121 char *name;
122 struct mixeng_volume vol;
123 struct audio_callback callback;
124 QLIST_ENTRY (SWVoiceIn) entries;
125 };
126
127 audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo);
128 int audioformat_bytes_per_sample(AudioFormat fmt);
129 int audio_buffer_frames(AudiodevPerDirectionOptions *pdo,
130 audsettings *as, int def_usecs);
131 int audio_buffer_samples(AudiodevPerDirectionOptions *pdo,
132 audsettings *as, int def_usecs);
133 int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo,
134 audsettings *as, int def_usecs);
135
136 static inline void *advance(void *p, size_t incr)
137 {
138 return (uint8_t *)p + incr;
139 }
140
141 int wav_start_capture(AudioBackend *state, CaptureState *s, const char *path,
142 int freq, int bits, int nchannels);
143
144 void audio_generic_initialize_buffer_in(HWVoiceIn *hw);
145 void audio_generic_run_buffer_in(HWVoiceIn *hw);
146 void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size);
147 void audio_generic_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size);
148 void audio_generic_initialize_buffer_out(HWVoiceOut *hw);
149 void audio_generic_run_buffer_out(HWVoiceOut *hw);
150 size_t audio_generic_buffer_get_free(HWVoiceOut *hw);
151 void *audio_generic_get_buffer_out(HWVoiceOut *hw, size_t *size);
152 size_t audio_generic_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size);
153 size_t audio_generic_write(HWVoiceOut *hw, void *buf, size_t size);
154 size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size);
155
156 struct capture_callback {
157 struct audio_capture_ops ops;
158 void *opaque;
159 QLIST_ENTRY (capture_callback) entries;
160 };
161
162 struct CaptureVoiceOut {
163 HWVoiceOut hw;
164 void *buf;
165 QLIST_HEAD (cb_listhead, capture_callback) cb_head;
166 QLIST_ENTRY (CaptureVoiceOut) entries;
167 };
168
169 struct SWVoiceCap {
170 SWVoiceOut sw;
171 CaptureVoiceOut *cap;
172 QLIST_ENTRY (SWVoiceCap) entries;
173 };
174
175 struct AudioMixengBackendClass {
176 AudioBackendClass parent_class;
177
178 int max_voices_out;
179 int max_voices_in;
180 size_t voice_size_out;
181 size_t voice_size_in;
182
183 int (*init_out)(HWVoiceOut *hw, audsettings *as);
184 void (*fini_out)(HWVoiceOut *hw);
185 size_t (*write) (HWVoiceOut *hw, void *buf, size_t size);
186 void (*run_buffer_out)(HWVoiceOut *hw);
187 /*
188 * Get the free output buffer size. This is an upper limit. The size
189 * returned by function get_buffer_out may be smaller.
190 */
191 size_t (*buffer_get_free)(HWVoiceOut *hw);
192 /*
193 * get a buffer that after later can be passed to put_buffer_out; optional
194 * returns the buffer, and writes it's size to size (in bytes)
195 */
196 void *(*get_buffer_out)(HWVoiceOut *hw, size_t *size);
197 /*
198 * put back the buffer returned by get_buffer_out; optional
199 * buf must be equal the pointer returned by get_buffer_out,
200 * size may be smaller
201 */
202 size_t (*put_buffer_out)(HWVoiceOut *hw, void *buf, size_t size);
203 void (*enable_out)(HWVoiceOut *hw, bool enable);
204 void (*volume_out)(HWVoiceOut *hw, Volume *vol);
205
206 int (*init_in) (HWVoiceIn *hw, audsettings *as);
207 void (*fini_in) (HWVoiceIn *hw);
208 size_t (*read) (HWVoiceIn *hw, void *buf, size_t size);
209 void (*run_buffer_in)(HWVoiceIn *hw);
210 void *(*get_buffer_in)(HWVoiceIn *hw, size_t *size);
211 void (*put_buffer_in)(HWVoiceIn *hw, void *buf, size_t size);
212 void (*enable_in)(HWVoiceIn *hw, bool enable);
213 void (*volume_in)(HWVoiceIn *hw, Volume *vol);
214 };
215
216 struct AudioMixengBackend {
217 AudioBackend parent_obj;
218
219 Audiodev *dev;
220
221 QEMUTimer *ts;
222 GTimer *run_timer;
223 QLIST_HEAD (hw_in_listhead, HWVoiceIn) hw_head_in;
224 QLIST_HEAD (hw_out_listhead, HWVoiceOut) hw_head_out;
225 QLIST_HEAD (cap_listhead, CaptureVoiceOut) cap_head;
226 int nb_hw_voices_out;
227 int nb_hw_voices_in;
228 int64_t period_ticks;
229
230 bool timer_running;
231 uint64_t timer_last;
232 VMChangeStateEntry *vmse;
233 };
234
235 extern const struct mixeng_volume nominal_volume;
236
237 extern const char *audio_prio_list[];
238
239 void audio_pcm_init_info (struct audio_pcm_info *info, const struct audsettings *as);
240 void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
241
242 void audio_run(AudioMixengBackend *s, const char *msg);
243
244 typedef struct RateCtl {
245 int64_t start_ticks;
246 int64_t bytes_sent;
247 int64_t peeked_frames;
248 } RateCtl;
249
250 void audio_rate_start(RateCtl *rate);
251 size_t audio_rate_peek_bytes(RateCtl *rate, struct audio_pcm_info *info);
252 void audio_rate_add_bytes(RateCtl *rate, size_t bytes_used);
253 size_t audio_rate_get_bytes(RateCtl *rate, struct audio_pcm_info *info,
254 size_t bytes_avail);
255
256 static inline size_t audio_ring_dist(size_t dst, size_t src, size_t len)
257 {
258 return (dst >= src) ? (dst - src) : (len - src + dst);
259 }
260
261 /**
262 * audio_ring_posb() - returns new position in ringbuffer in backward
263 * direction at given distance
264 *
265 * @pos: current position in ringbuffer
266 * @dist: distance in ringbuffer to walk in reverse direction
267 * @len: size of ringbuffer
268 */
269 static inline size_t audio_ring_posb(size_t pos, size_t dist, size_t len)
270 {
271 return pos >= dist ? pos - dist : len - dist + pos;
272 }
273
274 AudiodevPerDirectionOptions *audio_get_pdo_in(Audiodev *dev);
275 AudiodevPerDirectionOptions *audio_get_pdo_out(Audiodev *dev);
276
277 void audio_sample_to_uint64(const st_sample *sample, int pos,
278 uint64_t *left, uint64_t *right);
279 void audio_sample_from_uint64(st_sample *sample, int pos,
280 uint64_t left, uint64_t right);
281
282 #define TYPE_AUDIO_MIXENG_BACKEND "audio-mixeng-backend"
283 OBJECT_DECLARE_TYPE(AudioMixengBackend, AudioMixengBackendClass, AUDIO_MIXENG_BACKEND)
284
285 #endif /* QEMU_AUDIO_INT_H */