]> git.proxmox.com Git - qemu.git/blame - audio/mixeng.c
qom: improve documentation of cast functions
[qemu.git] / audio / mixeng.c
CommitLineData
85571bc7
FB
1/*
2 * QEMU Mixing engine
3 *
1d14ffa9 4 * Copyright (c) 2004-2005 Vassili Karpov (malc)
85571bc7
FB
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 */
87ecb68b
PB
25#include "qemu-common.h"
26#include "audio.h"
85571bc7 27
1d14ffa9
FB
28#define AUDIO_CAP "mixeng"
29#include "audio_int.h"
30
1d14ffa9
FB
31/* 8 bit */
32#define ENDIAN_CONVERSION natural
33#define ENDIAN_CONVERT(v) (v)
34
35/* Signed 8 bit */
a2885387
RPM
36#define BSIZE 8
37#define ITYPE int
1d14ffa9
FB
38#define IN_MIN SCHAR_MIN
39#define IN_MAX SCHAR_MAX
85571bc7 40#define SIGNED
1d14ffa9 41#define SHIFT 8
85571bc7
FB
42#include "mixeng_template.h"
43#undef SIGNED
44#undef IN_MAX
45#undef IN_MIN
a2885387
RPM
46#undef BSIZE
47#undef ITYPE
1d14ffa9 48#undef SHIFT
85571bc7 49
1d14ffa9 50/* Unsigned 8 bit */
a2885387
RPM
51#define BSIZE 8
52#define ITYPE uint
85571bc7
FB
53#define IN_MIN 0
54#define IN_MAX UCHAR_MAX
1d14ffa9 55#define SHIFT 8
85571bc7
FB
56#include "mixeng_template.h"
57#undef IN_MAX
58#undef IN_MIN
a2885387
RPM
59#undef BSIZE
60#undef ITYPE
1d14ffa9
FB
61#undef SHIFT
62
63#undef ENDIAN_CONVERT
64#undef ENDIAN_CONVERSION
85571bc7 65
1d14ffa9 66/* Signed 16 bit */
a2885387
RPM
67#define BSIZE 16
68#define ITYPE int
85571bc7
FB
69#define IN_MIN SHRT_MIN
70#define IN_MAX SHRT_MAX
71#define SIGNED
1d14ffa9
FB
72#define SHIFT 16
73#define ENDIAN_CONVERSION natural
74#define ENDIAN_CONVERT(v) (v)
85571bc7 75#include "mixeng_template.h"
1d14ffa9
FB
76#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
85571bc7
FB
83#undef SIGNED
84#undef IN_MAX
85#undef IN_MIN
a2885387
RPM
86#undef BSIZE
87#undef ITYPE
1d14ffa9 88#undef SHIFT
85571bc7 89
f941aa25 90/* Unsigned 16 bit */
a2885387
RPM
91#define BSIZE 16
92#define ITYPE uint
85571bc7
FB
93#define IN_MIN 0
94#define IN_MAX USHRT_MAX
1d14ffa9
FB
95#define SHIFT 16
96#define ENDIAN_CONVERSION natural
97#define ENDIAN_CONVERT(v) (v)
98#include "mixeng_template.h"
99#undef ENDIAN_CONVERT
100#undef ENDIAN_CONVERSION
101#define ENDIAN_CONVERSION swap
102#define ENDIAN_CONVERT(v) bswap16 (v)
85571bc7 103#include "mixeng_template.h"
1d14ffa9
FB
104#undef ENDIAN_CONVERT
105#undef ENDIAN_CONVERSION
85571bc7
FB
106#undef IN_MAX
107#undef IN_MIN
a2885387
RPM
108#undef BSIZE
109#undef ITYPE
1d14ffa9 110#undef SHIFT
85571bc7 111
f941aa25 112/* Signed 32 bit */
a2885387
RPM
113#define BSIZE 32
114#define ITYPE int
f941aa25
TS
115#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
a2885387
RPM
132#undef BSIZE
133#undef ITYPE
f941aa25
TS
134#undef SHIFT
135
ad483a51 136/* Unsigned 32 bit */
a2885387
RPM
137#define BSIZE 32
138#define ITYPE uint
f941aa25
TS
139#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
a2885387
RPM
154#undef BSIZE
155#undef ITYPE
f941aa25
TS
156#undef SHIFT
157
158t_sample *mixeng_conv[2][2][2][3] = {
85571bc7
FB
159 {
160 {
1d14ffa9
FB
161 {
162 conv_natural_uint8_t_to_mono,
f941aa25
TS
163 conv_natural_uint16_t_to_mono,
164 conv_natural_uint32_t_to_mono
1d14ffa9
FB
165 },
166 {
167 conv_natural_uint8_t_to_mono,
f941aa25
TS
168 conv_swap_uint16_t_to_mono,
169 conv_swap_uint32_t_to_mono,
1d14ffa9 170 }
85571bc7
FB
171 },
172 {
1d14ffa9
FB
173 {
174 conv_natural_int8_t_to_mono,
f941aa25
TS
175 conv_natural_int16_t_to_mono,
176 conv_natural_int32_t_to_mono
1d14ffa9
FB
177 },
178 {
179 conv_natural_int8_t_to_mono,
f941aa25
TS
180 conv_swap_int16_t_to_mono,
181 conv_swap_int32_t_to_mono
1d14ffa9 182 }
85571bc7
FB
183 }
184 },
185 {
186 {
1d14ffa9
FB
187 {
188 conv_natural_uint8_t_to_stereo,
f941aa25
TS
189 conv_natural_uint16_t_to_stereo,
190 conv_natural_uint32_t_to_stereo
1d14ffa9
FB
191 },
192 {
193 conv_natural_uint8_t_to_stereo,
f941aa25
TS
194 conv_swap_uint16_t_to_stereo,
195 conv_swap_uint32_t_to_stereo
1d14ffa9 196 }
85571bc7
FB
197 },
198 {
1d14ffa9
FB
199 {
200 conv_natural_int8_t_to_stereo,
f941aa25
TS
201 conv_natural_int16_t_to_stereo,
202 conv_natural_int32_t_to_stereo
1d14ffa9
FB
203 },
204 {
205 conv_natural_int8_t_to_stereo,
f941aa25
TS
206 conv_swap_int16_t_to_stereo,
207 conv_swap_int32_t_to_stereo,
1d14ffa9 208 }
85571bc7
FB
209 }
210 }
211};
212
f941aa25 213f_sample *mixeng_clip[2][2][2][3] = {
85571bc7
FB
214 {
215 {
1d14ffa9
FB
216 {
217 clip_natural_uint8_t_from_mono,
f941aa25
TS
218 clip_natural_uint16_t_from_mono,
219 clip_natural_uint32_t_from_mono
1d14ffa9
FB
220 },
221 {
222 clip_natural_uint8_t_from_mono,
f941aa25
TS
223 clip_swap_uint16_t_from_mono,
224 clip_swap_uint32_t_from_mono
1d14ffa9 225 }
85571bc7
FB
226 },
227 {
1d14ffa9
FB
228 {
229 clip_natural_int8_t_from_mono,
f941aa25
TS
230 clip_natural_int16_t_from_mono,
231 clip_natural_int32_t_from_mono
1d14ffa9
FB
232 },
233 {
234 clip_natural_int8_t_from_mono,
f941aa25
TS
235 clip_swap_int16_t_from_mono,
236 clip_swap_int32_t_from_mono
1d14ffa9 237 }
85571bc7
FB
238 }
239 },
240 {
241 {
1d14ffa9
FB
242 {
243 clip_natural_uint8_t_from_stereo,
f941aa25
TS
244 clip_natural_uint16_t_from_stereo,
245 clip_natural_uint32_t_from_stereo
1d14ffa9
FB
246 },
247 {
248 clip_natural_uint8_t_from_stereo,
f941aa25
TS
249 clip_swap_uint16_t_from_stereo,
250 clip_swap_uint32_t_from_stereo
1d14ffa9 251 }
85571bc7
FB
252 },
253 {
1d14ffa9
FB
254 {
255 clip_natural_int8_t_from_stereo,
f941aa25
TS
256 clip_natural_int16_t_from_stereo,
257 clip_natural_int32_t_from_stereo
1d14ffa9
FB
258 },
259 {
260 clip_natural_int8_t_from_stereo,
f941aa25
TS
261 clip_swap_int16_t_from_stereo,
262 clip_swap_int32_t_from_stereo
1d14ffa9 263 }
85571bc7
FB
264 }
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
1d14ffa9
FB
276 * 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.
85571bc7
FB
279 */
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 */
c0fe3827 301struct rate {
85571bc7
FB
302 uint64_t opos;
303 uint64_t opos_inc;
304 uint32_t ipos; /* position in the input stream (integer) */
1ea879e5 305 struct st_sample ilast; /* last sample in the input stream */
c0fe3827 306};
85571bc7
FB
307
308/*
309 * Prepare processing.
310 */
311void *st_rate_start (int inrate, int outrate)
312{
c0fe3827 313 struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
85571bc7
FB
314
315 if (!rate) {
e7cad338 316 dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
1d14ffa9 317 return NULL;
85571bc7
FB
318 }
319
320 rate->opos = 0;
321
322 /* increment */
1d14ffa9 323 rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
85571bc7
FB
324
325 rate->ipos = 0;
326 rate->ilast.l = 0;
327 rate->ilast.r = 0;
328 return rate;
329}
330
1d14ffa9
FB
331#define NAME st_rate_flow_mix
332#define OP(a, b) a += b
333#include "rate_template.h"
85571bc7 334
1d14ffa9
FB
335#define NAME st_rate_flow
336#define OP(a, b) a = b
337#include "rate_template.h"
85571bc7
FB
338
339void st_rate_stop (void *opaque)
340{
7267c094 341 g_free (opaque);
85571bc7 342}
1d14ffa9 343
1ea879e5 344void mixeng_clear (struct st_sample *buf, int len)
1d14ffa9 345{
1ea879e5 346 memset (buf, 0, len * sizeof (struct st_sample));
1d14ffa9 347}
00e07679
MW
348
349void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
350{
351#ifdef CONFIG_MIXEMU
352 if (vol->mute) {
353 mixeng_clear (buf, len);
354 return;
355 }
356
357 while (len--) {
358#ifdef FLOAT_MIXENG
359 buf->l = buf->l * vol->l;
360 buf->r = buf->r * vol->r;
361#else
362 buf->l = (buf->l * vol->l) >> 32;
363 buf->r = (buf->r * vol->r) >> 32;
364#endif
365 buf += 1;
366 }
367#else
368 (void) buf;
369 (void) len;
370 (void) vol;
371#endif
372}