1 /* 2 * QEMU Mixing engine 3 * 4 * Copyright (c) 2004 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 //#define DEBUG_FP 27 #include "audio/mixeng.h" 28 29 #define IN_T int8_t 30 #define IN_MIN CHAR_MIN 31 #define IN_MAX CHAR_MAX 32 #define SIGNED 33 #include "mixeng_template.h" 34 #undef SIGNED 35 #undef IN_MAX 36 #undef IN_MIN 37 #undef IN_T 38 39 #define IN_T uint8_t 40 #define IN_MIN 0 41 #define IN_MAX UCHAR_MAX 42 #include "mixeng_template.h" 43 #undef IN_MAX 44 #undef IN_MIN 45 #undef IN_T 46 47 #define IN_T int16_t 48 #define IN_MIN SHRT_MIN 49 #define IN_MAX SHRT_MAX 50 #define SIGNED 51 #include "mixeng_template.h" 52 #undef SIGNED 53 #undef IN_MAX 54 #undef IN_MIN 55 #undef IN_T 56 57 #define IN_T uint16_t 58 #define IN_MIN 0 59 #define IN_MAX USHRT_MAX 60 #include "mixeng_template.h" 61 #undef IN_MAX 62 #undef IN_MIN 63 #undef IN_T 64 65 t_sample *mixeng_conv[2][2][2] = { 66 { 67 { 68 conv_uint8_t_to_mono, 69 conv_uint16_t_to_mono 70 }, 71 { 72 conv_int8_t_to_mono, 73 conv_int16_t_to_mono 74 } 75 }, 76 { 77 { 78 conv_uint8_t_to_stereo, 79 conv_uint16_t_to_stereo 80 }, 81 { 82 conv_int8_t_to_stereo, 83 conv_int16_t_to_stereo 84 } 85 } 86 }; 87 88 f_sample *mixeng_clip[2][2][2] = { 89 { 90 { 91 clip_uint8_t_from_mono, 92 clip_uint16_t_from_mono 93 }, 94 { 95 clip_int8_t_from_mono, 96 clip_int16_t_from_mono 97 } 98 }, 99 { 100 { 101 clip_uint8_t_from_stereo, 102 clip_uint16_t_from_stereo 103 }, 104 { 105 clip_int8_t_from_stereo, 106 clip_int16_t_from_stereo 107 } 108 } 109 }; 110 111 /* 112 * August 21, 1998 113 * Copyright 1998 Fabrice Bellard. 114 * 115 * [Rewrote completly the code of Lance Norskog And Sundry 116 * Contributors with a more efficient algorithm.] 117 * 118 * This source code is freely redistributable and may be used for 119 * any purpose. This copyright notice must be maintained. 120 * Lance Norskog And Sundry Contributors are not responsible for 121 * the consequences of using this software. 122 */ 123 124 /* 125 * Sound Tools rate change effect file. 126 */ 127 /* 128 * Linear Interpolation. 129 * 130 * The use of fractional increment allows us to use no buffer. It 131 * avoid the problems at the end of the buffer we had with the old 132 * method which stored a possibly big buffer of size 133 * lcm(in_rate,out_rate). 134 * 135 * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If 136 * the input & output frequencies are equal, a delay of one sample is 137 * introduced. Limited to processing 32-bit count worth of samples. 138 * 139 * 1 << FRAC_BITS evaluating to zero in several places. Changed with 140 * an (unsigned long) cast to make it safe. MarkMLl 2/1/99 141 */ 142 143 /* Private data */ 144 typedef struct ratestuff { 145 uint64_t opos; 146 uint64_t opos_inc; 147 uint32_t ipos; /* position in the input stream (integer) */ 148 st_sample_t ilast; /* last sample in the input stream */ 149 } *rate_t; 150 151 /* 152 * Prepare processing. 153 */ 154 void *st_rate_start (int inrate, int outrate) 155 { 156 rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff)); 157 158 if (!rate) { 159 exit (EXIT_FAILURE); 160 } 161 162 if (inrate == outrate) { 163 // exit (EXIT_FAILURE); 164 } 165 166 if (inrate >= 65535 || outrate >= 65535) { 167 // exit (EXIT_FAILURE); 168 } 169 170 rate->opos = 0; 171 172 /* increment */ 173 rate->opos_inc = (inrate * ((int64_t) UINT_MAX)) / outrate; 174 175 rate->ipos = 0; 176 rate->ilast.l = 0; 177 rate->ilast.r = 0; 178 return rate; 179 } 180 181 /* 182 * Processed signed long samples from ibuf to obuf. 183 * Return number of samples processed. 184 */ 185 void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf, 186 int *isamp, int *osamp) 187 { 188 rate_t rate = (rate_t) opaque; 189 st_sample_t *istart, *iend; 190 st_sample_t *ostart, *oend; 191 st_sample_t ilast, icur, out; 192 int64_t t; 193 194 ilast = rate->ilast; 195 196 istart = ibuf; 197 iend = ibuf + *isamp; 198 199 ostart = obuf; 200 oend = obuf + *osamp; 201 202 if (rate->opos_inc == 1ULL << 32) { 203 int i, n = *isamp > *osamp ? *osamp : *isamp; 204 for (i = 0; i < n; i++) { 205 obuf[i].l += ibuf[i].r; 206 obuf[i].r += ibuf[i].r; 207 } 208 *isamp = n; 209 *osamp = n; 210 return; 211 } 212 213 while (obuf < oend) { 214 215 /* Safety catch to make sure we have input samples. */ 216 if (ibuf >= iend) 217 break; 218 219 /* read as many input samples so that ipos > opos */ 220 221 while (rate->ipos <= (rate->opos >> 32)) { 222 ilast = *ibuf++; 223 rate->ipos++; 224 /* See if we finished the input buffer yet */ 225 if (ibuf >= iend) goto the_end; 226 } 227 228 icur = *ibuf; 229 230 /* interpolate */ 231 t = rate->opos & 0xffffffff; 232 out.l = (ilast.l * (INT_MAX - t) + icur.l * t) / INT_MAX; 233 out.r = (ilast.r * (INT_MAX - t) + icur.r * t) / INT_MAX; 234 235 /* output sample & increment position */ 236 #if 0 237 *obuf++ = out; 238 #else 239 obuf->l += out.l; 240 obuf->r += out.r; 241 obuf += 1; 242 #endif 243 rate->opos += rate->opos_inc; 244 } 245 246 the_end: 247 *isamp = ibuf - istart; 248 *osamp = obuf - ostart; 249 rate->ilast = ilast; 250 } 251 252 void st_rate_stop (void *opaque) 253 { 254 qemu_free (opaque); 255 } 256