Annotation of qemu/audio/mixeng.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.