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