Home | History | Annotate | Download | only in audio
      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 
     26 /*
     27  * Processed signed long samples from ibuf to obuf.
     28  * Return number of samples processed.
     29  */
     30 void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf,
     31            int *isamp, int *osamp)
     32 {
     33     struct rate *rate = opaque;
     34     struct st_sample *istart, *iend;
     35     struct st_sample *ostart, *oend;
     36     struct st_sample ilast, icur, out;
     37 #ifdef FLOAT_MIXENG
     38     mixeng_real t;
     39 #else
     40     int64_t t;
     41 #endif
     42 
     43     ilast = rate->ilast;
     44 
     45     istart = ibuf;
     46     iend = ibuf + *isamp;
     47 
     48     ostart = obuf;
     49     oend = obuf + *osamp;
     50 
     51     if (rate->opos_inc == (1ULL + UINT_MAX)) {
     52         int i, n = *isamp > *osamp ? *osamp : *isamp;
     53         for (i = 0; i < n; i++) {
     54             OP (obuf[i].l, ibuf[i].l);
     55             OP (obuf[i].r, ibuf[i].r);
     56         }
     57         *isamp = n;
     58         *osamp = n;
     59         return;
     60     }
     61 
     62     while (obuf < oend) {
     63 
     64         /* Safety catch to make sure we have input samples.  */
     65         if (ibuf >= iend) {
     66             break;
     67         }
     68 
     69         /* read as many input samples so that ipos > opos */
     70 
     71         while (rate->ipos <= (rate->opos >> 32)) {
     72             ilast = *ibuf++;
     73             rate->ipos++;
     74             /* See if we finished the input buffer yet */
     75             if (ibuf >= iend) {
     76                 goto the_end;
     77             }
     78         }
     79 
     80         icur = *ibuf;
     81 
     82         /* interpolate */
     83 #ifdef FLOAT_MIXENG
     84 #ifdef RECIPROCAL
     85         t = (rate->opos & UINT_MAX) * (1.f / UINT_MAX);
     86 #else
     87         t = (rate->opos & UINT_MAX) / (mixeng_real) UINT_MAX;
     88 #endif
     89         out.l = (ilast.l * (1.0 - t)) + icur.l * t;
     90         out.r = (ilast.r * (1.0 - t)) + icur.r * t;
     91 #else
     92         t = rate->opos & 0xffffffff;
     93         out.l = (ilast.l * ((int64_t) UINT_MAX - t) + icur.l * t) >> 32;
     94         out.r = (ilast.r * ((int64_t) UINT_MAX - t) + icur.r * t) >> 32;
     95 #endif
     96 
     97         /* output sample & increment position */
     98         OP (obuf->l, out.l);
     99         OP (obuf->r, out.r);
    100         obuf += 1;
    101         rate->opos += rate->opos_inc;
    102     }
    103 
    104 the_end:
    105     *isamp = ibuf - istart;
    106     *osamp = obuf - ostart;
    107     rate->ilast = ilast;
    108 }
    109 
    110 #undef NAME
    111 #undef OP
    112