mixeng.c 6.8 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 25 26
 * 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.
 */
#include "vl.h"

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

#define NOVOL

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

/* Signed 8 bit */
B
bellard 已提交
37
#define IN_T int8_t
38 39
#define IN_MIN SCHAR_MIN
#define IN_MAX SCHAR_MAX
B
bellard 已提交
40
#define SIGNED
41
#define SHIFT 8
B
bellard 已提交
42 43 44 45 46
#include "mixeng_template.h"
#undef SIGNED
#undef IN_MAX
#undef IN_MIN
#undef IN_T
47
#undef SHIFT
B
bellard 已提交
48

49
/* Unsigned 8 bit */
B
bellard 已提交
50 51 52
#define IN_T uint8_t
#define IN_MIN 0
#define IN_MAX UCHAR_MAX
53
#define SHIFT 8
B
bellard 已提交
54 55 56 57
#include "mixeng_template.h"
#undef IN_MAX
#undef IN_MIN
#undef IN_T
58 59 60 61
#undef SHIFT

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

63
/* Signed 16 bit */
B
bellard 已提交
64 65 66 67
#define IN_T int16_t
#define IN_MIN SHRT_MIN
#define IN_MAX SHRT_MAX
#define SIGNED
68 69 70
#define SHIFT 16
#define ENDIAN_CONVERSION natural
#define ENDIAN_CONVERT(v) (v)
B
bellard 已提交
71
#include "mixeng_template.h"
72 73 74 75 76 77 78
#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 已提交
79 80 81 82
#undef SIGNED
#undef IN_MAX
#undef IN_MIN
#undef IN_T
83
#undef SHIFT
B
bellard 已提交
84 85 86 87

#define IN_T uint16_t
#define IN_MIN 0
#define IN_MAX USHRT_MAX
88 89 90 91 92 93 94 95
#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 已提交
96
#include "mixeng_template.h"
97 98
#undef ENDIAN_CONVERT
#undef ENDIAN_CONVERSION
B
bellard 已提交
99 100 101
#undef IN_MAX
#undef IN_MIN
#undef IN_T
102
#undef SHIFT
B
bellard 已提交
103

104
t_sample *mixeng_conv[2][2][2][2] = {
B
bellard 已提交
105 106
    {
        {
107 108 109 110 111 112 113 114
            {
                conv_natural_uint8_t_to_mono,
                conv_natural_uint16_t_to_mono
            },
            {
                conv_natural_uint8_t_to_mono,
                conv_swap_uint16_t_to_mono
            }
B
bellard 已提交
115 116
        },
        {
117 118 119 120 121 122 123 124
            {
                conv_natural_int8_t_to_mono,
                conv_natural_int16_t_to_mono
            },
            {
                conv_natural_int8_t_to_mono,
                conv_swap_int16_t_to_mono
            }
B
bellard 已提交
125 126 127 128
        }
    },
    {
        {
129 130 131 132 133 134 135 136
            {
                conv_natural_uint8_t_to_stereo,
                conv_natural_uint16_t_to_stereo
            },
            {
                conv_natural_uint8_t_to_stereo,
                conv_swap_uint16_t_to_stereo
            }
B
bellard 已提交
137 138
        },
        {
139 140 141 142 143 144 145 146
            {
                conv_natural_int8_t_to_stereo,
                conv_natural_int16_t_to_stereo
            },
            {
                conv_natural_int8_t_to_stereo,
                conv_swap_int16_t_to_stereo
            }
B
bellard 已提交
147 148 149 150
        }
    }
};

151
f_sample *mixeng_clip[2][2][2][2] = {
B
bellard 已提交
152 153
    {
        {
154 155 156 157 158 159 160 161
            {
                clip_natural_uint8_t_from_mono,
                clip_natural_uint16_t_from_mono
            },
            {
                clip_natural_uint8_t_from_mono,
                clip_swap_uint16_t_from_mono
            }
B
bellard 已提交
162 163
        },
        {
164 165 166 167 168 169 170 171
            {
                clip_natural_int8_t_from_mono,
                clip_natural_int16_t_from_mono
            },
            {
                clip_natural_int8_t_from_mono,
                clip_swap_int16_t_from_mono
            }
B
bellard 已提交
172 173 174 175
        }
    },
    {
        {
176 177 178 179 180 181 182 183
            {
                clip_natural_uint8_t_from_stereo,
                clip_natural_uint16_t_from_stereo
            },
            {
                clip_natural_uint8_t_from_stereo,
                clip_swap_uint16_t_from_stereo
            }
B
bellard 已提交
184 185
        },
        {
186 187 188 189 190 191 192 193
            {
                clip_natural_int8_t_from_stereo,
                clip_natural_int16_t_from_stereo
            },
            {
                clip_natural_int8_t_from_stereo,
                clip_swap_int16_t_from_stereo
            }
B
bellard 已提交
194 195 196 197 198 199 200 201 202 203 204 205
        }
    }
};

/*
 * August 21, 1998
 * Copyright 1998 Fabrice Bellard.
 *
 * [Rewrote completly the code of Lance Norskog And Sundry
 * Contributors with a more efficient algorithm.]
 *
 * This source code is freely redistributable and may be used for
206 207 208
 * 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 已提交
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
 */

/*
 * 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 已提交
231
struct rate {
B
bellard 已提交
232 233 234 235
    uint64_t opos;
    uint64_t opos_inc;
    uint32_t ipos;              /* position in the input stream (integer) */
    st_sample_t ilast;          /* last sample in the input stream */
B
bellard 已提交
236
};
B
bellard 已提交
237 238 239 240 241 242

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

    if (!rate) {
B
bellard 已提交
246
        dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate));
247
        return NULL;
B
bellard 已提交
248 249 250 251 252
    }

    rate->opos = 0;

    /* increment */
253
    rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
B
bellard 已提交
254 255 256 257 258 259 260

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

261 262 263
#define NAME st_rate_flow_mix
#define OP(a, b) a += b
#include "rate_template.h"
B
bellard 已提交
264

265 266 267
#define NAME st_rate_flow
#define OP(a, b) a = b
#include "rate_template.h"
B
bellard 已提交
268 269 270 271 272

void st_rate_stop (void *opaque)
{
    qemu_free (opaque);
}
273 274 275 276 277

void mixeng_clear (st_sample_t *buf, int len)
{
    memset (buf, 0, len * sizeof (st_sample_t));
}