comparison filter_templates.h @ 338:7b9a0f3f030e

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