Statistics
| Branch: | Revision:

root / audio / mixeng.c @ 85571bc7

History | View | Annotate | Download (6.2 kB)

1
/*
2
 * QEMU Mixing engine
3
 *
4
 * Copyright (c) 2004 Vassili Karpov (malc)
5
 * Copyright (c) 1998 Fabrice Bellard
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
#include "vl.h"
26
//#define DEBUG_FP
27
#include "audio/mixeng.h"
28

    
29
#define IN_T int8_t
30
#define IN_MIN CHAR_MIN
31
#define IN_MAX CHAR_MAX
32
#define SIGNED
33
#include "mixeng_template.h"
34
#undef SIGNED
35
#undef IN_MAX
36
#undef IN_MIN
37
#undef IN_T
38

    
39
#define IN_T uint8_t
40
#define IN_MIN 0
41
#define IN_MAX UCHAR_MAX
42
#include "mixeng_template.h"
43
#undef IN_MAX
44
#undef IN_MIN
45
#undef IN_T
46

    
47
#define IN_T int16_t
48
#define IN_MIN SHRT_MIN
49
#define IN_MAX SHRT_MAX
50
#define SIGNED
51
#include "mixeng_template.h"
52
#undef SIGNED
53
#undef IN_MAX
54
#undef IN_MIN
55
#undef IN_T
56

    
57
#define IN_T uint16_t
58
#define IN_MIN 0
59
#define IN_MAX USHRT_MAX
60
#include "mixeng_template.h"
61
#undef IN_MAX
62
#undef IN_MIN
63
#undef IN_T
64

    
65
t_sample *mixeng_conv[2][2][2] = {
66
    {
67
        {
68
            conv_uint8_t_to_mono,
69
            conv_uint16_t_to_mono
70
        },
71
        {
72
            conv_int8_t_to_mono,
73
            conv_int16_t_to_mono
74
        }
75
    },
76
    {
77
        {
78
            conv_uint8_t_to_stereo,
79
            conv_uint16_t_to_stereo
80
        },
81
        {
82
            conv_int8_t_to_stereo,
83
            conv_int16_t_to_stereo
84
        }
85
    }
86
};
87

    
88
f_sample *mixeng_clip[2][2][2] = {
89
    {
90
        {
91
            clip_uint8_t_from_mono,
92
            clip_uint16_t_from_mono
93
        },
94
        {
95
            clip_int8_t_from_mono,
96
            clip_int16_t_from_mono
97
        }
98
    },
99
    {
100
        {
101
            clip_uint8_t_from_stereo,
102
            clip_uint16_t_from_stereo
103
        },
104
        {
105
            clip_int8_t_from_stereo,
106
            clip_int16_t_from_stereo
107
        }
108
    }
109
};
110

    
111
/*
112
 * August 21, 1998
113
 * Copyright 1998 Fabrice Bellard.
114
 *
115
 * [Rewrote completly the code of Lance Norskog And Sundry
116
 * Contributors with a more efficient algorithm.]
117
 *
118
 * 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.  
122
 */
123

    
124
/*
125
 * Sound Tools rate change effect file.
126
 */
127
/*
128
 * Linear Interpolation.
129
 *
130
 * The use of fractional increment allows us to use no buffer. It
131
 * avoid the problems at the end of the buffer we had with the old
132
 * method which stored a possibly big buffer of size
133
 * lcm(in_rate,out_rate).
134
 *
135
 * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
136
 * the input & output frequencies are equal, a delay of one sample is
137
 * introduced.  Limited to processing 32-bit count worth of samples.
138
 *
139
 * 1 << FRAC_BITS evaluating to zero in several places.  Changed with
140
 * an (unsigned long) cast to make it safe.  MarkMLl 2/1/99
141
 */
142

    
143
/* Private data */
144
typedef struct ratestuff {
145
    uint64_t opos;
146
    uint64_t opos_inc;
147
    uint32_t ipos;              /* position in the input stream (integer) */
148
    st_sample_t ilast;          /* last sample in the input stream */
149
} *rate_t;
150

    
151
/*
152
 * Prepare processing.
153
 */
154
void *st_rate_start (int inrate, int outrate)
155
{
156
    rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff));
157

    
158
    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);
168
    }
169

    
170
    rate->opos = 0;
171

    
172
    /* increment */
173
    rate->opos_inc = (inrate * ((int64_t) UINT_MAX)) / outrate;
174

    
175
    rate->ipos = 0;
176
    rate->ilast.l = 0;
177
    rate->ilast.r = 0;
178
    return rate;
179
}
180

    
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;
198

    
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
}
251

    
252
void st_rate_stop (void *opaque)
253
{
254
    qemu_free (opaque);
255
}