(linenum→info "unix/slp.c:2238")

qemu/0.9.1/audio/mixeng_template.h

    1: /*
    2:  * QEMU Mixing engine
    3:  *
    4:  * Copyright (c) 2004-2005 Vassili Karpov (malc)
    5:  *
    6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
    7:  * of this software and associated documentation files (the "Software"), to deal
    8:  * in the Software without restriction, including without limitation the rights
    9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   10:  * copies of the Software, and to permit persons to whom the Software is
   11:  * furnished to do so, subject to the following conditions:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included in
   14:  * all copies or substantial portions of the Software.
   15:  *
   16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22:  * THE SOFTWARE.
   23:  */
   24: 
   25: /*
   26:  * Tusen tack till Mike Nordell
   27:  * dec++'ified by Dscho
   28:  */
   29: 
   30: #ifndef SIGNED
   31: #define HALF (IN_MAX >> 1)
   32: #endif
   33: 
   34: #ifdef NOVOL
   35: #define VOL(a, b) a
   36: #else
   37: #ifdef FLOAT_MIXENG
   38: #define VOL(a, b) ((a) * (b))
   39: #else
   40: #define VOL(a, b) ((a) * (b)) >> 32
   41: #endif
   42: #endif
   43: 
   44: #define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
   45: 
   46: #ifdef FLOAT_MIXENG
   47: static real_t inline glue (conv_, ET) (IN_T v)
   48: {
   49:     IN_T nv = ENDIAN_CONVERT (v);
   50: 
   51: #ifdef RECIPROCAL
   52: #ifdef SIGNED
   53:     return nv * (1.f / (real_t) (IN_MAX - IN_MIN));
   54: #else
   55:     return (nv - HALF) * (1.f / (real_t) IN_MAX);
   56: #endif
   57: #else  /* !RECIPROCAL */
   58: #ifdef SIGNED
   59:     return nv / (real_t) (IN_MAX - IN_MIN);
   60: #else
   61:     return (nv - HALF) / (real_t) IN_MAX;
   62: #endif
   63: #endif
   64: }
   65: 
   66: static IN_T inline glue (clip_, ET) (real_t v)
   67: {
   68:     if (v >= 0.5) {
   69:         return IN_MAX;
   70:     }
   71:     else if (v < -0.5) {
   72:         return IN_MIN;
   73:     }
   74: 
   75: #ifdef SIGNED
   76:     return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
   77: #else
   78:     return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
   79: #endif
   80: }
   81: 
   82: #else  /* !FLOAT_MIXENG */
   83: 
   84: static inline int64_t glue (conv_, ET) (IN_T v)
   85: {
   86:     IN_T nv = ENDIAN_CONVERT (v);
   87: #ifdef SIGNED
   88:     return ((int64_t) nv) << (32 - SHIFT);
   89: #else
   90:     return ((int64_t) nv - HALF) << (32 - SHIFT);
   91: #endif
   92: }
   93: 
   94: static inline IN_T glue (clip_, ET) (int64_t v)
   95: {
   96:     if (v >= 0x7f000000) {
   97:         return IN_MAX;
   98:     }
   99:     else if (v < -2147483648LL) {
  100:         return IN_MIN;
  101:     }
  102: 
  103: #ifdef SIGNED
  104:     return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
  105: #else
  106:     return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
  107: #endif
  108: }
  109: #endif
  110: 
  111: static void glue (glue (conv_, ET), _to_stereo)
  112:     (st_sample_t *dst, const void *src, int samples, volume_t *vol)
  113: {
  114:     st_sample_t *out = dst;
  115:     IN_T *in = (IN_T *) src;
  116: #ifndef NOVOL
  117:     if (vol->mute) {
  118:         mixeng_clear (dst, samples);
  119:         return;
  120:     }
  121: #else
  122:     (void) vol;
  123: #endif
  124:     while (samples--) {
  125:         out->l = VOL (glue (conv_, ET) (*in++), vol->l);
  126:         out->r = VOL (glue (conv_, ET) (*in++), vol->r);
  127:         out += 1;
  128:     }
  129: }
  130: 
  131: static void glue (glue (conv_, ET), _to_mono)
  132:     (st_sample_t *dst, const void *src, int samples, volume_t *vol)
  133: {
  134:     st_sample_t *out = dst;
  135:     IN_T *in = (IN_T *) src;
  136: #ifndef NOVOL
  137:     if (vol->mute) {
  138:         mixeng_clear (dst, samples);
  139:         return;
  140:     }
  141: #else
  142:     (void) vol;
  143: #endif
  144:     while (samples--) {
  145:         out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
  146:         out->r = out->l;
  147:         out += 1;
  148:         in += 1;
  149:     }
  150: }
  151: 
  152: static void glue (glue (clip_, ET), _from_stereo)
  153:     (void *dst, const st_sample_t *src, int samples)
  154: {
  155:     const st_sample_t *in = src;
  156:     IN_T *out = (IN_T *) dst;
  157:     while (samples--) {
  158:         *out++ = glue (clip_, ET) (in->l);
  159:         *out++ = glue (clip_, ET) (in->r);
  160:         in += 1;
  161:     }
  162: }
  163: 
  164: static void glue (glue (clip_, ET), _from_mono)
  165:     (void *dst, const st_sample_t *src, int samples)
  166: {
  167:     const st_sample_t *in = src;
  168:     IN_T *out = (IN_T *) dst;
  169:     while (samples--) {
  170:         *out++ = glue (clip_, ET) (in->l + in->r);
  171:         in += 1;
  172:     }
  173: }
  174: 
  175: #undef ET
  176: #undef HALF
  177: #undef VOL
Syntax (Markdown)