Revision 1d14ffa9 audio/mixeng.c

b/audio/mixeng.c
1 1
/*
2 2
 * QEMU Mixing engine
3 3
 *
4
 * Copyright (c) 2004 Vassili Karpov (malc)
4
 * Copyright (c) 2004-2005 Vassili Karpov (malc)
5 5
 * Copyright (c) 1998 Fabrice Bellard
6 6
 *
7 7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
......
23 23
 * THE SOFTWARE.
24 24
 */
25 25
#include "vl.h"
26
//#define DEBUG_FP
27
#include "audio/mixeng.h"
28 26

  
27
#define AUDIO_CAP "mixeng"
28
#include "audio_int.h"
29

  
30
#define NOVOL
31

  
32
/* 8 bit */
33
#define ENDIAN_CONVERSION natural
34
#define ENDIAN_CONVERT(v) (v)
35

  
36
/* Signed 8 bit */
29 37
#define IN_T int8_t
30
#define IN_MIN CHAR_MIN
31
#define IN_MAX CHAR_MAX
38
#define IN_MIN SCHAR_MIN
39
#define IN_MAX SCHAR_MAX
32 40
#define SIGNED
41
#define SHIFT 8
33 42
#include "mixeng_template.h"
34 43
#undef SIGNED
35 44
#undef IN_MAX
36 45
#undef IN_MIN
37 46
#undef IN_T
47
#undef SHIFT
38 48

  
49
/* Unsigned 8 bit */
39 50
#define IN_T uint8_t
40 51
#define IN_MIN 0
41 52
#define IN_MAX UCHAR_MAX
53
#define SHIFT 8
42 54
#include "mixeng_template.h"
43 55
#undef IN_MAX
44 56
#undef IN_MIN
45 57
#undef IN_T
58
#undef SHIFT
59

  
60
#undef ENDIAN_CONVERT
61
#undef ENDIAN_CONVERSION
46 62

  
63
/* Signed 16 bit */
47 64
#define IN_T int16_t
48 65
#define IN_MIN SHRT_MIN
49 66
#define IN_MAX SHRT_MAX
50 67
#define SIGNED
68
#define SHIFT 16
69
#define ENDIAN_CONVERSION natural
70
#define ENDIAN_CONVERT(v) (v)
51 71
#include "mixeng_template.h"
72
#undef ENDIAN_CONVERT
73
#undef ENDIAN_CONVERSION
74
#define ENDIAN_CONVERSION swap
75
#define ENDIAN_CONVERT(v) bswap16 (v)
76
#include "mixeng_template.h"
77
#undef ENDIAN_CONVERT
78
#undef ENDIAN_CONVERSION
52 79
#undef SIGNED
53 80
#undef IN_MAX
54 81
#undef IN_MIN
55 82
#undef IN_T
83
#undef SHIFT
56 84

  
57 85
#define IN_T uint16_t
58 86
#define IN_MIN 0
59 87
#define IN_MAX USHRT_MAX
88
#define SHIFT 16
89
#define ENDIAN_CONVERSION natural
90
#define ENDIAN_CONVERT(v) (v)
91
#include "mixeng_template.h"
92
#undef ENDIAN_CONVERT
93
#undef ENDIAN_CONVERSION
94
#define ENDIAN_CONVERSION swap
95
#define ENDIAN_CONVERT(v) bswap16 (v)
60 96
#include "mixeng_template.h"
97
#undef ENDIAN_CONVERT
98
#undef ENDIAN_CONVERSION
61 99
#undef IN_MAX
62 100
#undef IN_MIN
63 101
#undef IN_T
102
#undef SHIFT
64 103

  
65
t_sample *mixeng_conv[2][2][2] = {
104
t_sample *mixeng_conv[2][2][2][2] = {
66 105
    {
67 106
        {
68
            conv_uint8_t_to_mono,
69
            conv_uint16_t_to_mono
107
            {
108
                conv_natural_uint8_t_to_mono,
109
                conv_natural_uint16_t_to_mono
110
            },
111
            {
112
                conv_natural_uint8_t_to_mono,
113
                conv_swap_uint16_t_to_mono
114
            }
70 115
        },
71 116
        {
72
            conv_int8_t_to_mono,
73
            conv_int16_t_to_mono
117
            {
118
                conv_natural_int8_t_to_mono,
119
                conv_natural_int16_t_to_mono
120
            },
121
            {
122
                conv_natural_int8_t_to_mono,
123
                conv_swap_int16_t_to_mono
124
            }
74 125
        }
75 126
    },
76 127
    {
77 128
        {
78
            conv_uint8_t_to_stereo,
79
            conv_uint16_t_to_stereo
129
            {
130
                conv_natural_uint8_t_to_stereo,
131
                conv_natural_uint16_t_to_stereo
132
            },
133
            {
134
                conv_natural_uint8_t_to_stereo,
135
                conv_swap_uint16_t_to_stereo
136
            }
80 137
        },
81 138
        {
82
            conv_int8_t_to_stereo,
83
            conv_int16_t_to_stereo
139
            {
140
                conv_natural_int8_t_to_stereo,
141
                conv_natural_int16_t_to_stereo
142
            },
143
            {
144
                conv_natural_int8_t_to_stereo,
145
                conv_swap_int16_t_to_stereo
146
            }
84 147
        }
85 148
    }
86 149
};
87 150

  
88
f_sample *mixeng_clip[2][2][2] = {
151
f_sample *mixeng_clip[2][2][2][2] = {
89 152
    {
90 153
        {
91
            clip_uint8_t_from_mono,
92
            clip_uint16_t_from_mono
154
            {
155
                clip_natural_uint8_t_from_mono,
156
                clip_natural_uint16_t_from_mono
157
            },
158
            {
159
                clip_natural_uint8_t_from_mono,
160
                clip_swap_uint16_t_from_mono
161
            }
93 162
        },
94 163
        {
95
            clip_int8_t_from_mono,
96
            clip_int16_t_from_mono
164
            {
165
                clip_natural_int8_t_from_mono,
166
                clip_natural_int16_t_from_mono
167
            },
168
            {
169
                clip_natural_int8_t_from_mono,
170
                clip_swap_int16_t_from_mono
171
            }
97 172
        }
98 173
    },
99 174
    {
100 175
        {
101
            clip_uint8_t_from_stereo,
102
            clip_uint16_t_from_stereo
176
            {
177
                clip_natural_uint8_t_from_stereo,
178
                clip_natural_uint16_t_from_stereo
179
            },
180
            {
181
                clip_natural_uint8_t_from_stereo,
182
                clip_swap_uint16_t_from_stereo
183
            }
103 184
        },
104 185
        {
105
            clip_int8_t_from_stereo,
106
            clip_int16_t_from_stereo
186
            {
187
                clip_natural_int8_t_from_stereo,
188
                clip_natural_int16_t_from_stereo
189
            },
190
            {
191
                clip_natural_int8_t_from_stereo,
192
                clip_swap_int16_t_from_stereo
193
            }
107 194
        }
108 195
    }
109 196
};
......
116 203
 * Contributors with a more efficient algorithm.]
117 204
 *
118 205
 * This source code is freely redistributable and may be used for
119
 * any purpose.  This copyright notice must be maintained. 
120
 * Lance Norskog And Sundry Contributors are not responsible for 
121
 * the consequences of using this software.  
206
 * any purpose.  This copyright notice must be maintained.
207
 * Lance Norskog And Sundry Contributors are not responsible for
208
 * the consequences of using this software.
122 209
 */
123 210

  
124 211
/*
......
156 243
    rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff));
157 244

  
158 245
    if (!rate) {
159
        exit (EXIT_FAILURE);
160
    }
161

  
162
    if (inrate == outrate) {
163
        // exit (EXIT_FAILURE);
164
    }
165

  
166
    if (inrate >= 65535 || outrate >= 65535) {
167
        // exit (EXIT_FAILURE);
246
        return NULL;
168 247
    }
169 248

  
170 249
    rate->opos = 0;
171 250

  
172 251
    /* increment */
173
    rate->opos_inc = (inrate * ((int64_t) UINT_MAX)) / outrate;
252
    rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
174 253

  
175 254
    rate->ipos = 0;
176 255
    rate->ilast.l = 0;
......
178 257
    return rate;
179 258
}
180 259

  
181
/*
182
 * Processed signed long samples from ibuf to obuf.
183
 * Return number of samples processed.
184
 */
