spapr: Workaround for broken radix guests
[qemu.git] / audio / mixeng.c
1 /*
2 * QEMU Mixing engine
3 *
4 * Copyright (c) 2004-2005 Vassili Karpov (malc)
5 * Copyright (c) 1998 Fabrice Bellard
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
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 /* 8 bit */
35 #define ENDIAN_CONVERSION natural
36 #define ENDIAN_CONVERT(v) (v)
37
38 /* Signed 8 bit */
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 /* Unsigned 8 bit */
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 /* Signed 16 bit */
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 /* Unsigned 16 bit */
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 /* Signed 32 bit */
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 /* Unsigned 32 bit */
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
161 t_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
216 f_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
272 void 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
287 void 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 * August 21, 1998
304 * Copyright 1998 Fabrice Bellard.
305 *
306 * [Rewrote completely the code of Lance Norskog And Sundry
307 * Contributors with a more efficient algorithm.]
308 *
309 * This source code is freely redistributable and may be used for
310 * any purpose. This copyright notice must be maintained.
311 * Lance Norskog And Sundry Contributors are not responsible for
312 * the consequences of using this software.
313 */
314
315 /*
316 * Sound Tools rate change effect file.
317 */
318 /*
319 * Linear Interpolation.
320 *
321 * The use of fractional increment allows us to use no buffer. It
322 * avoid the problems at the end of the buffer we had with the old
323 * method which stored a possibly big buffer of size
324 * lcm(in_rate,out_rate).
325 *
326 * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
327 * the input & output frequencies are equal, a delay of one sample is
328 * introduced. Limited to processing 32-bit count worth of samples.
329 *
330 * 1 << FRAC_BITS evaluating to zero in several places. Changed with
331 * an (unsigned long) cast to make it safe. MarkMLl 2/1/99
332 */
333
334 /* Private data */
335 struct rate {
336 uint64_t opos;
337 uint64_t opos_inc;
338 uint32_t ipos; /* position in the input stream (integer) */
339 struct st_sample ilast; /* last sample in the input stream */
340 };
341
342 /*
343 * Prepare processing.
344 */
345 void *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 /* increment */
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
373 void st_rate_stop (void *opaque)
374 {
375 g_free (opaque);
376 }
377
378 void mixeng_clear (struct st_sample *buf, int len)
379 {
380 memset (buf, 0, len * sizeof (struct st_sample));
381 }
382
383 void 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 }