|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.