|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.