Revision 1d14ffa9 audio/mixeng_template.h

b/audio/mixeng_template.h
1 1
/*
2 2
 * QEMU Mixing engine
3
 * 
4
 * Copyright (c) 2004 Vassili Karpov (malc)
5
 * 
3
 *
4
 * Copyright (c) 2004-2005 Vassili Karpov (malc)
5
 *
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
8 8
 * in the Software without restriction, including without limitation the rights
......
27 27
 * dec++'ified by Dscho
28 28
 */
29 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 */
30 58
#ifdef SIGNED
31
#define HALFT IN_MAX
32
#define HALF IN_MAX
59
    return nv / (real_t) (IN_MAX - IN_MIN);
33 60
#else
34
#define HALFT ((IN_MAX)>>1)
35
#define HALF HALFT
61
    return (nv - HALF) / (real_t) IN_MAX;
36 62
#endif
63
#endif
64
}
37 65

  
38
static int64_t inline glue(conv_,IN_T) (IN_T v)
66
static IN_T inline glue (clip_, ET) (real_t v)
39 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);
40 87
#ifdef SIGNED
41
    return (INT_MAX*(int64_t)v)/HALF;
88
    return ((int64_t) nv) << (32 - SHIFT);
42 89
#else
43
    return (INT_MAX*((int64_t)v-HALFT))/HALF;
90
    return ((int64_t) nv - HALF) << (32 - SHIFT);
44 91
#endif
45 92
}
46 93

  
47
static IN_T inline glue(clip_,IN_T) (int64_t v)
94
static inline IN_T glue (clip_, ET) (int64_t v)
48 95
{
49
    if (v >= INT_MAX)
96
    if (v >= 0x7f000000) {
50 97
        return IN_MAX;
51
    else if (v < -INT_MAX)
98
    }
99
    else if (v < -2147483648LL) {
52 100
        return IN_MIN;
101
    }
53 102

  
54 103
#ifdef SIGNED
55
    return (IN_T) (v*HALF/INT_MAX);
104
    return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
56 105
#else
57
    return (IN_T) (v+INT_MAX/2)*HALF/INT_MAX;
106
    return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
58 107
#endif
59 108
}
109
#endif
60 110

  
61
static void glue(glue(conv_,IN_T),_to_stereo) (void *dst, const void *src,
62
                                               int samples)
111
static void glue (glue (conv_, ET), _to_stereo)
112
    (st_sample_t *dst, const void *src, int samples, volume_t *vol)
63 113
{
64
    st_sample_t *out = (st_sample_t *) dst;
114
    st_sample_t *out = dst;
65 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
66 124
    while (samples--) {
67
        out->l = glue(conv_,IN_T) (*in++);
68
        out->r = glue(conv_,IN_T) (*in++);
125
        out->l = VOL (glue (conv_, ET) (*in++), vol->l);
126
        out->r = VOL (glue (conv_, ET) (*in++), vol->r);
69 127
        out += 1;
70 128
    }
71 129
}
72 130

  
73
static void glue(glue(conv_,IN_T),_to_mono) (void *dst, const void *src,
74
                                             int samples)
131
static void glue (glue (conv_, ET), _to_mono)
132
    (st_sample_t *dst, const void *src, int samples, volume_t *vol)
75 133
{
76
    st_sample_t *out = (st_sample_t *) dst;
134
    st_sample_t *out = dst;
77 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
78 144
    while (samples--) {
79
        out->l = glue(conv_,IN_T) (in[0]);
145
        out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
80 146
        out->r = out->l;
81 147
        out += 1;
82 148
        in += 1;
83 149
    }
84 150
}
85 151

  
86
static void glue(glue(clip_,IN_T),_from_stereo) (void *dst, const void *src,
87
                                                 int samples)
152
static void glue (glue (clip_, ET), _from_stereo)
153
    (void *dst, const st_sample_t *src, int samples)
88 154
{
89
    st_sample_t *in = (st_sample_t *) src;
155
    const st_sample_t *in = src;
90 156
    IN_T *out = (IN_T *) dst;
91 157
    while (samples--) {
92
        *out++ = glue(clip_,IN_T) (in->l);
93
        *out++ = glue(clip_,IN_T) (in->r);
158
        *out++ = glue (clip_, ET) (in->l);
159
        *out++ = glue (clip_, ET) (in->r);
94 160
        in += 1;
95 161
    }
96 162
}
97 163

  
98
static void glue(glue(clip_,IN_T),_from_mono) (void *dst, const void *src,
99
                                               int samples)
164
static void glue (glue (clip_, ET), _from_mono)
165
    (void *dst, const st_sample_t *src, int samples)
100 166
{
101
    st_sample_t *in = (st_sample_t *) src;
167
    const st_sample_t *in = src;
102 168
    IN_T *out = (IN_T *) dst;
103 169
    while (samples--) {
104
        *out++ = glue(clip_,IN_T) (in->l + in->r);
170
        *out++ = glue (clip_, ET) (in->l + in->r);
105 171
        in += 1;
106 172
    }
107 173
}
108 174

  
175
#undef ET
109 176
#undef HALF
110
#undef HALFT
111

  
177
#undef VOL

Also available in: Unified diff