Statistics
| Branch: | Revision:

root / audio / mixeng_template.h @ 6327c221

History | View | Annotate | Download (3.9 kB)

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
38
static mixeng_real inline glue (conv_, ET) (IN_T v)
39
{
40
    IN_T nv = ENDIAN_CONVERT (v);
41

    
42
#ifdef RECIPROCAL
43
#ifdef SIGNED
44
    return nv * (1.f / (mixeng_real) (IN_MAX - IN_MIN));
45
#else
46
    return (nv - HALF) * (1.f / (mixeng_real) IN_MAX);
47
#endif
48
#else  /* !RECIPROCAL */
49
#ifdef SIGNED
50
    return nv / (mixeng_real) ((mixeng_real) IN_MAX - IN_MIN);
51
#else
52
    return (nv - HALF) / (mixeng_real) IN_MAX;
53
#endif
54
#endif
55
}
56

    
57
static IN_T inline glue (clip_, ET) (mixeng_real v)
58
{
59
    if (v >= 0.5) {
60
        return IN_MAX;
61
    }
62
    else if (v < -0.5) {
63
        return IN_MIN;
64
    }
65

    
66
#ifdef SIGNED
67
    return ENDIAN_CONVERT ((IN_T) (v * ((mixeng_real) IN_MAX - IN_MIN)));
68
#else
69
    return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
70
#endif
71
}
72

    
73
#else  /* !FLOAT_MIXENG */
74

    
75
static inline int64_t glue (conv_, ET) (IN_T v)
76
{
77
    IN_T nv = ENDIAN_CONVERT (v);
78
#ifdef SIGNED
79
    return ((int64_t) nv) << (32 - SHIFT);
80
#else
81
    return ((int64_t) nv - HALF) << (32 - SHIFT);
82
#endif
83
}
84

    
85
static inline IN_T glue (clip_, ET) (int64_t v)
86
{
87
    if (v >= 0x7f000000) {
88
        return IN_MAX;
89
    }
90
    else if (v < -2147483648LL) {
91
        return IN_MIN;
92
    }
93

    
94
#ifdef SIGNED
95
    return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
96
#else
97
    return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
98
#endif
99
}
100
#endif
101

    
102
static void glue (glue (conv_, ET), _to_stereo)
103
    (struct st_sample *dst, const void *src, int samples)
104
{
105
    struct st_sample *out = dst;
106
    IN_T *in = (IN_T *) src;
107

    
108
    while (samples--) {
109
        out->l = glue (conv_, ET) (*in++);
110
        out->r = glue (conv_, ET) (*in++);
111
        out += 1;
112
    }
113
}
114

    
115
static void glue (glue (conv_, ET), _to_mono)
116
    (struct st_sample *dst, const void *src, int samples)
117
{
118
    struct st_sample *out = dst;
119
    IN_T *in = (IN_T *) src;
120

    
121
    while (samples--) {
122
        out->l = glue (conv_, ET) (in[0]);
123
        out->r = out->l;
124
        out += 1;
125
        in += 1;
126
    }
127
}
128

    
129
static void glue (glue (clip_, ET), _from_stereo)
130
    (void *dst, const struct st_sample *src, int samples)
131
{
132
    const struct st_sample *in = src;
133
    IN_T *out = (IN_T *) dst;
134
    while (samples--) {
135
        *out++ = glue (clip_, ET) (in->l);
136
        *out++ = glue (clip_, ET) (in->r);
137
        in += 1;
138
    }
139
}
140

    
141
static void glue (glue (clip_, ET), _from_mono)
142
    (void *dst, const struct st_sample *src, int samples)
143
{
144
    const struct st_sample *in = src;
145
    IN_T *out = (IN_T *) dst;
146
    while (samples--) {
147
        *out++ = glue (clip_, ET) (in->l + in->r);
148
        in += 1;
149
    }
150
}
151

    
152
#undef ET
153
#undef HALF
154
#undef IN_T