18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU Mixing engine 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2004-2005 Vassili Karpov (malc) 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1998 Fabrice Bellard 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions: 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software. 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE. 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Processed signed long samples from ibuf to obuf. 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Return number of samples processed. 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *isamp, int *osamp) 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct rate *rate = opaque; 345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct st_sample *istart, *iend; 355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct st_sample *ostart, *oend; 365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct st_sample ilast, icur, out; 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT_MIXENG 385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner mixeng_real t; 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int64_t t; 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ilast = rate->ilast; 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project istart = ibuf; 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project iend = ibuf + *isamp; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ostart = obuf; 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project oend = obuf + *osamp; 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (rate->opos_inc == (1ULL + UINT_MAX)) { 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i, n = *isamp > *osamp ? *osamp : *isamp; 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < n; i++) { 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OP (obuf[i].l, ibuf[i].l); 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OP (obuf[i].r, ibuf[i].r); 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *isamp = n; 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *osamp = n; 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (obuf < oend) { 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Safety catch to make sure we have input samples. */ 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ibuf >= iend) { 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* read as many input samples so that ipos > opos */ 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (rate->ipos <= (rate->opos >> 32)) { 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ilast = *ibuf++; 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rate->ipos++; 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* See if we finished the input buffer yet */ 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ibuf >= iend) { 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto the_end; 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project icur = *ibuf; 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* interpolate */ 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT_MIXENG 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef RECIPROCAL 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project t = (rate->opos & UINT_MAX) * (1.f / UINT_MAX); 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t = (rate->opos & UINT_MAX) / (mixeng_real) UINT_MAX; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project out.l = (ilast.l * (1.0 - t)) + icur.l * t; 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project out.r = (ilast.r * (1.0 - t)) + icur.r * t; 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project t = rate->opos & 0xffffffff; 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project out.l = (ilast.l * ((int64_t) UINT_MAX - t) + icur.l * t) >> 32; 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project out.r = (ilast.r * ((int64_t) UINT_MAX - t) + icur.r * t) >> 32; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* output sample & increment position */ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OP (obuf->l, out.l); 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project OP (obuf->r, out.r); 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project obuf += 1; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rate->opos += rate->opos_inc; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectthe_end: 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *isamp = ibuf - istart; 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *osamp = obuf - ostart; 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project rate->ilast = ilast; 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef NAME 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef OP 112