mixeng.c revision c27f813900a3c114562efbb8df1065e94766fc48
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 "audio.h" 26 27#define AUDIO_CAP "mixeng" 28#include "audio_int.h" 29 30#define NOVOL 31 32/* 8 bit */ 33#define ENDIAN_CONVERSION natural 34#define ENDIAN_CONVERT(v) (v) 35 36/* Signed 8 bit */ 37#define IN_T int8_t 38#define IN_MIN SCHAR_MIN 39#define IN_MAX SCHAR_MAX 40#define SIGNED 41#define SHIFT 8 42#include "mixeng_template.h" 43#undef SIGNED 44#undef IN_MAX 45#undef IN_MIN 46#undef IN_T 47#undef SHIFT 48 49/* Unsigned 8 bit */ 50#define IN_T uint8_t 51#define IN_MIN 0 52#define IN_MAX UCHAR_MAX 53#define SHIFT 8 54#include "mixeng_template.h" 55#undef IN_MAX 56#undef IN_MIN 57#undef IN_T 58#undef SHIFT 59 60#undef ENDIAN_CONVERT 61#undef ENDIAN_CONVERSION 62 63/* Signed 16 bit */ 64#define IN_T int16_t 65#define IN_MIN SHRT_MIN 66#define IN_MAX SHRT_MAX 67#define SIGNED 68#define SHIFT 16 69#define ENDIAN_CONVERSION natural 70#define ENDIAN_CONVERT(v) (v) 71#include "mixeng_template.h" 72#undef ENDIAN_CONVERT 73#undef ENDIAN_CONVERSION 74#define ENDIAN_CONVERSION swap 75#define ENDIAN_CONVERT(v) bswap16 (v) 76#include "mixeng_template.h" 77#undef ENDIAN_CONVERT 78#undef ENDIAN_CONVERSION 79#undef SIGNED 80#undef IN_MAX 81#undef IN_MIN 82#undef IN_T 83#undef SHIFT 84 85/* Unsigned 16 bit */ 86#define IN_T uint16_t 87#define IN_MIN 0 88#define IN_MAX USHRT_MAX 89#define SHIFT 16 90#define ENDIAN_CONVERSION natural 91#define ENDIAN_CONVERT(v) (v) 92#include "mixeng_template.h" 93#undef ENDIAN_CONVERT 94#undef ENDIAN_CONVERSION 95#define ENDIAN_CONVERSION swap 96#define ENDIAN_CONVERT(v) bswap16 (v) 97#include "mixeng_template.h" 98#undef ENDIAN_CONVERT 99#undef ENDIAN_CONVERSION 100#undef IN_MAX 101#undef IN_MIN 102#undef IN_T 103#undef SHIFT 104 105/* Signed 32 bit */ 106#define IN_T int32_t 107#define IN_MIN INT32_MIN 108#define IN_MAX INT32_MAX 109#define SIGNED 110#define SHIFT 32 111#define ENDIAN_CONVERSION natural 112#define ENDIAN_CONVERT(v) (v) 113#include "mixeng_template.h" 114#undef ENDIAN_CONVERT 115#undef ENDIAN_CONVERSION 116#define ENDIAN_CONVERSION swap 117#define ENDIAN_CONVERT(v) bswap32 (v) 118#include "mixeng_template.h" 119#undef ENDIAN_CONVERT 120#undef ENDIAN_CONVERSION 121#undef SIGNED 122#undef IN_MAX 123#undef IN_MIN 124#undef IN_T 125#undef SHIFT 126 127/* Unsigned 16 bit */ 128#define IN_T uint32_t 129#define IN_MIN 0 130#define IN_MAX UINT32_MAX 131#define SHIFT 32 132#define ENDIAN_CONVERSION natural 133#define ENDIAN_CONVERT(v) (v) 134#include "mixeng_template.h" 135#undef ENDIAN_CONVERT 136#undef ENDIAN_CONVERSION 137#define ENDIAN_CONVERSION swap 138#define ENDIAN_CONVERT(v) bswap32 (v) 139#include "mixeng_template.h" 140#undef ENDIAN_CONVERT 141#undef ENDIAN_CONVERSION 142#undef IN_MAX 143#undef IN_MIN 144#undef IN_T 145#undef SHIFT 146 147t_sample *mixeng_conv[2][2][2][3] = { 148 { 149 { 150 { 151 conv_natural_uint8_t_to_mono, 152 conv_natural_uint16_t_to_mono, 153 conv_natural_uint32_t_to_mono 154 }, 155 { 156 conv_natural_uint8_t_to_mono, 157 conv_swap_uint16_t_to_mono, 158 conv_swap_uint32_t_to_mono, 159 } 160 }, 161 { 162 { 163 conv_natural_int8_t_to_mono, 164 conv_natural_int16_t_to_mono, 165 conv_natural_int32_t_to_mono 166 }, 167 { 168 conv_natural_int8_t_to_mono, 169 conv_swap_int16_t_to_mono, 170 conv_swap_int32_t_to_mono 171 } 172 } 173 }, 174 { 175 { 176 { 177 conv_natural_uint8_t_to_stereo, 178 conv_natural_uint16_t_to_stereo, 179 conv_natural_uint32_t_to_stereo 180 }, 181 { 182 conv_natural_uint8_t_to_stereo, 183 conv_swap_uint16_t_to_stereo, 184 conv_swap_uint32_t_to_stereo 185 } 186 }, 187 { 188 { 189 conv_natural_int8_t_to_stereo, 190 conv_natural_int16_t_to_stereo, 191 conv_natural_int32_t_to_stereo 192 }, 193 { 194 conv_natural_int8_t_to_stereo, 195 conv_swap_int16_t_to_stereo, 196 conv_swap_int32_t_to_stereo, 197 } 198 } 199 } 200}; 201 202f_sample *mixeng_clip[2][2][2][3] = { 203 { 204 { 205 { 206 clip_natural_uint8_t_from_mono, 207 clip_natural_uint16_t_from_mono, 208 clip_natural_uint32_t_from_mono 209 }, 210 { 211 clip_natural_uint8_t_from_mono, 212 clip_swap_uint16_t_from_mono, 213 clip_swap_uint32_t_from_mono 214 } 215 }, 216 { 217 { 218 clip_natural_int8_t_from_mono, 219 clip_natural_int16_t_from_mono, 220 clip_natural_int32_t_from_mono 221 }, 222 { 223 clip_natural_int8_t_from_mono, 224 clip_swap_int16_t_from_mono, 225 clip_swap_int32_t_from_mono 226 } 227 } 228 }, 229 { 230 { 231 { 232 clip_natural_uint8_t_from_stereo, 233 clip_natural_uint16_t_from_stereo, 234 clip_natural_uint32_t_from_stereo 235 }, 236 { 237 clip_natural_uint8_t_from_stereo, 238 clip_swap_uint16_t_from_stereo, 239 clip_swap_uint32_t_from_stereo 240 } 241 }, 242 { 243 { 244 clip_natural_int8_t_from_stereo, 245 clip_natural_int16_t_from_stereo, 246 clip_natural_int32_t_from_stereo 247 }, 248 { 249 clip_natural_int8_t_from_stereo, 250 clip_swap_int16_t_from_stereo, 251 clip_swap_int32_t_from_stereo 252 } 253 } 254 } 255}; 256 257/* 258 * August 21, 1998 259 * Copyright 1998 Fabrice Bellard. 260 * 261 * [Rewrote completly the code of Lance Norskog And Sundry 262 * Contributors with a more efficient algorithm.] 263 * 264 * This source code is freely redistributable and may be used for 265 * any purpose. This copyright notice must be maintained. 266 * Lance Norskog And Sundry Contributors are not responsible for 267 * the consequences of using this software. 268 */ 269 270/* 271 * Sound Tools rate change effect file. 272 */ 273/* 274 * Linear Interpolation. 275 * 276 * The use of fractional increment allows us to use no buffer. It 277 * avoid the problems at the end of the buffer we had with the old 278 * method which stored a possibly big buffer of size 279 * lcm(in_rate,out_rate). 280 * 281 * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If 282 * the input & output frequencies are equal, a delay of one sample is 283 * introduced. Limited to processing 32-bit count worth of samples. 284 * 285 * 1 << FRAC_BITS evaluating to zero in several places. Changed with 286 * an (unsigned long) cast to make it safe. MarkMLl 2/1/99 287 */ 288 289/* Private data */ 290struct rate { 291 uint64_t opos; 292 uint64_t opos_inc; 293 uint32_t ipos; /* position in the input stream (integer) */ 294 st_sample_t ilast; /* last sample in the input stream */ 295}; 296 297/* 298 * Prepare processing. 299 */ 300void *st_rate_start (int inrate, int outrate) 301{ 302 struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate)); 303 304 if (!rate) { 305 dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate)); 306 return NULL; 307 } 308 309 rate->opos = 0; 310 311 /* increment */ 312 rate->opos_inc = ((uint64_t) inrate << 32) / outrate; 313 314 rate->ipos = 0; 315 rate->ilast.l = 0; 316 rate->ilast.r = 0; 317 return rate; 318} 319 320#define NAME st_rate_flow_mix 321#define OP(a, b) a += b 322#include "rate_template.h" 323 324#define NAME st_rate_flow 325#define OP(a, b) a = b 326#include "rate_template.h" 327 328void st_rate_stop (void *opaque) 329{ 330 qemu_free (opaque); 331} 332 333void mixeng_clear (st_sample_t *buf, int len) 334{ 335 memset (buf, 0, len * sizeof (st_sample_t)); 336} 337