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 "vl.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 #define IN_T uint16_t 86 #define IN_MIN 0 87 #define IN_MAX USHRT_MAX 88 #define SHIFT 16 89 #define ENDIAN_CONVERSION natural 90 #define ENDIAN_CONVERT(v) (v) 91 #include "mixeng_template.h" 92 #undef ENDIAN_CONVERT 93 #undef ENDIAN_CONVERSION 94 #define ENDIAN_CONVERSION swap 95 #define ENDIAN_CONVERT(v) bswap16 (v) 96 #include "mixeng_template.h" 97 #undef ENDIAN_CONVERT 98 #undef ENDIAN_CONVERSION 99 #undef IN_MAX 100 #undef IN_MIN 101 #undef IN_T 102 #undef SHIFT 103 104 t_sample *mixeng_conv[2][2][2][2] = { 105 { 106 { 107 { 108 conv_natural_uint8_t_to_mono, 109 conv_natural_uint16_t_to_mono 110 }, 111 { 112 conv_natural_uint8_t_to_mono, 113 conv_swap_uint16_t_to_mono 114 } 115 }, 116 { 117 { 118 conv_natural_int8_t_to_mono, 119 conv_natural_int16_t_to_mono 120 }, 121 { 122 conv_natural_int8_t_to_mono, 123 conv_swap_int16_t_to_mono 124 } 125 } 126 }, 127 { 128 { 129 { 130 conv_natural_uint8_t_to_stereo, 131 conv_natural_uint16_t_to_stereo 132 }, 133 { 134 conv_natural_uint8_t_to_stereo, 135 conv_swap_uint16_t_to_stereo 136 } 137 }, 138 { 139 { 140 conv_natural_int8_t_to_stereo, 141 conv_natural_int16_t_to_stereo 142 }, 143 { 144 conv_natural_int8_t_to_stereo, 145 conv_swap_int16_t_to_stereo 146 } 147 } 148 } 149 }; 150 151 f_sample *mixeng_clip[2][2][2][2] = { 152 { 153 { 154 { 155 clip_natural_uint8_t_from_mono, 156 clip_natural_uint16_t_from_mono 157 }, 158 { 159 clip_natural_uint8_t_from_mono, 160 clip_swap_uint16_t_from_mono 161 } 162 }, 163 { 164 { 165 clip_natural_int8_t_from_mono, 166 clip_natural_int16_t_from_mono 167 }, 168 { 169 clip_natural_int8_t_from_mono, 170 clip_swap_int16_t_from_mono 171 } 172 } 173 }, 174 { 175 { 176 { 177 clip_natural_uint8_t_from_stereo, 178 clip_natural_uint16_t_from_stereo 179 }, 180 { 181 clip_natural_uint8_t_from_stereo, 182 clip_swap_uint16_t_from_stereo 183 } 184 }, 185 { 186 { 187 clip_natural_int8_t_from_stereo, 188 clip_natural_int16_t_from_stereo 189 }, 190 { 191 clip_natural_int8_t_from_stereo, 192 clip_swap_int16_t_from_stereo 193 } 194 } 195 } 196 }; 197 198 /* 199 * August 21, 1998 200 * Copyright 1998 Fabrice Bellard. 201 * 202 * [Rewrote completly the code of Lance Norskog And Sundry 203 * Contributors with a more efficient algorithm.] 204 * 205 * This source code is freely redistributable and may be used for 206 * any purpose. This copyright notice must be maintained. 207 * Lance Norskog And Sundry Contributors are not responsible for 208 * the consequences of using this software. 209 */ 210 211 /* 212 * Sound Tools rate change effect file. 213 */ 214 /* 215 * Linear Interpolation. 216 * 217 * The use of fractional increment allows us to use no buffer. It 218 * avoid the problems at the end of the buffer we had with the old 219 * method which stored a possibly big buffer of size 220 * lcm(in_rate,out_rate). 221 * 222 * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If 223 * the input & output frequencies are equal, a delay of one sample is 224 * introduced. Limited to processing 32-bit count worth of samples. 225 * 226 * 1 << FRAC_BITS evaluating to zero in several places. Changed with 227 * an (unsigned long) cast to make it safe. MarkMLl 2/1/99 228 */ 229 230 /* Private data */ 231 typedef struct ratestuff { 232 uint64_t opos; 233 uint64_t opos_inc; 234 uint32_t ipos; /* position in the input stream (integer) */ 235 st_sample_t ilast; /* last sample in the input stream */ 236 } *rate_t; 237 238 /* 239 * Prepare processing. 240 */ 241 void *st_rate_start (int inrate, int outrate) 242 { 243 rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff)); 244 245 if (!rate) { 246 return NULL; 247 } 248 249 rate->opos = 0; 250 251 /* increment */ 252 rate->opos_inc = ((uint64_t) inrate << 32) / outrate; 253 254 rate->ipos = 0; 255 rate->ilast.l = 0; 256 rate->ilast.r = 0; 257 return rate; 258 } 259 260 #define NAME st_rate_flow_mix 261 #define OP(a, b) a += b 262 #include "rate_template.h" 263 264 #define NAME st_rate_flow 265 #define OP(a, b) a = b 266 #include "rate_template.h" 267 268 void st_rate_stop (void *opaque) 269 { 270 qemu_free (opaque); 271 } 272 273 void mixeng_clear (st_sample_t *buf, int len) 274 { 275 memset (buf, 0, len * sizeof (st_sample_t)); 276 } 277