mixeng.c 9.1 KB
Newer Older
B
bellard 已提交
1 2 3
/*
 * QEMU Mixing engine
 *
4
 * Copyright (c) 2004-2005 Vassili Karpov (malc)
B
bellard 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 * Copyright (c) 1998 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
P
Peter Maydell 已提交
25
#include "qemu/osdep.h"
P
pbrook 已提交
26
#include "qemu-common.h"
27
#include "qemu/bswap.h"
P
pbrook 已提交
28
#include "audio.h"
B
bellard 已提交
29

30 31 32 33 34 35 36 37
#define AUDIO_CAP "mixeng"
#include "audio_int.h"

/* 8 bit */
#define ENDIAN_CONVERSION natural
#define ENDIAN_CONVERT(v) (v)

/* Signed 8 bit */
38 39
#define BSIZE 8
#define ITYPE int
40 41
#define IN_MIN SCHAR_MIN
#define IN_MAX SCHAR_MAX
B
bellard 已提交
42
#define SIGNED
43
#define SHIFT 8
B
bellard 已提交
44 45 46 47
#include "mixeng_template.h"
#undef SIGNED
#undef IN_MAX
#undef IN_MIN
48 49
#undef BSIZE
#undef ITYPE
50
#undef SHIFT
B
bellard 已提交
51

52
/* Unsigned 8 bit */
53 54
#define BSIZE 8
#define ITYPE uint
B
bellard 已提交
55 56
#define IN_MIN 0
#define IN_MAX UCHAR_MAX
57
#define SHIFT 8
B
bellard 已提交
58 59 60
#include "mixeng_template.h"
#undef IN_MAX
#undef IN_MIN
61 62
#undef BSIZE
#undef ITYPE
63 64 65 66
#undef SHIFT

#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
B
bellard 已提交
67

68
/* Signed 16 bit */
69 70
#define BSIZE 16
#define ITYPE int
B
bellard 已提交
71 72 73
#define IN_MIN SHRT_MIN
#define IN_MAX SHRT_MAX
#define SIGNED
74 75 76
#define SHIFT 16
#define ENDIAN_CONVERSION natural
#define ENDIAN_CONVERT(v) (v)
B
bellard 已提交
77
#include "mixeng_template.h"
78 79 80 81 82 83 84
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
#define ENDIAN_CONVERSION swap
#define ENDIAN_CONVERT(v) bswap16 (v)
#include "mixeng_template.h"
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
B
bellard 已提交
85 86 87
#undef SIGNED
#undef IN_MAX
#undef IN_MIN
88 89
#undef BSIZE
#undef ITYPE
90
#undef SHIFT
B
bellard 已提交
91

92
/* Unsigned 16 bit */
93 94
#define BSIZE 16
#define ITYPE uint
B
bellard 已提交
95 96
#define IN_MIN 0
#define IN_MAX USHRT_MAX
97 98 99 100 101 102 103 104
#define SHIFT 16
#define ENDIAN_CONVERSION natural
#define ENDIAN_CONVERT(v) (v)
#include "mixeng_template.h"
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
#define ENDIAN_CONVERSION swap
#define ENDIAN_CONVERT(v) bswap16 (v)
B
bellard 已提交
105
#include "mixeng_template.h"
106 107
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
B
bellard 已提交
108 109
#undef IN_MAX
#undef IN_MIN
110 111
#undef BSIZE
#undef ITYPE
112
#undef SHIFT
B
bellard 已提交
113

114
/* Signed 32 bit */
115 116
#define BSIZE 32
#define ITYPE int
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
#define IN_MIN INT32_MIN
#define IN_MAX INT32_MAX
#define SIGNED
#define SHIFT 32
#define ENDIAN_CONVERSION natural
#define ENDIAN_CONVERT(v) (v)
#include "mixeng_template.h"
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
#define ENDIAN_CONVERSION swap
#define ENDIAN_CONVERT(v) bswap32 (v)
#include "mixeng_template.h"
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
#undef SIGNED
#undef IN_MAX
#undef IN_MIN
134 135
#undef BSIZE
#undef ITYPE
136 137
#undef SHIFT

M
malc 已提交
138
/* Unsigned 32 bit */
139 140
#define BSIZE 32
#define ITYPE uint
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
#define IN_MIN 0
#define IN_MAX UINT32_MAX
#define SHIFT 32
#define ENDIAN_CONVERSION natural
#define ENDIAN_CONVERT(v) (v)
#include "mixeng_template.h"
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
#define ENDIAN_CONVERSION swap
#define ENDIAN_CONVERT(v) bswap32 (v)
#include "mixeng_template.h"
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
#undef IN_MAX
#undef IN_MIN
156 157
#undef BSIZE
#undef ITYPE
158 159 160
#undef SHIFT

t_sample *mixeng_conv[2][2][2][3] = {
B
bellard 已提交
161 162
    {
        {
163 164
            {
                conv_natural_uint8_t_to_mono,
165 166
                conv_natural_uint16_t_to_mono,
                conv_natural_uint32_t_to_mono
167 168 169
            },
            {
                conv_natural_uint8_t_to_mono,
170 171
                conv_swap_uint16_t_to_mono,
                conv_swap_uint32_t_to_mono,
172
            }
B
bellard 已提交
173 174
        },
        {
175 176
            {
                conv_natural_int8_t_to_mono,
177 178
                conv_natural_int16_t_to_mono,
                conv_natural_int32_t_to_mono
179 180 181
            },
            {
                conv_natural_int8_t_to_mono,
182 183
                conv_swap_int16_t_to_mono,
                conv_swap_int32_t_to_mono
184
            }
B
bellard 已提交
185 186 187 188
        }
    },
    {
        {
189 190
            {
                conv_natural_uint8_t_to_stereo,
191 192
                conv_natural_uint16_t_to_stereo,
                conv_natural_uint32_t_to_stereo
193 194 195
            },
            {
                conv_natural_uint8_t_to_stereo,
196 197
                conv_swap_uint16_t_to_stereo,
                conv_swap_uint32_t_to_stereo
198
            }
B
bellard 已提交
199 200
        },
        {
201 202
            {
                conv_natural_int8_t_to_stereo,
203 204
                conv_natural_int16_t_to_stereo,
                conv_natural_int32_t_to_stereo
205 206 207
            },
            {
                conv_natural_int8_t_to_stereo,
208 209
                conv_swap_int16_t_to_stereo,
                conv_swap_int32_t_to_stereo,
210
            }
B
bellard 已提交
211 212 213 214
        }
    }
};

