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