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
274
275static const float float_scale = (int64_t)INT32_MAX + 1;
276#define CONV_NATURAL_FLOAT(x) ((x) * float_scale)
277
278#ifdef RECIPROCAL
279static const float float_scale_reciprocal = 1.f / ((int64_t)INT32_MAX + 1);
280#define CLIP_NATURAL_FLOAT(x) ((x) * float_scale_reciprocal)
281#else
282#define CLIP_NATURAL_FLOAT(x) ((x) / float_scale)
283#endif
284#endif
285
286static void conv_natural_float_to_mono(struct st_sample *dst, const void *src,
287 int samples)
288{
289 float *in = (float *)src;
290
291 while (samples--) {
292 dst->r = dst->l = CONV_NATURAL_FLOAT(*in++);
293 dst++;
294 }
295}
296
297static void conv_natural_float_to_stereo(struct st_sample *dst, const void *src,
298 int samples)
299{
300 float *in = (float *)src;
301
302 while (samples--) {
303 dst->l = CONV_NATURAL_FLOAT(*in++);
304 dst->r = CONV_NATURAL_FLOAT(*in++);
305 dst++;
306 }
307}
308
309t_sample *mixeng_conv_float[2] = {
310 conv_natural_float_to_mono,
311 conv_natural_float_to_stereo,
312};
313
314static void clip_natural_float_from_mono(void *dst, const struct st_sample *src,
315 int samples)
316{
317 float *out = (float *)dst;
318
319 while (samples--) {
320 *out++ = CLIP_NATURAL_FLOAT(src->l + src->r);
321 src++;
322 }
323}
324
325static void clip_natural_float_from_stereo(
326 void *dst, const struct st_sample *src, int samples)
327{
328 float *out = (float *)dst;
329
330 while (samples--) {
331 *out++ = CLIP_NATURAL_FLOAT(src->l);
332 *out++ = CLIP_NATURAL_FLOAT(src->r);
333 src++;
334 }
335}
336
337f_sample *mixeng_clip_float[2] = {
338 clip_natural_float_from_mono,
339 clip_natural_float_from_stereo,
340};
341
342void audio_sample_to_uint64(const void *samples, int pos,
343 uint64_t *left, uint64_t *right)
344{
345 const struct st_sample *sample = samples;
346 sample += pos;
347#ifdef FLOAT_MIXENG
348 error_report(
349 "Coreaudio and floating point samples are not supported by replay yet");
350 abort();
351#else
352 *left = sample->l;
353 *right = sample->r;
354#endif
355}
356
357void audio_sample_from_uint64(void *samples, int pos,
358 uint64_t left, uint64_t right)
359{
360 struct st_sample *sample = samples;
361 sample += pos;
362#ifdef FLOAT_MIXENG
363 error_report(
364 "Coreaudio and floating point samples are not supported by replay yet");
365 abort();
366#else
367 sample->l = left;
368 sample->r = right;
369#endif
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
404
405struct rate {
406 uint64_t opos;
407 uint64_t opos_inc;
408 uint32_t ipos;
409 struct st_sample ilast;
410};
411
412
413
414
415void *st_rate_start (int inrate, int outrate)
416{
417 struct rate *rate = audio_calloc(__func__, 1, sizeof(*rate));
418
419 if (!rate) {
420 dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
421 return NULL;
422 }
423
424 rate->opos = 0;
425
426
427 rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
428
429 rate->ipos = 0;
430 rate->ilast.l = 0;
431 rate->ilast.r = 0;
432 return rate;
433}
434
435#define NAME st_rate_flow_mix
436#define OP(a, b) a += b
437#include "rate_template.h"
438
439#define NAME st_rate_flow
440#define OP(a, b) a = b
441#include "rate_template.h"
442
443void st_rate_stop (void *opaque)
444{
445 g_free (opaque);
446}
447
448void mixeng_clear (struct st_sample *buf, int len)
449{
450 memset (buf, 0, len * sizeof (struct st_sample));
451}
452
453void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
454{
455 if (vol->mute) {
456 mixeng_clear (buf, len);
457 return;
458 }
459
460 while (len--) {
461#ifdef FLOAT_MIXENG
462 buf->l = buf->l * vol->l;
463 buf->r = buf->r * vol->r;
464#else
465 buf->l = (buf->l * vol->l) >> 32;
466 buf->r = (buf->r * vol->r) >> 32;
467#endif
468 buf += 1;
469 }
470}
471