215
f_sample *mixeng_clip[2][2][2][3] = {
B
bellard 已提交
216 217
    {
        {
218 219
            {
                clip_natural_uint8_t_from_mono,
220 221
                clip_natural_uint16_t_from_mono,
                clip_natural_uint32_t_from_mono
222 223 224
            },
            {
                clip_natural_uint8_t_from_mono,
225 226
                clip_swap_uint16_t_from_mono,
                clip_swap_uint32_t_from_mono
227
            }
B
bellard 已提交
228 229
        },
        {
230 231
            {
                clip_natural_int8_t_from_mono,
232 233
                clip_natural_int16_t_from_mono,
                clip_natural_int32_t_from_mono
234 235 236
            },
            {
                clip_natural_int8_t_from_mono,
237 238
                clip_swap_int16_t_from_mono,
                clip_swap_int32_t_from_mono
239
            }
B
bellard 已提交
240 241 242 243
        }
    },
    {
        {
244 245
            {
                clip_natural_uint8_t_from_stereo,
246 247
                clip_natural_uint16_t_from_stereo,
                clip_natural_uint32_t_from_stereo
248 249 250
            },
            {
                clip_natural_uint8_t_from_stereo,
251 252
                clip_swap_uint16_t_from_stereo,
                clip_swap_uint32_t_from_stereo
253
            }
B
bellard 已提交
254 255
        },
        {
256 257
            {
                clip_natural_int8_t_from_stereo,
258 259
                clip_natural_int16_t_from_stereo,
                clip_natural_int32_t_from_stereo
260 261 262
            },
            {
                clip_natural_int8_t_from_stereo,
263 264
                clip_swap_int16_t_from_stereo,
                clip_swap_int32_t_from_stereo
265
            }
B
bellard 已提交
266 267 268 269 270 271 272 273
        }
    }
};

/*
 * August 21, 1998
 * Copyright 1998 Fabrice Bellard.
 *
S
Stefan Weil 已提交
274
 * [Rewrote completely the code of Lance Norskog And Sundry
B
bellard 已提交
275 276 277
 * Contributors with a more efficient algorithm.]
 *
 * This source code is freely redistributable and may be used for
278 279 280
 * any purpose.  This copyright notice must be maintained.
 * Lance Norskog And Sundry Contributors are not responsible for
 * the consequences of using this software.
B
bellard 已提交
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
 */

/*
 * Sound Tools rate change effect file.
 */
/*
 * Linear Interpolation.
 *
 * The use of fractional increment allows us to use no buffer. It
 * avoid the problems at the end of the buffer we had with the old
 * method which stored a possibly big buffer of size
 * lcm(in_rate,out_rate).
 *
 * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
 * the input & output frequencies are equal, a delay of one sample is
 * introduced.  Limited to processing 32-bit count worth of samples.
 *
 * 1 << FRAC_BITS evaluating to zero in several places.  Changed with
 * an (unsigned long) cast to make it safe.  MarkMLl 2/1/99
 */

/* Private data */
B
bellard 已提交
303
struct rate {
B
bellard 已提交
304 305 306
    uint64_t opos;
    uint64_t opos_inc;
    uint32_t ipos;              /* position in the input stream (integer) */
M
malc 已提交
307
    struct st_sample ilast;          /* last sample in the input stream */
B
bellard 已提交
308
};
B
bellard 已提交
309 310 311 312 313 314

/*
 * Prepare processing.
 */
void *st_rate_start (int inrate, int outrate)
{
B
bellard 已提交
315
    struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate));
B
bellard 已提交
316 317

    if (!rate) {
B
bellard 已提交
318
        dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
319
        return NULL;
B
bellard 已提交
320 321 322 323 324
    }

    rate->opos = 0;

    /* increment */
325
    rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
B
bellard 已提交
326 327 328 329 330 331 332

    rate->ipos = 0;
    rate->ilast.l = 0;
    rate->ilast.r = 0;
    return rate;
}

333 334 335
#define NAME st_rate_flow_mix
#define OP(a, b) a += b
#include "rate_template.h"
B
bellard 已提交
336

337 338 339
#define NAME st_rate_flow
#define OP(a, b) a = b
#include "rate_template.h"
B
bellard 已提交
340 341 342

void st_rate_stop (void *opaque)
{
343
    g_free (opaque);
B
bellard 已提交
344
}
345

M
malc 已提交
346
void mixeng_clear (struct st_sample *buf, int len)
347
{
M
malc 已提交
348
    memset (buf, 0, len * sizeof (struct st_sample));
349
}
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368

void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
{
    if (vol->mute) {
        mixeng_clear (buf, len);
        return;
    }

    while (len--) {
#ifdef FLOAT_MIXENG
        buf->l = buf->l * vol->l;
        buf->r = buf->r * vol->r;
#else
        buf->l = (buf->l * vol->l) >> 32;
        buf->r = (buf->r * vol->r) >> 32;
#endif
        buf += 1;
    }
}