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
271void audio_sample_to_uint64(void *samples, int pos,
272 uint64_t *left, uint64_t *right)
273{
274 struct st_sample *sample = samples;
275 sample += pos;
276#ifdef FLOAT_MIXENG
277 error_report(
278 "Coreaudio and floating point samples are not supported by replay yet");
279 abort();
280#else
281 *left = sample->l;
282 *right = sample->r;
283#endif
284}
285
286void audio_sample_from_uint64(void *samples, int pos,
287 uint64_t left, uint64_t right)
288{
289 struct st_sample *sample = samples;
290 sample += pos;
291#ifdef FLOAT_MIXENG
292 error_report(
293 "Coreaudio and floating point samples are not supported by replay yet");
294 abort();
295#else
296 sample->l = left;
297 sample->r = right;
298#endif
299}
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
334struct rate {
335 uint64_t opos;
336 uint64_t opos_inc;
337 uint32_t ipos;
338 struct st_sample ilast;
339};
340
341
342
343
344void *st_rate_start (int inrate, int outrate)
345{
346 struct rate *rate = audio_calloc(__func__, 1, sizeof(*rate));
347
348 if (!rate) {
349 dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
350 return NULL;
351 }
352
353 rate->opos = 0;
354
355
356 rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
357
358 rate->ipos = 0;
359 rate->ilast.l = 0;
360 rate->ilast.r = 0;
361 return rate;
362}
363
364#define NAME st_rate_flow_mix
365#define OP(a, b) a += b
366#include "rate_template.h"
367
368#define NAME st_rate_flow
369#define OP(a, b) a = b
370#include "rate_template.h"
371
372void st_rate_stop (void *opaque)
373{
374 g_free (opaque);
375}
376
377void mixeng_clear (struct st_sample *buf, int len)
378{
379 memset (buf, 0, len * sizeof (struct st_sample));
380}
381
382void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
383{
384 if (vol->mute) {
385 mixeng_clear (buf, len);
386 return;
387 }
388
389 while (len--) {
390#ifdef FLOAT_MIXENG
391 buf->l = buf->l * vol->l;
392 buf->r = buf->r * vol->r;
393#else
394 buf->l = (buf->l * vol->l) >> 32;
395 buf->r = (buf->r * vol->r) >> 32;
396#endif
397 buf += 1;
398 }
399}
400