Statistics
| Branch: | Revision:

root / audio / mixeng_template.h @ 1ea879e5

History | View | Annotate | Download (4.3 kB)

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