comparison filter_templates.h @ 362:c7f73428deaf

Updated from Frank.
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 12 Jun 2002 18:16:33 +0000
parents 7b9a0f3f030e
children f61eadea1f44
comparison
equal deleted inserted replaced
361:473e6217fdfa 362:c7f73428deaf
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
25 (This code blatantly abducted for SDL_sound. Thanks, Frank! --ryan.)
26
27 */ 24 */
28 25
29 #ifndef Suffix 26 #ifndef Suffix
30 #error include filter_template.h with defined Suffix macro! 27 #error include filter_template.h with defined Suffix macro!
31 #else 28 #else
32 #define CH(x) (Suffix((x)*)) 29 #define CH(x) (Suffix((x)*))
33 //--------------------------------------------------------------------------- 30 //---------------------------------------------------------------------------
34 int Suffix(_doubleRate)( short *buffer, int mode, int length ) 31 int Suffix(_doubleRate)( short *buffer, int mode, int length )
35 { 32 {
36 const fsize = _fsize/2; 33 const fsize = _fsize/2;
37 int i,di,border; 34 int i,di,border;
38 short inbuffer[_fsize]; 35 short inbuffer[_fsize];
39 36
40 if( mode & Sound_AI_Loop ) 37 if( mode & SDL_AI_Loop )
41 { 38 {
42 for( i = 0; i < fsize; i++ ) 39 for( i = 0; i < fsize; i++ )
43 { 40 {
44 inbuffer[CH(i+fsize)] = buffer[CH(length+i)] = buffer[CH(i)]; 41 inbuffer[CH(i+fsize)] = buffer[CH(length+i)] = buffer[CH(i)];
45 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; 42 inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
46 } 43 }
47 border = 0; 44 border = 0;
48 } 45 }
49 else 46 else
50 { 47 {
51 for( i = 0; i < fsize; i++ ) 48 for( i = 0; i < fsize; i++ )
52 { 49 {
53 inbuffer[CH(i)] = buffer[CH(length+i)] = 0; 50 inbuffer[CH(i)] = buffer[CH(length+i)] = 0;
54 inbuffer[CH(i+fsize)] = buffer[CH(i)]; 51 inbuffer[CH(i+fsize)] = buffer[CH(i)];
55 } 52 }
56 border = fsize/2; 53 border = fsize/2;
57 } 54 }
58 55
59 for(i = length + border - 1; i >= -border; i--) 56 for(i = length + border - 1; i >= -border; i--)
60 { 57 {
61 const short* const inp = i < fsize/2 ? 58 const short* const inp = i < fsize/2 ?
62 &inbuffer[CH(i+fsize)] : &buffer[CH(i)]; 59 &inbuffer[CH(i+fsize)] : &buffer[CH(i)];
63 short* const outp = &buffer[CH(2*(i+border))]; 60 short* const outp = &buffer[CH(2*(i+border))];
64 int out = 0; 61 int out = 0;
65 62
66 for( di = 1; di < 1+fsize; di+=2 ) 63 for( di = 1; di < 1+fsize; di+=2 )
67 out+= filter[di]*( inp[CH(di)/2] + inp[CH(1-di)/2] ); 64 out+= filter[di]*( inp[CH(di)/2] + inp[CH(1-di)/2] );
68 outp[CH(1)] = ( 32770*inp[CH(1)] + out) >> 16; 65 outp[CH(1)] = ( 32770*inp[CH(1)] + out) >> 16;
69 outp[CH(0)] = ( 32770*inp[CH(0)] + out) >> 16; 66 outp[CH(0)] = ( 32770*inp[CH(0)] + out) >> 16;
70 } 67 }
71 return 2*length + 4*border; 68 return 2*length + 4*border;
72 } 69 }
73 70
74 //--------------------------------------------------------------------------- 71 //---------------------------------------------------------------------------
75 short Suffix(filterHalfBand)( short* inp ) 72 short Suffix(filterHalfBand)( short* inp )
76 { 73 {
77 static const int fsize = _fsize; 74 static const int fsize = _fsize;
78 int out = 32770*inp[0]; 75 int out = 32770*inp[0];
79 int di; 76 int di;
80 for( di = 1; di < fsize/2; di+=2 ) 77 for( di = 1; di < fsize/2; di+=2 )
81 out+= filter[di]*( inp[CH(di)] + inp[CH(-di)] ); 78 out+= filter[di]*( inp[CH(di)] + inp[CH(-di)] );
82 return out >> 16; 79 return out >> 16;
83 } 80 }
84 81
85 int Suffix(_halfRate)( short *buffer, int mode, int length ) 82 int Suffix(_halfRate)( short *buffer, int mode, int length )
86 { 83 {
87 static const int fsize = _fsize; 84 static const int fsize = _fsize;
88 85
89 int i,border; 86 int i,border;
90 87
91 short inbuffer[3*_fsize]; 88 short inbuffer[3*_fsize];
92 short *finp, *linp; 89 short *finp, *linp;
93 90
94 if( mode & Sound_AI_Loop ) 91 if( mode & SDL_AI_Loop )
95 { 92 {
96 if( length & 1 ) 93 if( length & 1 )
97 { 94 {
98 // do something meaningful 95 // do something meaningful
99 } 96 }
100 for( i = 0; i < fsize; i++ ) 97 for( i = 0; i < fsize; i++ )
101 { 98 {
102 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; 99 inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
103 inbuffer[CH(i+fsize)] = buffer[CH(i)]; 100 inbuffer[CH(i+fsize)] = buffer[CH(i)];
104 } 101 }
105 border = 0; 102 border = 0;
106 finp = inbuffer + CH( fsize ); 103 finp = inbuffer + CH( fsize );
107 linp = inbuffer + CH( fsize-length ); 104 linp = inbuffer + CH( fsize-length );
108 } 105 }
109 else 106 else
110 { 107 {
111 for( i = 0; i < fsize; i++ ) 108 for( i = 0; i < fsize; i++ )
112 { 109 {
113 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; 110 inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
114 inbuffer[CH(i+fsize)] = 0; 111 inbuffer[CH(i+fsize)] = 0;
115 inbuffer[CH(i+2*fsize)] = buffer[CH(i)]; 112 inbuffer[CH(i+2*fsize)] = buffer[CH(i)];
116 } 113 }
117 border = fsize; 114 border = fsize;
118 finp = inbuffer + CH( (3*fsize)/2 + 2*border ); 115 finp = inbuffer + CH( (3*fsize)/2 + 2*border );
119 linp = inbuffer + CH( fsize/2 - length ); 116 linp = inbuffer + CH( fsize/2 - length );
120 } 117 }
121 118
122 length = ( length + 1 ) / 2; 119 length = ( length + 1 ) / 2;
123 120
124 for(i = -border; i < fsize; i++) 121 for(i = -border; i < fsize; i++)
125 { 122 {
126 buffer[CH(i+border)] = Suffix(filterHalfBand)( finp+CH(2*i) ); 123 buffer[CH(i+border)] = Suffix(filterHalfBand)( finp+CH(2*i) );
127 } 124 }
128 for(; i < length-fsize; i++) 125 for(; i < length-fsize; i++)
129 { 126 {
130 buffer[CH(i+border)] = Suffix(filterHalfBand)( buffer+CH(2*i) ); 127 buffer[CH(i+border)] = Suffix(filterHalfBand)( buffer+CH(2*i) );
131 } 128 }
132 for(; i < length+border; i++) 129 for(; i < length+border; i++)
133 { 130 {
134 buffer[CH(i+border)] = Suffix(filterHalfBand)( linp+CH(2*i) ); 131 buffer[CH(i+border)] = Suffix(filterHalfBand)( linp+CH(2*i) );
135 } 132 }
136 return length + 2*border; 133 return length + 2*border;
137 } 134 }
138 135
139 //--------------------------------------------------------------------------- 136 //---------------------------------------------------------------------------
140 short Suffix(filterVarBand)( VarFilter* filt, short** inpp, char* cpos ) 137 short Suffix(filterVarBand)( VarFilter* filt, short** inpp, char* cpos )
141 { 138 {
142 static const int fsize = _fsize; 139 int di;
143 140 int out = 0;
144 int di; 141 short *inp = *inpp;
145 int out = 0; 142 int pos = *cpos;
146 short *inp = *inpp; 143 short *filter = filt->c[pos];
147 int pos = *cpos; 144
148 short *filter = filt->c[pos]; 145 for( di = 0; di < 2*_fsize; di++ )
149 146 out+= filter[di] * (int)inp[CH(di)];
150 for( di = 0; di < fsize; di++ ) 147
151 out+= filter[di] * (int)inp[CH(di)]; 148 *inpp += CH(filt->incr[pos]);
152 149 *cpos = ( pos + 1 ) % filt->pos_mod;
153 *inpp += CH(filt->incr[pos]); 150 return out >> 16;
154 *cpos = ( pos + 1 ) % filt->pos_mod; 151 }
155 return out >> 16; 152
156 } 153 int Suffix(_varRateDown)( short* buffer, int mode, VarFilter* filter, int length )
157 154 {
158 int Suffix(_varRate)( short* buffer, int mode, VarFilter* filter, int 155 static const int fsize = _fsize;
159 length ) 156 int i,border;
160 { 157 short inbuffer[CH(3*_fsize)];
161 static const int fsize = _fsize; 158 short *finp, *linp, *bufp, *outbuf;
162 int i,border; 159 char pos = 0;
163 short inbuffer[CH(3*_fsize)]; 160 VarFilter* filterp = filter;
164 short *finp, *linp, *bufp; 161
165 char pos = 0; 162 if( mode & SDL_AI_Loop )
166 VarFilter* filterp = filter; 163 {
167 164 for( i = 0; i < fsize; i++ )
168 if( mode & Sound_AI_Loop ) 165 {
169 { 166 inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
170 for( i = 0; i < fsize; i++ ) 167 inbuffer[CH(i+fsize)] = buffer[CH(i)];
171 { 168 }
172 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; 169 border = 0;
173 inbuffer[CH(i+fsize)] = buffer[CH(i)]; 170 finp = inbuffer+CH(fsize);
174 } 171 linp = inbuffer+CH(fsize-length);
175 border = 0; 172 }
176 finp = inbuffer+CH(fsize); 173 else
177 linp = inbuffer+CH(fsize-length); 174 {
178 } 175 for( i = 0; i < fsize; i++ )
179 else 176 {
180 { 177 inbuffer[CH(i)] = buffer[CH(length-fsize+i)];
181 for( i = 0; i < fsize; i++ ) 178 inbuffer[CH(i+fsize)] = 0;
182 { 179 inbuffer[CH(i+2*fsize)] = buffer[CH(i)];
183 inbuffer[CH(i)] = buffer[CH(length-fsize+i)]; 180 }
184 inbuffer[CH(i+fsize)] = 0; 181 border = fsize;
185 inbuffer[CH(i+2*fsize)] = buffer[CH(i)]; 182 finp = inbuffer + CH( 3*fsize/2 );
186 } 183 linp = inbuffer + CH( fsize/2 );
187 border = fsize; 184 }
188 finp = inbuffer + CH( (3*fsize)/2 + 2*border ); 185
189 linp = inbuffer + CH( fsize/2 - length ); 186 length = ( length + 1 ) / 2;
190 } 187 bufp = buffer;
191 188 outbuf = buffer+CH(border);
192 length = ( length + 1 ) / 2; 189
193 bufp = buffer; 190 for(i = -border; i < fsize; i++)
194 191 {
195 for(i = -border; i < fsize; i++) 192 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &finp, &pos );
196 { 193 }
197 buffer[CH(i+border)] = Suffix(filterVarBand)( filterp, &finp, &pos ); 194 for(; i < length-fsize; i++)
198 } 195 {
199 for(; i < length-fsize; i++) 196 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &bufp, &pos );
200 { 197 }
201 buffer[CH(i+border)] = Suffix(filterVarBand)( filterp, &bufp, &pos ); 198 for(; i < length+border; i++)
202 } 199 {
203 for(; i < length+border; i++) 200 outbuf[CH(i)] = Suffix(filterVarBand)( filterp, &linp, &pos );
204 { 201 }
205 buffer[CH(i+border)] = Suffix(filterVarBand)( filterp, &linp, &pos ); 202 return length + 2*border;
206 } 203 }
207 return length + 2*border; 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;
208 } 255 }
209 //--------------------------------------------------------------------------- 256 //---------------------------------------------------------------------------
210 #undef CH 257 #undef CH
211 #endif /* Suffix */ 258 #endif /* Suffix */
212 259