symbian-qemu-0.9.1-12/qemu-symbian-svp/audio/mixeng_template.h
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 CONFIG_MIXEMU
       
    35 #ifdef FLOAT_MIXENG
       
    36 #define VOL(a, b) ((a) * (b))
       
    37 #else
       
    38 #define VOL(a, b) ((a) * (b)) >> 32
       
    39 #endif
       
    40 #else
       
    41 #define VOL(a, b) a
       
    42 #endif
       
    43 
       
    44 #define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
       
    45 
       
    46 #ifdef FLOAT_MIXENG
       
    47 static mixeng_real 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 / (mixeng_real) (IN_MAX - IN_MIN));
       
    54 #else
       
    55     return (nv - HALF) * (1.f / (mixeng_real) IN_MAX);
       
    56 #endif
       
    57 #else  /* !RECIPROCAL */
       
    58 #ifdef SIGNED
       
    59     return nv / (mixeng_real) (IN_MAX - IN_MIN);
       
    60 #else
       
    61     return (nv - HALF) / (mixeng_real) IN_MAX;
       
    62 #endif
       
    63 #endif
       
    64 }
       
    65 
       
    66 static IN_T inline glue (clip_, ET) (mixeng_real 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     (struct st_sample *dst, const void *src, int samples, struct mixeng_volume *vol)
       
   113 {
       
   114     struct st_sample *out = dst;
       
   115     IN_T *in = (IN_T *) src;
       
   116 #ifdef CONFIG_MIXEMU
       
   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     (struct st_sample *dst, const void *src, int samples, struct mixeng_volume *vol)
       
   133 {
       
   134     struct st_sample *out = dst;
       
   135     IN_T *in = (IN_T *) src;
       
   136 #ifdef CONFIG_MIXEMU
       
   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 struct st_sample *src, int samples)
       
   154 {
       
   155     const struct st_sample *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 struct st_sample *src, int samples)
       
   166 {
       
   167     const struct st_sample *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