Mercurial > SDL_sound_CoreAudio
comparison filter_templates.h @ 365:f61eadea1f44
More revisions from Frank.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Tue, 18 Jun 2002 21:49:44 +0000 |
parents | c7f73428deaf |
children | eda146d666d1 |
comparison
equal
deleted
inserted
replaced
364:4bcbc442d145 | 365:f61eadea1f44 |
---|---|
1 /* | 1 /* |
2 Extended Audio Converter for SDL (Simple DirectMedia Layer) | 2 * Extended Audio Converter for SDL (Simple DirectMedia Layer) |
3 Copyright (C) 2002 Frank Ranostaj | 3 * Copyright (C) 2002 Frank Ranostaj |
4 Institute of Applied Physik | 4 * Institute of Applied Physik |
5 Johann Wolfgang Goethe-Universität | 5 * Johann Wolfgang Goethe-Universität |
6 Frankfurt am Main, Germany | 6 * Frankfurt am Main, Germany |
7 | 7 * |
8 This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
11 version 2 of the License, or (at your option) any later version. | 11 * version 2 of the License, or (at your option) any later version. |
12 | 12 * |
13 This library is distributed in the hope that it will be useful, | 13 * This library is distributed in the hope that it will be useful, |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 Library General Public License for more details. | 16 * Library General Public License for more details. |
17 | 17 * |
18 You should have received a copy of the GNU Library General Public | 18 * You should have received a copy of the GNU Library General Public |
19 License along with this library; if not, write to the Free | 19 * License along with this library; if not, write to the Free |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | 21 * |
22 Frank Ranostaj | 22 * Frank Ranostaj |
23 ranostaj@stud.uni-frankfurt.de | 23 * ranostaj@stud.uni-frankfurt.de |
24 */ | 24 * |
25 * (This code blatantly abducted for SDL_sound. Thanks, Frank! --ryan.) | |
26 */ | |
25 | 27 |
26 #ifndef Suffix | 28 #ifndef Suffix |
27 #error include filter_template.h with defined Suffix macro! | 29 #error include filter_template.h with defined Suffix macro! |
28 #else | 30 #else |
29 #define CH(x) (Suffix((x)*)) | 31 #define CH(x) (Suffix((x)*)) |
30 //--------------------------------------------------------------------------- | 32 /*-------------------------------------------------------------------------*/ |
31 int Suffix(_doubleRate)( short *buffer, int mode, int length ) | 33 /* |
34 * !!! FIXME !!! | |
35 * | |
36 * | |
37 * Tune doubleRate(), halfRate() and varRate() for speed | |
38 * - Frank | |
39 */ | |
40 | |
41 /*-------------------------------------------------------------------------*/ | |
42 static Sint16* Suffix(doubleRate)( Sint16 *outp, Sint16 *inp, int length, | |
43 VarFilter* filt, int* cpos ) | |
32 { | 44 { |
33 const fsize = _fsize/2; | 45 static const int fsize = _fsize; |
34 int i,di,border; | 46 int i, out; |
35 short inbuffer[_fsize]; | 47 Sint16* to; |
36 | 48 |
37 if( mode & SDL_AI_Loop ) | 49 inp += fsize; |
50 to = inp + length; | |
51 | |
52 for(; inp > to; inp -= CH(1) ) | |
38 { | 53 { |
39 for( i = 0; i < fsize; i++ ) | 54 out = 0; |
40 { | 55 for( i = 1; i < 1+fsize; i++ ) |
41 inbuffer[CH(i+fsize)] = buffer[CH(length+i)] = buffer[CH(i)]; | 56 out+= filter[2*i] * ( inp[CH(i)] + inp[CH(1-i)] ); |
42 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; | 57 |
43 } | 58 outp[CH(1)] = ( 32770 * inp[CH(1)] + out) >> 16; |
44 border = 0; | 59 outp[CH(0)] = ( 32770 * inp[CH(0)] + out) >> 16; |
60 outp -= CH(2); | |
45 } | 61 } |
46 else | 62 return outp; |
47 { | |
48 for( i = 0; i < fsize; i++ ) | |
49 { | |
50 inbuffer[CH(i)] = buffer[CH(length+i)] = 0; | |
51 inbuffer[CH(i+fsize)] = buffer[CH(i)]; | |
52 } | |
53 border = fsize/2; | |
54 } | |
55 | |
56 for(i = length + border - 1; i >= -border; i--) | |
57 { | |
58 const short* const inp = i < fsize/2 ? | |
59 &inbuffer[CH(i+fsize)] : &buffer[CH(i)]; | |
60 short* const outp = &buffer[CH(2*(i+border))]; | |
61 int out = 0; | |
62 | |
63 for( di = 1; di < 1+fsize; di+=2 ) | |
64 out+= filter[di]*( inp[CH(di)/2] + inp[CH(1-di)/2] ); | |
65 outp[CH(1)] = ( 32770*inp[CH(1)] + out) >> 16; | |
66 outp[CH(0)] = ( 32770*inp[CH(0)] + out) >> 16; | |
67 } | |
68 return 2*length + 4*border; | |
69 } | 63 } |
70 | 64 |
71 //--------------------------------------------------------------------------- | 65 /*-------------------------------------------------------------------------*/ |
72 short Suffix(filterHalfBand)( short* inp ) | 66 static Sint16* Suffix(halfRate)( Sint16 *outp, Sint16 *inp, int length, |
67 VarFilter* filt, int* cpos ) | |
73 { | 68 { |
74 static const int fsize = _fsize; | 69 static const int fsize = CH(_fsize/2); |
75 int out = 32770*inp[0]; | 70 int i, out; |
76 int di; | 71 Sint16* to; |
77 for( di = 1; di < fsize/2; di+=2 ) | 72 |
78 out+= filter[di]*( inp[CH(di)] + inp[CH(-di)] ); | 73 inp -= fsize; |
79 return out >> 16; | 74 to = inp + length; |
75 | |
76 for(; inp < to; inp+= CH(2) ) | |
77 { | |
78 out = 32770 * inp[0]; | |
79 for( i = 1; i < fsize/2; i+=2 ) | |
80 out+= filter[i]*( (int)inp[CH(i)] + inp[CH(-i)] ); | |
81 outp[0] = out >> 16; | |
82 | |
83 outp += CH(1); | |
84 } | |
85 return outp; | |
80 } | 86 } |
81 | 87 |
82 int Suffix(_halfRate)( short *buffer, int mode, int length ) | 88 /*-------------------------------------------------------------------------*/ |
89 static Sint16* Suffix(increaseRate)( Sint16 *outp, Sint16 *inp, int length, | |
90 VarFilter* filt, int* cpos ) | |
83 { | 91 { |
84 static const int fsize = _fsize; | 92 const static int fsize = 2*_fsize; |
93 Sint16 *filter; | |
94 int out; | |
95 int i, pos; | |
96 Sint16* to; | |
85 | 97 |
86 int i,border; | 98 inp += fsize; |
99 to = inp + length; | |
87 | 100 |
88 short inbuffer[3*_fsize]; | 101 while( inp > to ) |
89 short *finp, *linp; | 102 { |
103 pos = *cpos; | |
104 out = 0; | |
105 filter = filt->c[pos]; | |
106 for( i = 0; i < 2*_fsize; i++ ) | |
107 out+= filter[i] * (int)inp[CH(i)]; | |
108 outp[0] = out >> 16; | |
90 | 109 |
91 if( mode & SDL_AI_Loop ) | 110 inp -= CH(filt->incr[pos]); |
92 { | 111 outp -= CH(1); |
93 if( length & 1 ) | 112 *cpos = ( pos + 1 ) % filt->denominator; |
94 { | |
95 // do something meaningful | |
96 } | |
97 for( i = 0; i < fsize; i++ ) | |
98 { | |
99 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; | |
100 inbuffer[CH(i+fsize)] = buffer[CH(i)]; | |
101 } | |
102 border = 0; | |
103 finp = inbuffer + CH( fsize ); | |
104 linp = inbuffer + CH( fsize-length ); | |
105 } | 113 } |
106 else | 114 return outp; |
107 { | |
108 for( i = 0; i < fsize; i++ ) | |
109 { | |
110 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; | |
111 inbuffer[CH(i+fsize)] = 0; | |
112 inbuffer[CH(i+2*fsize)] = buffer[CH(i)]; | |
113 } | |
114 border = fsize; | |
115 finp = inbuffer + CH( (3*fsize)/2 + 2*border ); | |
116 linp = inbuffer + CH( fsize/2 - length ); | |
117 } | |
118 | |
119 length = ( length + 1 ) / 2; | |
120 | |
121 for(i = -border; i < fsize; i++) | |
122 { | |
123 buffer[CH(i+border)] = Suffix(filterHalfBand)( finp+CH(2*i) ); | |
124 } | |
125 for(; i < length-fsize; i++) | |
126 { | |
127 buffer[CH(i+border)] = Suffix(filterHalfBand)( buffer+CH(2*i) ); | |
128 } | |
129 for(; i < length+border; i++) | |
130 { | |
131 buffer[CH(i+border)] = Suffix(filterHalfBand)( linp+CH(2*i) ); | |
132 } | |
133 return length + 2*border; | |
134 } | 115 } |
135 | 116 |
136 //--------------------------------------------------------------------------- | 117 /*-------------------------------------------------------------------------*/ |
137 short Suffix(filterVarBand)( VarFilter* filt, short** inpp, char* cpos ) | 118 static Sint16* Suffix(decreaseRate)( Sint16 *outp, Sint16 *inp, int length, |
119 VarFilter* filt, int* cpos ) | |
138 { | 120 { |
139 int di; | 121 const static int fsize = 2*_fsize; |
140 int out = 0; | 122 Sint16 *filter; |
141 short *inp = *inpp; | 123 int out; |
142 int pos = *cpos; | 124 int i, pos; |
143 short *filter = filt->c[pos]; | 125 Sint16 *to; |
144 | 126 |
145 for( di = 0; di < 2*_fsize; di++ ) | 127 inp -= fsize; |
146 out+= filter[di] * (int)inp[CH(di)]; | 128 to = inp + length; |
147 | 129 |
148 *inpp += CH(filt->incr[pos]); | 130 while( inp < to ) |
149 *cpos = ( pos + 1 ) % filt->pos_mod; | 131 { |
150 return out >> 16; | 132 pos = *cpos; |
133 out = 0; | |
134 filter = filt->c[pos]; | |
135 for( i = 0; i < 2*_fsize; i++ ) | |
136 out+= filter[i] * (int)inp[CH(i)]; | |
137 outp[0] = out >> 16; | |
138 | |
139 inp += CH(filt->incr[pos]); | |
140 outp += CH(1); | |
141 *cpos = ( pos + 1 ) % filt->denominator; | |
142 } | |
143 return outp; | |
151 } | 144 } |
152 | 145 |
153 int Suffix(_varRateDown)( short* buffer, int mode, VarFilter* filter, int length ) | 146 /*-------------------------------------------------------------------------*/ |
154 { | |
155 static const int fsize = _fsize; | |
156 int i,border; | |
157 short inbuffer[CH(3*_fsize)]; | |
158 short *finp, *linp, *bufp, *outbuf; | |
159 char pos = 0; | |
160 VarFilter* filterp = filter; | |
161 | |
162 if( mode & SDL_AI_Loop ) | |
163 { | |
164 for( i = 0; i < fsize; i++ ) | |
165 { | |
166 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; | |
167 inbuffer[CH(i+fsize)] = buffer[CH(i)]; | |
168 } | |
169 border = 0; | |
170 finp = inbuffer+CH(fsize); | |
171 linp = inbuffer+CH(fsize-length); | |
172 } | |
173 else | |
174 { | |
175 for( i = 0; i < fsize; i++ ) | |
176 { | |
177 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; | |
178 inbuffer[CH(i+fsize)] = 0; | |
179 inbuffer[CH(i+2*fsize)] = buffer[CH(i)]; | |
180 } | |
181 border = fsize; | |
182 finp = inbuffer + CH( 3*fsize/2 ); | |
183 linp = inbuffer + CH( fsize/2 ); | |
184 } | |
185 | |
186 length = ( length + 1 ) / 2; | |
187 bufp = buffer; | |
188 outbuf = buffer+CH(border); | |
189 | |
190 for(i = -border; i < fsize; i++) | |
191 { | |
192 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &finp, &pos ); | |
193 } | |
194 for(; i < length-fsize; i++) | |
195 { | |
196 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &bufp, &pos ); | |
197 } | |
198 for(; i < length+border; i++) | |
199 { | |
200 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &linp, &pos ); | |
201 } | |
202 return length + 2*border; | |
203 } | |
204 | |
205 int Suffix(_varRateUp)( short* buffer, int mode, VarFilter* filter, int length ) | |
206 { | |
207 static const int fsize = _fsize; | |
208 int i,border; | |
209 short inbuffer[CH(3*_fsize)]; | |
210 short *finp, *linp, *bufp, *outbuf; | |
211 char pos = 0; | |
212 VarFilter* filterp = filter; | |
213 | |
214 if( mode & SDL_AI_Loop ) | |
215 { | |
216 for( i = 0; i < fsize; i++ ) | |
217 { | |
218 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; | |
219 inbuffer[CH(i+fsize)] = buffer[CH(i)]; | |
220 } | |
221 border = 0; | |
222 finp = inbuffer+CH(fsize); | |
223 linp = inbuffer+CH(fsize-length); | |
224 } | |
225 else | |
226 { | |
227 for( i = 0; i < fsize; i++ ) | |
228 { | |
229 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; | |
230 inbuffer[CH(i+fsize)] = 0; | |
231 inbuffer[CH(i+2*fsize)] = buffer[CH(i)]; | |
232 } | |
233 border = fsize; | |
234 finp = inbuffer + CH( 3*fsize/2 ); | |
235 linp = inbuffer + CH( fsize/2 ); | |
236 } | |
237 | |
238 length = 2 * length; | |
239 bufp = buffer+length; | |
240 outbuf = buffer+CH(border); | |
241 | |
242 for(i = length+border-1; i > length-fsize-1; i--) | |
243 { | |
244 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &linp, &pos ); | |
245 } | |
246 for(; i > fsize-1 ; i--) | |
247 { | |
248 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &bufp, &pos ); | |
249 } | |
250 for(; i > -border-1; i--) | |
251 { | |
252 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &finp, &pos ); | |
253 } | |
254 return length + 2*border; | |
255 } | |
256 //--------------------------------------------------------------------------- | |
257 #undef CH | 147 #undef CH |
258 #endif /* Suffix */ | 148 #endif /* Suffix */ |
259 | 149 |