185
void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
186
                   int *isamp, int *osamp)
187
{
188
    rate_t rate = (rate_t) opaque;
189
    st_sample_t *istart, *iend;
190
    st_sample_t *ostart, *oend;
191
    st_sample_t ilast, icur, out;
192
    int64_t t;
193

  
194
    ilast = rate->ilast;
195

  
196
    istart = ibuf;
197
    iend = ibuf + *isamp;
260
#define NAME st_rate_flow_mix
261
#define OP(a, b) a += b
262
#include "rate_template.h"
198 263

  
199
    ostart = obuf;
200
    oend = obuf + *osamp;
201

  
202
    if (rate->opos_inc == 1ULL << 32) {
203
        int i, n = *isamp > *osamp ? *osamp : *isamp;
204
        for (i = 0; i < n; i++) {
205
            obuf[i].l += ibuf[i].r;
206
            obuf[i].r += ibuf[i].r;
207
        }
208
        *isamp = n;
209
        *osamp = n;
210
        return;
211
    }
212

  
213
    while (obuf < oend) {
214

  
215
        /* Safety catch to make sure we have input samples.  */
216
        if (ibuf >= iend)
217
            break;
218

  
219
        /* read as many input samples so that ipos > opos */
220

  
221
        while (rate->ipos <= (rate->opos >> 32)) {
222
            ilast = *ibuf++;
223
            rate->ipos++;
224
            /* See if we finished the input buffer yet */
225
            if (ibuf >= iend) goto the_end;
226
        }
227

  
228
        icur = *ibuf;
229

  
230
        /* interpolate */
231
        t = rate->opos & 0xffffffff;
232
        out.l = (ilast.l * (INT_MAX - t) + icur.l * t) / INT_MAX;
233
        out.r = (ilast.r * (INT_MAX - t) + icur.r * t) / INT_MAX;
234

  
235
        /* output sample & increment position */
236
#if 0
237
        *obuf++ = out;
238
#else
239
        obuf->l += out.l;
240
        obuf->r += out.r;
241
        obuf += 1;
242
#endif
243
        rate->opos += rate->opos_inc;
244
    }
245

  
246
the_end:
247
    *isamp = ibuf - istart;
248
    *osamp = obuf - ostart;
249
    rate->ilast = ilast;
250
}
264
#define NAME st_rate_flow
265
#define OP(a, b) a = b
266
#include "rate_template.h"
251 267

  
252 268
void st_rate_stop (void *opaque)
253 269
{
254 270
    qemu_free (opaque);
255 271
}
272

  
273
void mixeng_clear (st_sample_t *buf, int len)
274
{
275
    memset (buf, 0, len * sizeof (st_sample_t));
276
}

Also available in: Unified diff