1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "qemu-common.h"
27#include "qemu/bswap.h"
28#include "qemu/error-report.h"
29#include "audio.h"
30
31#define AUDIO_CAP "mixeng"
32#include "audio_int.h"
33
34
35#define ENDIAN_CONVERSION natural
36#define ENDIAN_CONVERT(v) (v)
37
38
39#define BSIZE 8
40#define ITYPE int
41#define IN_MIN SCHAR_MIN
42#define IN_MAX SCHAR_MAX
43#define SIGNED
44#define SHIFT 8
45#include "mixeng_template.h"
46#undef SIGNED
47#undef IN_MAX
48#undef IN_MIN
49#undef BSIZE
50#undef ITYPE
51#undef SHIFT
52
53
54#define BSIZE 8
55#define ITYPE uint
56#define IN_MIN 0
57#define IN_MAX UCHAR_MAX
58#define SHIFT 8
59#include "mixeng_template.h"
60#undef IN_MAX
61#undef IN_MIN
62#undef BSIZE
63#undef ITYPE
64#undef SHIFT
65
66#undef ENDIAN_CONVERT
67#undef ENDIAN_CONVERSION
68
69
70#define BSIZE 16
71#define ITYPE int
72#define IN_MIN SHRT_MIN
73#define IN_MAX SHRT_MAX
74#define SIGNED
75#define SHIFT 16
76#define ENDIAN_CONVERSION natural
77#define ENDIAN_CONVERT(v) (v)
78#include "mixeng_template.h"
79#undef ENDIAN_CONVERT
80#undef ENDIAN_CONVERSION
81#define ENDIAN_CONVERSION swap
82#define ENDIAN_CONVERT(v) bswap16 (v)
83#include "mixeng_template.h"
84#undef ENDIAN_CONVERT
85#undef ENDIAN_CONVERSION
86#undef SIGNED
87#undef IN_MAX
88#undef IN_MIN
89#undef BSIZE
90#undef ITYPE
91#undef SHIFT
92
93
94#define BSIZE 16
95#define ITYPE uint
96#define IN_MIN 0
97#define IN_MAX USHRT_MAX
98#define SHIFT 16
99#define ENDIAN_CONVERSION natural
100#define ENDIAN_CONVERT(v) (v)
101#include "mixeng_template.h"
102#undef ENDIAN_CONVERT
103#undef ENDIAN_CONVERSION
104#define ENDIAN_CONVERSION swap
105#define ENDIAN_CONVERT(v) bswap16 (v)
106#include "mixeng_template.h"
107#undef ENDIAN_CONVERT
108#undef ENDIAN_CONVERSION
109#undef IN_MAX
110#undef IN_MIN
111#undef BSIZE
112#undef ITYPE
113#undef SHIFT
114
115
116#define BSIZE 32
117#define ITYPE int
118#define IN_MIN INT32_MIN
119#define IN_MAX INT32_MAX
120#define SIGNED
121#define SHIFT 32
122#define ENDIAN_CONVERSION natural
123#define ENDIAN_CONVERT(v) (v)
124#include "mixeng_template.h"
125#undef ENDIAN_CONVERT
126#undef ENDIAN_CONVERSION
127#define ENDIAN_CONVERSION swap
128#define ENDIAN_CONVERT(v) bswap32 (v)
129#include "mixeng_template.h"
130#undef ENDIAN_CONVERT
131#undef ENDIAN_CONVERSION
132#undef SIGNED
133#undef IN_MAX
134#undef IN_MIN
135#undef BSIZE
136#undef ITYPE
137#undef SHIFT
138
139
140#define BSIZE 32
141#define ITYPE uint
142#define IN_MIN 0
143#define IN_MAX UINT32_MAX
144#define SHIFT 32
145#define ENDIAN_CONVERSION natural
146#define ENDIAN_CONVERT(v) (v)
147#include "mixeng_template.h"
148#undef ENDIAN_CONVERT
149#undef ENDIAN_CONVERSION
150#define ENDIAN_CONVERSION swap
151#define ENDIAN_CONVERT(v) bswap32 (v)
152#include "mixeng_template.h"
153#undef ENDIAN_CONVERT
154#undef ENDIAN_CONVERSION
155#undef IN_MAX
156#undef IN_MIN
157#undef BSIZE
158#undef ITYPE
159#undef SHIFT
160
161t_sample *mixeng_conv[2][2][2][3] = {
162 {
163 {
164 {
165 conv_natural_uint8_t_to_mono,
166 conv_natural_uint16_t_to_mono,
167 conv_natural_uint32_t_to_mono
168 },
169 {
170 conv_natural_uint8_t_to_mono,
171 conv_swap_uint16_t_to_mono,
172 conv_swap_uint32_t_to_mono,
173 }
174 },
175 {
176 {
177 conv_natural_int8_t_to_mono,
178 conv_natural_int16_t_to_mono,
179 conv_natural_int32_t_to_mono
180 },
181 {
182 conv_natural_int8_t_to_mono,
183 conv_swap_int16_t_to_mono,
184 conv_swap_int32_t_to_mono
185 }
186 }
187 },
188 {
189 {
190 {
191 conv_natural_uint8_t_to_stereo,
192 conv_natural_uint16_t_to_stereo,
193 conv_natural_uint32_t_to_stereo
194 },
195 {
196 conv_natural_uint8_t_to_stereo,
197 conv_swap_uint16_t_to_stereo,
198 conv_swap_uint32_t_to_stereo
199 }
200 },
201 {
202 {
203 conv_natural_int8_t_to_stereo,
204 conv_natural_int16_t_to_stereo,
205 conv_natural_int32_t_to_stereo
206 },
207 {
208 conv_natural_int8_t_to_stereo,
209 conv_swap_int16_t_to_stereo,
210 conv_swap_int32_t_to_stereo,
211 }
212 }
213 }
214};
215
216f_sample *mixeng_clip[2][2][2][3] = {
217 {
218 {
219 {
220 clip_natural_uint8_t_from_mono,
221 clip_natural_uint16_t_from_mono,
222 clip_natural_uint32_t_from_mono
223 },
224 {
225 clip_natural_uint8_t_from_mono,
226 clip_swap_uint16_t_from_mono,
227 clip_swap_uint32_t_from_mono
228 }
229 },
230 {
231 {
232 clip_natural_int8_t_from_mono,
233 clip_natural_int16_t_from_mono,
234 clip_natural_int32_t_from_mono
235 },
236 {
237 clip_natural_int8_t_from_mono,
238 clip_swap_int16_t_from_mono,
239 clip_swap_int32_t_from_mono
240 }
241 }
242 },
243 {
244 {
245 {
246 clip_natural_uint8_t_from_stereo,
247 clip_natural_uint16_t_from_stereo,
248 clip_natural_uint32_t_from_stereo
249 },
250 {
251 clip_natural_uint8_t_from_stereo,
252 clip_swap_uint16_t_from_stereo,
253 clip_swap_uint32_t_from_stereo
254 }
255 },
256 {
257 {
258 clip_natural_int8_t_from_stereo,
259 clip_natural_int16_t_from_stereo,
260 clip_natural_int32_t_from_stereo
261 },
262 {
263 clip_natural_int8_t_from_stereo,
264 clip_swap_int16_t_from_stereo,
265 clip_swap_int32_t_from_stereo
266 }
267 }
268 }
269};
270
271
272void audio_sample_to_uint64(void *samples, int pos,
273 uint64_t *left, uint64_t *right)
274{
275 struct st_sample *sample = samples;
276 sample += pos;
277#ifdef FLOAT_MIXENG
278 error_report(
279 "Coreaudio and floating point samples are not supported by replay yet");
280 abort();
281#else
282 *left = sample->l;
283 *right = sample->r;
284#endif
285}
286
287void audio_sample_from_uint64(void *samples, int pos,
288 uint64_t left, uint64_t right)
289{
290 struct st_sample *sample = samples;
291 sample += pos;
292#ifdef FLOAT_MIXENG
293 error_report(
294 "Coreaudio and floating point samples are not supported by replay yet");
295 abort();
296#else
297 sample->l = left;
298 sample->r = right;
299#endif
300}
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335struct rate {
336 uint64_t opos;
337 uint64_t opos_inc;
338 uint32_t ipos;
339 struct st_sample ilast;
340};
341
342
343
344
345void *st_rate_start (int inrate, int outrate)
346{
347 struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
348
349 if (!rate) {
350 dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
351 return NULL;
352 }
353
354 rate->opos = 0;
355
356
357 rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
358
359 rate->ipos = 0;
360 rate->ilast.l = 0;
361 rate->ilast.r = 0;
362 return rate;
363}
364
365#define NAME st_rate_flow_mix
366#define OP(a, b) a += b
367#include "rate_template.h"
368
369#define NAME st_rate_flow
370#define OP(a, b) a = b
371#include "rate_template.h"
372
373void st_rate_stop (void *opaque)
374{
375 g_free (opaque);
376}
377
378void mixeng_clear (struct st_sample *buf, int len)
379{
380 memset (buf, 0, len * sizeof (struct st_sample));
381}
382
383void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
384{
385 if (vol->mute) {
386 mixeng_clear (buf, len);
387 return;
388 }
389
390 while (len--) {
391#ifdef FLOAT_MIXENG
392 buf->l = buf->l * vol->l;
393 buf->r = buf->r * vol->r;
394#else
395 buf->l = (buf->l * vol->l) >> 32;
396 buf->r = (buf->r * vol->r) >> 32;
397#endif
398 buf += 1;
399 }
400}
401