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 "qemu-common.h" 26 #include "audio.h" 27 28 #define AUDIO_CAP "mixeng" 29 #include "audio_int.h" 30 31 /* 8 bit */ 32 #define ENDIAN_CONVERSION natural 33 #define ENDIAN_CONVERT(v) (v) 34 35 /* Signed 8 bit */ 36 #define BSIZE 8 37 #define ITYPE int 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 BSIZE 47 #undef ITYPE 48 #undef SHIFT 49 50 /* Unsigned 8 bit */ 51 #define BSIZE 8 52 #define ITYPE uint 53 #define IN_MIN 0 54 #define IN_MAX UCHAR_MAX 55 #define SHIFT 8 56 #include "mixeng_template.h" 57 #undef IN_MAX 58 #undef IN_MIN 59 #undef BSIZE 60 #undef ITYPE 61 #undef SHIFT 62 63 #undef ENDIAN_CONVERT 64 #undef ENDIAN_CONVERSION 65 66 /* Signed 16 bit */ 67 #define BSIZE 16 68 #define ITYPE int 69 #define IN_MIN SHRT_MIN 70 #define IN_MAX SHRT_MAX 71 #define SIGNED 72 #define SHIFT 16 73 #define ENDIAN_CONVERSION natural 74 #define ENDIAN_CONVERT(v) (v) 75 #include "mixeng_template.h" 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 83 #undef SIGNED 84 #undef IN_MAX 85 #undef IN_MIN 86 #undef BSIZE 87 #undef ITYPE 88 #undef SHIFT 89 90 /* Unsigned 16 bit */ 91 #define BSIZE 16 92 #define ITYPE uint 93 #define IN_MIN 0 94 #define IN_MAX USHRT_MAX 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) 103 #include "mixeng_template.h" 104 #undef ENDIAN_CONVERT 105 #undef ENDIAN_CONVERSION 106 #undef IN_MAX 107 #undef IN_MIN 108 #undef BSIZE 109 #undef ITYPE 110 #undef SHIFT 111 112 /* Signed 32 bit */ 113 #define BSIZE 32 114 #define ITYPE int 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 132 #undef BSIZE 133 #undef ITYPE 134 #undef SHIFT 135 136 /* Unsigned 32 bit */ 137 #define BSIZE 32 138 #define ITYPE uint 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 154 #undef BSIZE 155 #undef ITYPE 156 #undef SHIFT 157 158 t_sample *mixeng_conv[2][2][2][3] = { 159 { 160 { 161 { 162 conv_natural_uint8_t_to_mono, 163 conv_natural_uint16_t_to_mono, 164 conv_natural_uint32_t_to_mono 165 }, 166 { 167 conv_natural_uint8_t_to_mono, 168 conv_swap_uint16_t_to_mono, 169 conv_swap_uint32_t_to_mono, 170 } 171 }, 172 { 173 { 174 conv_natural_int8_t_to_mono, 175 conv_natural_int16_t_to_mono, 176 conv_natural_int32_t_to_mono 177 }, 178 { 179 conv_natural_int8_t_to_mono, 180 conv_swap_int16_t_to_mono, 181 conv_swap_int32_t_to_mono 182 } 183 } 184 }, 185 { 186 { 187 { 188 conv_natural_uint8_t_to_stereo, 189 conv_natural_uint16_t_to_stereo, 190 conv_natural_uint32_t_to_stereo 191 }, 192 { 193 conv_natural_uint8_t_to_stereo, 194 conv_swap_uint16_t_to_stereo, 195 conv_swap_uint32_t_to_stereo 196 } 197 }, 198 { 199 { 200 conv_natural_int8_t_to_stereo, 201 conv_natural_int16_t_to_stereo, 202 conv_natural_int32_t_to_stereo 203 }, 204 { 205 conv_natural_int8_t_to_stereo, 206 conv_swap_int16_t_to_stereo, 207 conv_swap_int32_t_to_stereo, 208 } 209 } 210 } 211 }; 212 213 f_sample *mixeng_clip[2][2][2][3] = { 214 { 215 { 216 { 217 clip_natural_uint8_t_from_mono, 218 clip_natural_uint16_t_from_mono, 219 clip_natural_uint32_t_from_mono 220 }, 221 { 222 clip_natural_uint8_t_from_mono, 223 clip_swap_uint16_t_from_mono, 224 clip_swap_uint32_t_from_mono 225 } 226 }, 227 { 228 { 229 clip_natural_int8_t_from_mono, 230 clip_natural_int16_t_from_mono, 231 clip_natural_int32_t_from_mono 232 }, 233 { 234 clip_natural_int8_t_from_mono, 235 clip_swap_int16_t_from_mono, 236 clip_swap_int32_t_from_mono 237 } 238 } 239 }, 240 { 241 { 242 { 243 clip_natural_uint8_t_from_stereo, 244 clip_natural_uint16_t_from_stereo, 245 clip_natural_uint32_t_from_stereo 246 }, 247 { 248 clip_natural_uint8_t_from_stereo, 249 clip_swap_uint16_t_from_stereo, 250 clip_swap_uint32_t_from_stereo 251 } 252 }, 253 { 254 { 255 clip_natural_int8_t_from_stereo, 256 clip_natural_int16_t_from_stereo, 257 clip_natural_int32_t_from_stereo 258 }, 259 { 260 clip_natural_int8_t_from_stereo, 261 clip_swap_int16_t_from_stereo, 262 clip_swap_int32_t_from_stereo 263 } 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 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. 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 */ 301 struct rate { 302 uint64_t opos; 303 uint64_t opos_inc; 304 uint32_t ipos; /* position in the input stream (integer) */ 305 struct st_sample ilast; /* last sample in the input stream */ 306 }; 307 308 /* 309 * Prepare processing. 310 */ 311 void *st_rate_start (int inrate, int outrate) 312 { 313 struct rate *rate = audio_calloc (AUDIO_FUNC, 1, sizeof (*rate)); 314 315 if (!rate) { 316 dolog ("Could not allocate resampler (%zu bytes)\n", sizeof (*rate)); 317 return NULL; 318 } 319 320 rate->opos = 0; 321 322 /* increment */ 323 rate->opos_inc = ((uint64_t) inrate << 32) / outrate; 324 325 rate->ipos = 0; 326 rate->ilast.l = 0; 327 rate->ilast.r = 0; 328 return rate; 329 } 330 331 #define NAME st_rate_flow_mix 332 #define OP(a, b) a += b 333 #include "rate_template.h" 334 335 #define NAME st_rate_flow 336 #define OP(a, b) a = b 337 #include "rate_template.h" 338 339 void st_rate_stop (void *opaque) 340 { 341 g_free (opaque); 342 } 343 344 void mixeng_clear (struct st_sample *buf, int len) 345 { 346 memset (buf, 0, len * sizeof (struct st_sample)); 347 } 348 349 void 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 } 373