blob: 0e4976f271e5c180ebdfb7819034a31fab5ea5de [file] [log] [blame]
bellard85571bc2004-11-07 18:04:02 +00001/*
2 * QEMU Mixing engine
3 *
bellard1d14ffa2005-10-30 18:58:22 +00004 * Copyright (c) 2004-2005 Vassili Karpov (malc)
bellard85571bc2004-11-07 18:04:02 +00005 * 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 */
pbrook87ecb682007-11-17 17:14:51 +000025#include "qemu-common.h"
26#include "audio.h"
bellard85571bc2004-11-07 18:04:02 +000027
bellard1d14ffa2005-10-30 18:58:22 +000028#define AUDIO_CAP "mixeng"
29#include "audio_int.h"
30
bellard1d14ffa2005-10-30 18:58:22 +000031/* 8 bit */
32#define ENDIAN_CONVERSION natural
33#define ENDIAN_CONVERT(v) (v)
34
35/* Signed 8 bit */
Roger Pau Monnea2885382012-05-18 12:08:14 +010036#define BSIZE 8
37#define ITYPE int
bellard1d14ffa2005-10-30 18:58:22 +000038#define IN_MIN SCHAR_MIN
39#define IN_MAX SCHAR_MAX
bellard85571bc2004-11-07 18:04:02 +000040#define SIGNED
bellard1d14ffa2005-10-30 18:58:22 +000041#define SHIFT 8
bellard85571bc2004-11-07 18:04:02 +000042#include "mixeng_template.h"
43#undef SIGNED
44#undef IN_MAX
45#undef IN_MIN
Roger Pau Monnea2885382012-05-18 12:08:14 +010046#undef BSIZE
47#undef ITYPE
bellard1d14ffa2005-10-30 18:58:22 +000048#undef SHIFT
bellard85571bc2004-11-07 18:04:02 +000049
bellard1d14ffa2005-10-30 18:58:22 +000050/* Unsigned 8 bit */
Roger Pau Monnea2885382012-05-18 12:08:14 +010051#define BSIZE 8
52#define ITYPE uint
bellard85571bc2004-11-07 18:04:02 +000053#define IN_MIN 0
54#define IN_MAX UCHAR_MAX
bellard1d14ffa2005-10-30 18:58:22 +000055#define SHIFT 8
bellard85571bc2004-11-07 18:04:02 +000056#include "mixeng_template.h"
57#undef IN_MAX
58#undef IN_MIN
Roger Pau Monnea2885382012-05-18 12:08:14 +010059#undef BSIZE
60#undef ITYPE
bellard1d14ffa2005-10-30 18:58:22 +000061#undef SHIFT
bellard85571bc2004-11-07 18:04:02 +000062
bellard1d14ffa2005-10-30 18:58:22 +000063#undef ENDIAN_CONVERT
64#undef ENDIAN_CONVERSION
65
66/* Signed 16 bit */
Roger Pau Monnea2885382012-05-18 12:08:14 +010067#define BSIZE 16
68#define ITYPE int
bellard85571bc2004-11-07 18:04:02 +000069#define IN_MIN SHRT_MIN
70#define IN_MAX SHRT_MAX
71#define SIGNED
bellard1d14ffa2005-10-30 18:58:22 +000072#define SHIFT 16
73#define ENDIAN_CONVERSION natural
74#define ENDIAN_CONVERT(v) (v)
bellard85571bc2004-11-07 18:04:02 +000075#include "mixeng_template.h"
bellard1d14ffa2005-10-30 18:58:22 +000076#undef ENDIAN_CONVERT
77#undef ENDIAN_CONVERSION
78#define ENDIAN_CONVERSION swap
79#define ENDIAN_CONVERT(v) bswap16 (v)
80#include "mixeng_template.h"
81#undef ENDIAN_CONVERT
82#undef ENDIAN_CONVERSION
bellard85571bc2004-11-07 18:04:02 +000083#undef SIGNED
84#undef IN_MAX
85#undef IN_MIN
Roger Pau Monnea2885382012-05-18 12:08:14 +010086#undef BSIZE
87#undef ITYPE
bellard1d14ffa2005-10-30 18:58:22 +000088#undef SHIFT
bellard85571bc2004-11-07 18:04:02 +000089
thsf941aa22007-02-17 22:19:29 +000090/* Unsigned 16 bit */
Roger Pau Monnea2885382012-05-18 12:08:14 +010091#define BSIZE 16
92#define ITYPE uint
bellard85571bc2004-11-07 18:04:02 +000093#define IN_MIN 0
94#define IN_MAX USHRT_MAX
bellard1d14ffa2005-10-30 18:58:22 +000095#define SHIFT 16
96#define ENDIAN_CONVERSION natural
97#define ENDIAN_CONVERT(v) (v)
bellard85571bc2004-11-07 18:04:02 +000098#include "mixeng_template.h"
bellard1d14ffa2005-10-30 18:58:22 +000099#undef ENDIAN_CONVERT
100#undef ENDIAN_CONVERSION
101#define ENDIAN_CONVERSION swap
102#define ENDIAN_CONVERT(v) bswap16 (v)
103#include "mixeng_template.h"
104#undef ENDIAN_CONVERT
105#undef ENDIAN_CONVERSION
bellard85571bc2004-11-07 18:04:02 +0000106#undef IN_MAX
107#undef IN_MIN
Roger Pau Monnea2885382012-05-18 12:08:14 +0100108#undef BSIZE
109#undef ITYPE
bellard1d14ffa2005-10-30 18:58:22 +0000110#undef SHIFT
bellard85571bc2004-11-07 18:04:02 +0000111
thsf941aa22007-02-17 22:19:29 +0000112/* Signed 32 bit */
Roger Pau Monnea2885382012-05-18 12:08:14 +0100113#define BSIZE 32
114#define ITYPE int
thsf941aa22007-02-17 22:19:29 +0000115#define IN_MIN INT32_MIN
116#define IN_MAX INT32_MAX
117#define SIGNED
118#define SHIFT 32
119#define ENDIAN_CONVERSION natural
120#define ENDIAN_CONVERT(v) (v)
121#include "mixeng_template.h"
122#undef ENDIAN_CONVERT
123#undef ENDIAN_CONVERSION
124#define ENDIAN_CONVERSION swap
125#define ENDIAN_CONVERT(v) bswap32 (v)
126#include "mixeng_template.h"
127#undef ENDIAN_CONVERT
128#undef ENDIAN_CONVERSION
129#undef SIGNED
130#undef IN_MAX
131#undef IN_MIN
Roger Pau Monnea2885382012-05-18 12:08:14 +0100132#undef BSIZE
133#undef ITYPE
thsf941aa22007-02-17 22:19:29 +0000134#undef SHIFT
135
malcad483a52010-03-11 18:28:38 +0300136/* Unsigned 32 bit */
Roger Pau Monnea2885382012-05-18 12:08:14 +0100137#define BSIZE 32
138#define ITYPE uint
thsf941aa22007-02-17 22:19:29 +0000139#define IN_MIN 0
140#define IN_MAX UINT32_MAX
141#define SHIFT 32
142#define ENDIAN_CONVERSION natural
143#define ENDIAN_CONVERT(v) (v)
144#include "mixeng_template.h"
145#undef ENDIAN_CONVERT
146#undef ENDIAN_CONVERSION
147#define ENDIAN_CONVERSION swap
148#define ENDIAN_CONVERT(v) bswap32 (v)
149#include "mixeng_template.h"
150#undef ENDIAN_CONVERT
151#undef ENDIAN_CONVERSION
152#undef IN_MAX
153#undef IN_MIN
Roger Pau Monnea2885382012-05-18 12:08:14 +0100154#undef BSIZE
155#undef ITYPE
thsf941aa22007-02-17 22:19:29 +0000156#undef SHIFT
157
158t_sample *mixeng_conv[2][2][2][3] = {
bellard85571bc2004-11-07 18:04:02 +0000159 {
160 {
bellard1d14ffa2005-10-30 18:58:22 +0000161 {
162 conv_natural_uint8_t_to_mono,
thsf941aa22007-02-17 22:19:29 +0000163 conv_natural_uint16_t_to_mono,
164 conv_natural_uint32_t_to_mono
bellard1d14ffa2005-10-30 18:58:22 +0000165 },
166 {
167 conv_natural_uint8_t_to_mono,
thsf941aa22007-02-17 22:19:29 +0000168 conv_swap_uint16_t_to_mono,
169 conv_swap_uint32_t_to_mono,
bellard1d14ffa2005-10-30 18:58:22 +0000170 }
bellard85571bc2004-11-07 18:04:02 +0000171 },
172 {
bellard1d14ffa2005-10-30 18:58:22 +0000173 {
174 conv_natural_int8_t_to_mono,
thsf941aa22007-02-17 22:19:29 +0000175 conv_natural_int16_t_to_mono,
176 conv_natural_int32_t_to_mono
bellard1d14ffa2005-10-30 18:58:22 +0000177 },
178 {
179 conv_natural_int8_t_to_mono,
thsf941aa22007-02-17 22:19:29 +0000180 conv_swap_int16_t_to_mono,
181 conv_swap_int32_t_to_mono
bellard1d14ffa2005-10-30 18:58:22 +0000182 }
bellard85571bc2004-11-07 18:04:02 +0000183 }
184 },
185 {
186 {
bellard1d14ffa2005-10-30 18:58:22 +0000187 {
188 conv_natural_uint8_t_to_stereo,
thsf941aa22007-02-17 22:19:29 +0000189 conv_natural_uint16_t_to_stereo,
190 conv_natural_uint32_t_to_stereo
bellard1d14ffa2005-10-30 18:58:22 +0000191 },
192 {
193 conv_natural_uint8_t_to_stereo,
thsf941aa22007-02-17 22:19:29 +0000194 conv_swap_uint16_t_to_stereo,
195 conv_swap_uint32_t_to_stereo
bellard1d14ffa2005-10-30 18:58:22 +0000196 }
bellard85571bc2004-11-07 18:04:02 +0000197 },
198 {
bellard1d14ffa2005-10-30 18:58:22 +0000199 {
200 conv_natural_int8_t_to_stereo,
thsf941aa22007-02-17 22:19:29 +0000201 conv_natural_int16_t_to_stereo,
202 conv_natural_int32_t_to_stereo
bellard1d14ffa2005-10-30 18:58:22 +0000203 },
204 {
205 conv_natural_int8_t_to_stereo,
thsf941aa22007-02-17 22:19:29 +0000206 conv_swap_int16_t_to_stereo,
207 conv_swap_int32_t_to_stereo,
bellard1d14ffa2005-10-30 18:58:22 +0000208 }
bellard85571bc2004-11-07 18:04:02 +0000209 }
210 }
211};
212
thsf941aa22007-02-17 22:19:29 +0000213f_sample *mixeng_clip[2][2][2][3] = {
bellard85571bc2004-11-07 18:04:02 +0000214 {
215 {
bellard1d14ffa2005-10-30 18:58:22 +0000216 {
217 clip_natural_uint8_t_from_mono,
thsf941aa22007-02-17 22:19:29 +0000218 clip_natural_uint16_t_from_mono,
219 clip_natural_uint32_t_from_mono
bellard1d14ffa2005-10-30 18:58:22 +0000220 },
221 {
222 clip_natural_uint8_t_from_mono,
thsf941aa22007-02-17 22:19:29 +0000223 clip_swap_uint16_t_from_mono,
224 clip_swap_uint32_t_from_mono
bellard1d14ffa2005-10-30 18:58:22 +0000225 }
bellard85571bc2004-11-07 18:04:02 +0000226 },
227 {
bellard1d14ffa2005-10-30 18:58:22 +0000228 {
229 clip_natural_int8_t_from_mono,
thsf941aa22007-02-17 22:19:29 +0000230 clip_natural_int16_t_from_mono,
231 clip_natural_int32_t_from_mono
bellard1d14ffa2005-10-30 18:58:22 +0000232 },
233 {
234 clip_natural_int8_t_from_mono,
thsf941aa22007-02-17 22:19:29 +0000235 clip_swap_int16_t_from_mono,
236 clip_swap_int32_t_from_mono
bellard1d14ffa2005-10-30 18:58:22 +0000237 }
bellard85571bc2004-11-07 18:04:02 +0000238 }
239 },
240 {
241 {
bellard1d14ffa2005-10-30 18:58:22 +0000242 {
243 clip_natural_uint8_t_from_stereo,
thsf941aa22007-02-17 22:19:29 +0000244 clip_natural_uint16_t_from_stereo,
245 clip_natural_uint32_t_from_stereo
bellard1d14ffa2005-10-30 18:58:22 +0000246 },
247 {
248 clip_natural_uint8_t_from_stereo,
thsf941aa22007-02-17 22:19:29 +0000249 clip_swap_uint16_t_from_stereo,
250 clip_swap_uint32_t_from_stereo
bellard1d14ffa2005-10-30 18:58:22 +0000251 }
bellard85571bc2004-11-07 18:04:02 +0000252 },
253 {
bellard1d14ffa2005-10-30 18:58:22 +0000254 {
255 clip_natural_int8_t_from_stereo,
thsf941aa22007-02-17 22:19:29 +0000256 clip_natural_int16_t_from_stereo,
257 clip_natural_int32_t_from_stereo
bellard1d14ffa2005-10-30 18:58:22 +0000258 },
259 {
260 clip_natural_int8_t_from_stereo,
thsf941aa22007-02-17 22:19:29 +0000261 clip_swap_int16_t_from_stereo,
262 clip_swap_int32_t_from_stereo
bellard1d14ffa2005-10-30 18:58:22 +0000263 }
bellard85571bc2004-11-07 18:04:02 +0000264 }
265 }
266};
267
268/*
269 * August 21, 1998
270 * Copyright 1998 Fabrice Bellard.
271 *
272 * [Rewrote completly the code of Lance Norskog And Sundry
273 * Contributors with a more efficient algorithm.]
274 *
275 * This source code is freely redistributable and may be used for
bellard1d14ffa2005-10-30 18:58:22 +0000276 * any purpose. This copyright notice must be maintained.
277 * Lance Norskog And Sundry Contributors are not responsible for
278 * the consequences of using this software.
bellard85571bc2004-11-07 18:04:02 +0000279 */
280
281/*
282 * Sound Tools rate change effect file.
283 */
284/*
285 * Linear Interpolation.
286 *
287 * The use of fractional increment allows us to use no buffer. It
288 * avoid the problems at the end of the buffer we had with the old
289 * method which stored a possibly big buffer of size
290 * lcm(in_rate,out_rate).
291 *
292 * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
293 * the input & output frequencies are equal, a delay of one sample is
294 * introduced. Limited to processing 32-bit count worth of samples.
295 *
296 * 1 << FRAC_BITS evaluating to zero in several places. Changed with
297 * an (unsigned long) cast to make it safe. MarkMLl 2/1/99
298 */
299
300/* Private data */
bellardc0fe3822005-11-05 18:55:28 +0000301struct rate {
bellard85571bc2004-11-07 18:04:02 +0000302 uint64_t opos;
303 uint64_t opos_inc;
304 uint32_t ipos; /* position in the input stream (integer) */
malc1ea879e2008-12-03 22:48:44 +0000305 struct st_sample ilast; /* last sample in the input stream */
bellardc0fe3822005-11-05 18:55:28 +0000306};
bellard85571bc2004-11-07 18:04:02 +0000307
308/*
309 * Prepare processing.
310 */
311void *st_rate_start (int inrate, int outrate)
312{
bellardc0fe3822005-11-05 18:55:28 +0000313 struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
bellard85571bc2004-11-07 18:04:02 +0000314
315 if (!rate) {
bellarde7cad332005-11-11 00:03:36 +0000316 dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
bellard1d14ffa2005-10-30 18:58:22 +0000317 return NULL;
bellard85571bc2004-11-07 18:04:02 +0000318 }
319
320 rate->opos = 0;
321
322 /* increment */
bellard1d14ffa2005-10-30 18:58:22 +0000323 rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
bellard85571bc2004-11-07 18:04:02 +0000324
325 rate->ipos = 0;
326 rate->ilast.l = 0;
327 rate->ilast.r = 0;
328 return rate;
329}
330
bellard1d14ffa2005-10-30 18:58:22 +0000331#define NAME st_rate_flow_mix
332#define OP(a, b) a += b
333#include "rate_template.h"
bellard85571bc2004-11-07 18:04:02 +0000334
bellard1d14ffa2005-10-30 18:58:22 +0000335#define NAME st_rate_flow
336#define OP(a, b) a = b
337#include "rate_template.h"
bellard85571bc2004-11-07 18:04:02 +0000338
339void st_rate_stop (void *opaque)
340{
Anthony Liguori7267c092011-08-20 22:09:37 -0500341 g_free (opaque);
bellard85571bc2004-11-07 18:04:02 +0000342}
bellard1d14ffa2005-10-30 18:58:22 +0000343
malc1ea879e2008-12-03 22:48:44 +0000344void mixeng_clear (struct st_sample *buf, int len)
bellard1d14ffa2005-10-30 18:58:22 +0000345{
malc1ea879e2008-12-03 22:48:44 +0000346 memset (buf, 0, len * sizeof (struct st_sample));
bellard1d14ffa2005-10-30 18:58:22 +0000347}
Michael Walle00e07672011-01-05 01:05:47 +0100348
349void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
350{
Michael Walle00e07672011-01-05 01:05:47 +0100351 if (vol->mute) {
352 mixeng_clear (buf, len);
353 return;
354 }
355
356 while (len--) {
357#ifdef FLOAT_MIXENG
358 buf->l = buf->l * vol->l;
359 buf->r = buf->r * vol->r;
360#else
361 buf->l = (buf->l * vol->l) >> 32;
362 buf->r = (buf->r * vol->r) >> 32;
363#endif
364 buf += 1;
365 }
Michael Walle00e07672011-01-05 01:05:47 +0100366}