/
filter_templates.h
199 lines (174 loc) · 5.78 KB
1
/*
2
3
4
* Extended Audio Converter for SDL (Simple DirectMedia Layer)
* Copyright (C) 2002 Frank Ranostaj
* Institute of Applied Physik
5
* Johann Wolfgang Goethe-Universität
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
* 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.)
*/
27
28
29
30
31
32
33
#ifndef Suffix
#error include filter_template.h with defined Suffix macro!
#else
#define CH(x) (Suffix((x)*))
/*-------------------------------------------------------------------------*/
34
/* this filter (Kaiser-window beta=6.8) gives a decent -80dB attentuation */
35
36
37
38
/*-------------------------------------------------------------------------*/
#define sum_d(v,dx) ((int) v[CH(dx)] + v[CH(1-dx)])
static Sint16* Suffix(doubleRate)( Sint16 *outp, Sint16 *inp, int length,
VarFilter* filt, RateAux* aux )
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
72
return outp;
73
}
74
#undef sum_d
75
76
/*-------------------------------------------------------------------------*/
77
#define sum_h(v,dx) ((int) v[CH(dx)] + v[CH(-dx)])
78
static Sint16* Suffix(halfRate)( Sint16 *outp, Sint16 *inp, int length,
79
VarFilter* filt, RateAux* aux )
80
{
81
int out;
82
Sint16* to;
83
84
to = inp + length;
85
inp += aux->carry;
86
87
while( inp < to )
88
{
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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);
104
out-= 6764 * sum_h( inp, 3);
105
106
107
out+= 20798 * sum_h( inp, 1);
out+= 32770 * (int)inp[0];
108
outp[0] = out >> 16;
109
110
inp += CH(2);
111
outp += CH(1);
112
}
113
114
aux->carry = inp < to + CH(1) ? 0 : CH(1);
115
return outp;
116
}
117
#undef sum_h
118
119
120
/*-------------------------------------------------------------------------*/
static Sint16* Suffix(increaseRate)( Sint16 *outp, Sint16 *inp, int length,
121
VarFilter* filter, RateAux* aux )
122
{
123
const static int fsize = CH(2*_fsize);
124
Sint16 *f;
125
126
127
int out;
int i, pos;
Sint16* to;
128
129
130
inp -= fsize;
to = inp - length;
131
pos = aux->pos;
132
133
while( inp > to )
134
{
135
out = 0;
136
f = filter->c[pos];
137
for( i = _fsize + 1; --i; inp+=CH(4), f+=4 )
138
139
{
out+= f[0] * (int)inp[CH(0)];
140
141
142
out+= f[1] * (int)inp[CH(1)];
out+= f[2] * (int)inp[CH(2)];
out+= f[3] * (int)inp[CH(3)];
143
}
144
outp[0] = out >> 16;
145
146
147
148
pos = ( pos + filter->ratio.denominator - 1 )
% filter->ratio.denominator;
inp -= CH( 4 * _fsize );
149
inp -= CH( filter->incr[pos] );
150
outp -= CH(1);
151
}
152
153
aux->pos = pos;
154
return outp;
155
156
}
157
158
/*-------------------------------------------------------------------------*/
static Sint16* Suffix(decreaseRate)( Sint16 *outp, Sint16 *inp, int length,
159
VarFilter* filter, RateAux* aux )
160
{
161
const static int fsize = CH(2*_fsize);
162
Sint16 *f;
163
164
165
int out;
int i, pos;
Sint16 *to;
166
167
168
inp -= fsize;
to = inp + length;
169
170
pos = aux->pos;
inp += aux->carry;
171
172
while( inp < to )
173
{
174
out = 0;
175
176
177
178
179
180
181
182
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)];
}
183
184
outp[0] = out >> 16;
185
186
inp -= CH( 4 * _fsize );
inp += CH( filter->incr[pos] );
187
outp += CH(1);
188
pos = ( pos + 1 ) % filter->ratio.denominator;
189
}
190
191
192
aux->pos = pos;
aux->carry = inp < to + CH(1) ? 0 : CH(1);
193
return outp;
194
}
195
196
/*-------------------------------------------------------------------------*/
197
198
#undef CH
#endif /* Suffix */
199