/
filter_templates.h
193 lines (170 loc) · 5.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
* Extended Audio Converter for SDL (Simple DirectMedia Layer)
* Copyright (C) 2002 Frank Ranostaj
* Institute of Applied Physik
* Johann Wolfgang Goethe-Universität
* Frankfurt am Main, Germany
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Frank Ranostaj
* ranostaj@stud.uni-frankfurt.de
*
* (This code blatantly abducted for SDL_sound. Thanks, Frank! --ryan.)
*/
#ifndef Suffix
#error include filter_template.h with defined Suffix macro!
#else
#define CH(x) (Suffix((x)*))
/*-------------------------------------------------------------------------*/
34
35
36
/* this filter (Kaiser-window beta=6.8) gives a decent -80dB attentuation */
/*-------------------------------------------------------------------------*/
#define sum_d(v,dx) ((int) v[CH(dx)] + v[CH(1-dx)])
37
38
static Sint16* Suffix(doubleRate)( Sint16 *outp, Sint16 *inp, int length,
VarFilter* filt, int* cpos )
39
{
40
41
int out;
Sint16 *to;
42
43
to = inp - length;
44
45
while( inp > to )
46
{
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
out = 0;
out-= 9 * sum_d( inp, 16);
out+= 23 * sum_d( inp, 15);
out-= 46 * sum_d( inp, 14);
out+= 83 * sum_d( inp, 13);
out-= 138 * sum_d( inp, 12);
out+= 217 * sum_d( inp, 11);
out-= 326 * sum_d( inp, 10);
out+= 474 * sum_d( inp, 9);
out-= 671 * sum_d( inp, 8);
out+= 936 * sum_d( inp, 7);
out-= 1295 * sum_d( inp, 6);
out+= 1800 * sum_d( inp, 5);
out-= 2560 * sum_d( inp, 4);
out+= 3863 * sum_d( inp, 3);
out-= 6764 * sum_d( inp, 2);
out+= 20798 * sum_d( inp, 1);
64
65
66
outp[CH(1)] = ( 32770 * inp[CH(1)] + out) >> 16;
outp[CH(0)] = ( 32770 * inp[CH(0)] + out) >> 16;
67
68
inp -= CH(1);
69
outp -= CH(2);
70
}
71
return outp;
72
}
73
#undef sum_d
74
75
/*-------------------------------------------------------------------------*/
76
#define sum_h(v,dx) ((int) v[CH(dx)] + v[CH(-dx)])
77
78
static Sint16* Suffix(halfRate)( Sint16 *outp, Sint16 *inp, int length,
VarFilter* filt, int* cpos )
79
{
80
int out;
81
Sint16* to;
82
83
to = inp + length;
84
85
while( inp < to )
86
{
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
out = 0;
out-= 9 * sum_h( inp, 31);
out+= 23 * sum_h( inp, 29);
out-= 46 * sum_h( inp, 27);
out+= 83 * sum_h( inp, 25);
out-= 138 * sum_h( inp, 23);
out+= 217 * sum_h( inp, 21);
out-= 326 * sum_h( inp, 19);
out+= 474 * sum_h( inp, 17);
out-= 671 * sum_h( inp, 15);
out+= 936 * sum_h( inp, 13);
out-= 1295 * sum_h( inp, 11);
out+= 1800 * sum_h( inp, 9);
out-= 2560 * sum_h( inp, 7);
out+= 3863 * sum_h( inp, 5);
102
out-= 6764 * sum_h( inp, 3);
103
104
105
out+= 20798 * sum_h( inp, 1);
out+= 32770 * (int)inp[0];
106
outp[0] = out >> 16;
107
108
inp+= CH(2);
109
outp += CH(1);
110
}
111
return outp;
112
}
113
#undef sum_h
114
115
116
/*-------------------------------------------------------------------------*/
static Sint16* Suffix(increaseRate)( Sint16 *outp, Sint16 *inp, int length,
117
VarFilter* filter, int* cpos )
118
{
119
const static int fsize = CH(2*_fsize);
120
Sint16 *f;
121
122
123
int out;
int i, pos;
Sint16* to;
124
125
126
inp -= fsize;
to = inp - length;
127
pos = *cpos;
128
129
while( inp > to )
130
{
131
out = 0;
132
f = filter->c[pos];
133
for( i = _fsize + 1; --i; inp+=CH(4), f+=4 )
134
135
{
out+= f[0] * (int)inp[CH(0)];
136
137
138
out+= f[1] * (int)inp[CH(1)];
out+= f[2] * (int)inp[CH(2)];
out+= f[3] * (int)inp[CH(3)];
139
}
140
outp[0] = out >> 16;
141
142
143
144
pos = ( pos + filter->ratio.denominator - 1 )
% filter->ratio.denominator;
inp -= CH( 4 * _fsize );
145
inp -= CH( filter->incr[pos] );
146
outp -= CH(1);
147
}
148
149
*cpos = pos;
150
return outp;
151
152
}
153
154
/*-------------------------------------------------------------------------*/
static Sint16* Suffix(decreaseRate)( Sint16 *outp, Sint16 *inp, int length,
155
VarFilter* filter, int* cpos )
156
{
157
const static int fsize = CH(2*_fsize);
158
Sint16 *f;
159
160
161
int out;
int i, pos;
Sint16 *to;
162
163
164
inp -= fsize;
to = inp + length;
165
pos = *cpos;
166
167
while( inp < to )
168
{
169
out = 0;
170
171
172
173
174
175
176
177
f = filter->c[pos];
for( i = _fsize + 1; --i; inp+=CH(4), f+=4 )
{
out+= f[0] * (int)inp[CH(0)];
out+= f[1] * (int)inp[CH(1)];
out+= f[2] * (int)inp[CH(2)];
out+= f[3] * (int)inp[CH(3)];
}
178
179
outp[0] = out >> 16;
180
181
inp -= CH( 4 * _fsize );
inp += CH( filter->incr[pos] );
182
outp += CH(1);
183
pos = ( pos + 1 ) % filter->ratio.denominator;
184
}
185
186
*cpos = pos;
187
return outp;
188
}
189
190
/*-------------------------------------------------------------------------*/
191
192
#undef CH
#endif /* Suffix */