|
1 /* |
|
2 * QEMU Mixing engine |
|
3 * |
|
4 * Copyright (c) 2004-2005 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 |
|
26 /* |
|
27 * Processed signed long samples from ibuf to obuf. |
|
28 * Return number of samples processed. |
|
29 */ |
|
30 void NAME (void *opaque, struct st_sample *ibuf, struct st_sample *obuf, |
|
31 int *isamp, int *osamp) |
|
32 { |
|
33 struct rate *rate = opaque; |
|
34 struct st_sample *istart, *iend; |
|
35 struct st_sample *ostart, *oend; |
|
36 struct st_sample ilast, icur, out; |
|
37 #ifdef FLOAT_MIXENG |
|
38 mixeng_real t; |
|
39 #else |
|
40 int64_t t; |
|
41 #endif |
|
42 |
|
43 ilast = rate->ilast; |
|
44 |
|
45 istart = ibuf; |
|
46 iend = ibuf + *isamp; |
|
47 |
|
48 ostart = obuf; |
|
49 oend = obuf + *osamp; |
|
50 |
|
51 if (rate->opos_inc == (1ULL + UINT_MAX)) { |
|
52 int i, n = *isamp > *osamp ? *osamp : *isamp; |
|
53 for (i = 0; i < n; i++) { |
|
54 OP (obuf[i].l, ibuf[i].l); |
|
55 OP (obuf[i].r, ibuf[i].r); |
|
56 } |
|
57 *isamp = n; |
|
58 *osamp = n; |
|
59 return; |
|
60 } |
|
61 |
|
62 while (obuf < oend) { |
|
63 |
|
64 /* Safety catch to make sure we have input samples. */ |
|
65 if (ibuf >= iend) { |
|
66 break; |
|
67 } |
|
68 |
|
69 /* read as many input samples so that ipos > opos */ |
|
70 |
|
71 while (rate->ipos <= (rate->opos >> 32)) { |
|
72 ilast = *ibuf++; |
|
73 rate->ipos++; |
|
74 /* See if we finished the input buffer yet */ |
|
75 if (ibuf >= iend) { |
|
76 goto the_end; |
|
77 } |
|
78 } |
|
79 |
|
80 icur = *ibuf; |
|
81 |
|
82 /* interpolate */ |
|
83 #ifdef FLOAT_MIXENG |
|
84 #ifdef RECIPROCAL |
|
85 t = (rate->opos & UINT_MAX) * (1.f / UINT_MAX); |
|
86 #else |
|
87 t = (rate->opos & UINT_MAX) / (mixeng_real) UINT_MAX; |
|
88 #endif |
|
89 out.l = (ilast.l * (1.0 - t)) + icur.l * t; |
|
90 out.r = (ilast.r * (1.0 - t)) + icur.r * t; |
|
91 #else |
|
92 t = rate->opos & 0xffffffff; |
|
93 out.l = (ilast.l * ((int64_t) UINT_MAX - t) + icur.l * t) >> 32; |
|
94 out.r = (ilast.r * ((int64_t) UINT_MAX - t) + icur.r * t) >> 32; |
|
95 #endif |
|
96 |
|
97 /* output sample & increment position */ |
|
98 OP (obuf->l, out.l); |
|
99 OP (obuf->r, out.r); |
|
100 obuf += 1; |
|
101 rate->opos += rate->opos_inc; |
|
102 } |
|
103 |
|
104 the_end: |
|
105 *isamp = ibuf - istart; |
|
106 *osamp = obuf - ostart; |
|
107 rate->ilast = ilast; |
|
108 } |
|
109 |
|
110 #undef NAME |
|
111 #undef OP |