qemu/audio/mixeng_template.h
<<
>>
Prefs
   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#define ET glue (ENDIAN_CONVERSION, glue (glue (glue (_, ITYPE), BSIZE), _t))
  35#define IN_T glue (glue (ITYPE, BSIZE), _t)
  36
  37#ifdef FLOAT_MIXENG
  38static inline mixeng_real glue (conv_, ET) (IN_T v)
  39{
  40    IN_T nv = ENDIAN_CONVERT (v);
  41
  42#ifdef RECIPROCAL
  43#ifdef SIGNED
  44    return nv * (2.f / ((mixeng_real)IN_MAX - IN_MIN));
  45#else
  46    return (nv - HALF) * (2.f / (mixeng_real)IN_MAX);
  47#endif
  48#else  /* !RECIPROCAL */
  49#ifdef SIGNED
  50    return nv / (((mixeng_real)IN_MAX - IN_MIN) / 2.f);
  51#else
  52    return (nv - HALF) / ((mixeng_real)IN_MAX / 2.f);
  53#endif
  54#endif
  55}
  56
  57static inline IN_T glue (clip_, ET) (mixeng_real v)
  58{
  59    if (v >= 1.f) {
  60        return IN_MAX;
  61    } else if (v < -1.f) {
  62        return IN_MIN;
  63    }
  64
  65#ifdef SIGNED
  66    return ENDIAN_CONVERT((IN_T)(v * (((mixeng_real)IN_MAX - IN_MIN) / 2.f)));
  67#else
  68    return ENDIAN_CONVERT((IN_T)((v * ((mixeng_real)IN_MAX / 2.f)) + HALF));
  69#endif
  70}
  71
  72#else  /* !FLOAT_MIXENG */
  73
  74static inline int64_t glue (conv_, ET) (IN_T v)
  75{
  76    IN_T nv = ENDIAN_CONVERT (v);
  77#ifdef SIGNED
  78    return ((int64_t) nv) << (32 - SHIFT);
  79#else
  80    return ((int64_t) nv - HALF) << (32 - SHIFT);
  81#endif
  82}
  83
  84static inline IN_T glue (clip_, ET) (int64_t v)
  85{
  86    if (v >= 0x7fffffffLL) {
  87        return IN_MAX;
  88    } else if (v < -2147483648LL) {
  89        return IN_MIN;
  90    }
  91
  92#ifdef SIGNED
  93    return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
  94#else
  95    return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
  96#endif
  97}
  98#endif
  99
 100static void glue (glue (conv_, ET), _to_stereo)
 101    (struct st_sample *dst, const void *src, int samples)
 102{
 103    struct st_sample *out = dst;
 104    IN_T *in = (IN_T *) src;
 105
 106    while (samples--) {
 107        out->l = glue (conv_, ET) (*in++);
 108        out->r = glue (conv_, ET) (*in++);
 109        out += 1;
 110    }
 111}
 112
 113static void glue (glue (conv_, ET), _to_mono)
 114    (struct st_sample *dst, const void *src, int samples)
 115{
 116    struct st_sample *out = dst;
 117    IN_T *in = (IN_T *) src;
 118
 119    while (samples--) {
 120        out->l = glue (conv_, ET) (in[0]);
 121        out->r = out->l;
 122        out += 1;
 123        in += 1;
 124    }
 125}
 126
 127static void glue (glue (clip_, ET), _from_stereo)
 128    (void *dst, const struct st_sample *src, int samples)
 129{
 130    const struct st_sample *in = src;
 131    IN_T *out = (IN_T *) dst;
 132    while (samples--) {
 133        *out++ = glue (clip_, ET) (in->l);
 134        *out++ = glue (clip_, ET) (in->r);
 135        in += 1;
 136    }
 137}
 138
 139static void glue (glue (clip_, ET), _from_mono)
 140    (void *dst, const struct st_sample *src, int samples)
 141{
 142    const struct st_sample *in = src;
 143    IN_T *out = (IN_T *) dst;
 144    while (samples--) {
 145        *out++ = glue (clip_, ET) (in->l + in->r);
 146        in += 1;
 147    }
 148}
 149
 150#undef ET
 151#undef HALF
 152#undef IN_T
 153