r8brain-free-src
High-quality pro audio sample rate converter library
 
Loading...
Searching...
No Matches
r8butil.h
Go to the documentation of this file.
1//$ nobt
2//$ nocpp
3
16
17#ifndef R8BUTIL_INCLUDED
18#define R8BUTIL_INCLUDED
19
20#include "r8bbase.h"
21
22namespace r8b {
23
32
33inline double convertResponseToLog( const double re, const double im )
34{
35 return( 4.34294481903251828 * log( re * re + im * im + 1e-100 ));
36}
37
51
52inline void updateScanStep( double& step, const double curg,
53 double& prevg_log, const double prec, const double maxstep,
54 const double minstep = 1e-11 )
55{
56 double curg_log = 4.34294481903251828 * log( curg + 1e-100 );
57 curg_log += ( prevg_log - curg_log ) * 0.7;
58
59 const double slope = fabs( curg_log - prevg_log );
60 prevg_log = curg_log;
61
62 if( slope > 0.0 )
63 {
64 step /= prec * slope;
65 step = max( min( step, maxstep ), minstep );
66 }
67}
68
88
89inline void findFIRFilterResponseMinLtoR( const double* const flt,
90 const int fltlen, double& ming, double& minth, const double thend )
91{
92 const double maxstep = minth * 2e-3;
93 double curth = minth;
94 double re;
95 double im;
96 calcFIRFilterResponse( flt, fltlen, R8B_PI * curth, re, im );
97 double prevg_log = convertResponseToLog( re, im );
98 double step = 1e-11;
99
100 while( true )
101 {
102 curth += step;
103
104 if( curth > thend )
105 {
106 break;
107 }
108
109 calcFIRFilterResponse( flt, fltlen, R8B_PI * curth, re, im );
110 const double curg = re * re + im * im;
111
112 if( curg > ming )
113 {
114 ming = curg;
115 minth = curth;
116 break;
117 }
118
119 ming = curg;
120 minth = curth;
121
122 updateScanStep( step, curg, prevg_log, 0.31, maxstep );
123 }
124}
125
146
147inline void findFIRFilterResponseMaxLtoR( const double* const flt,
148 const int fltlen, double& maxg, double& maxth, const double thend )
149{
150 const double maxstep = maxth * 1e-4;
151 double premaxth = maxth;
152 double premaxg = maxg;
153 double postmaxth = maxth;
154 double postmaxg = maxg;
155
156 double prevth = maxth;
157 double prevg = maxg;
158 double curth = maxth;
159 double re;
160 double im;
161 calcFIRFilterResponse( flt, fltlen, R8B_PI * curth, re, im );
162 double prevg_log = convertResponseToLog( re, im );
163 double step = 1e-11;
164
165 bool WasPeak = false;
166 int AfterPeakCount = 0;
167
168 while( true )
169 {
170 curth += step;
171
172 if( curth > thend )
173 {
174 break;
175 }
176
177 calcFIRFilterResponse( flt, fltlen, R8B_PI * curth, re, im );
178 const double curg = re * re + im * im;
179
180 if( curg > maxg )
181 {
182 premaxth = prevth;
183 premaxg = prevg;
184 maxg = curg;
185 maxth = curth;
186 WasPeak = true;
187 AfterPeakCount = 0;
188 }
189 else
190 if( WasPeak )
191 {
192 if( AfterPeakCount == 0 )
193 {
194 postmaxth = curth;
195 postmaxg = curg;
196 }
197
198 if( AfterPeakCount == 5 )
199 {
200 // Perform 2 approximate binary searches.
201
202 int k;
203
204 for( k = 0; k < 2; k++ )
205 {
206 double l = ( k == 0 ? premaxth : maxth );
207 double curgl = ( k == 0 ? premaxg : maxg );
208 double r = ( k == 0 ? maxth : postmaxth );
209 double curgr = ( k == 0 ? maxg : postmaxg );
210
211 while( true )
212 {
213 const double c = ( l + r ) * 0.5;
214 calcFIRFilterResponse( flt, fltlen, R8B_PI * c,
215 re, im );
216
217 const double curg = re * re + im * im;
218
219 if( curgl > curgr )
220 {
221 r = c;
222 curgr = curg;
223 }
224 else
225 {
226 l = c;
227 curgl = curg;
228 }
229
230 if( r - l < 1e-11 )
231 {
232 if( curgl > curgr )
233 {
234 maxth = l;
235 maxg = curgl;
236 }
237 else
238 {
239 maxth = r;
240 maxg = curgr;
241 }
242
243 break;
244 }
245 }
246 }
247
248 break;
249 }
250
251 AfterPeakCount++;
252 }
253
254 prevth = curth;
255 prevg = curg;
256
257 updateScanStep( step, curg, prevg_log, 1.0, maxstep );
258 }
259}
260
278
279inline void findFIRFilterResponseLevelRtoL( const double* const flt,
280 const int fltlen, const double maxg, double& th, const double thend )
281{
282 // Perform exact binary search.
283
284 double l = thend;
285 double r = th;
286
287 while( true )
288 {
289 const double c = ( l + r ) * 0.5;
290
291 if( r - l < 1e-14 )
292 {
293 th = c;
294 break;
295 }
296
297 double re;
298 double im;
299 calcFIRFilterResponse( flt, fltlen, R8B_PI * c, re, im );
300 const double curg = re * re + im * im;
301
302 if( curg > maxg )
303 {
304 l = c;
305 }
306 else
307 {
308 r = c;
309 }
310 }
311}
312
313} // namespace r8b
314
315#endif // R8BUTIL_INCLUDED
The "base" header file with basic classes and functions.
The "r8brain-free-src" library namespace.
Definition CDSPBlockConvolver.h:22
void findFIRFilterResponseMaxLtoR(const double *const flt, const int fltlen, double &maxg, double &maxth, const double thend)
Locates normalized frequency at which the maximal filter gain is reached.
Definition r8butil.h:147
double convertResponseToLog(const double re, const double im)
Converts complex response into magnitude in log scale.
Definition r8butil.h:33
R8B_CONST double R8B_PI
Equals pi.
Definition r8bbase.h:179
void calcFIRFilterResponse(const double *flt, int fltlen, const double th, double &re0, double &im0, const int fltlat=0)
FIR filter's frequency response calculation.
Definition r8bbase.h:819
void findFIRFilterResponseLevelRtoL(const double *const flt, const int fltlen, const double maxg, double &th, const double thend)
Locates normalized frequency at which the specified maximum filter gain is reached.
Definition r8butil.h:279
T min(const T &v1, const T &v2)
Returns minimum of two values.
Definition r8bbase.h:1079
T max(const T &v1, const T &v2)
Returns maximum of two values.
Definition r8bbase.h:1098
void updateScanStep(double &step, const double curg, double &prevg_log, const double prec, const double maxstep, const double minstep=1e-11)
An utility function that performs frequency response scanning step update based on the current magnit...
Definition r8butil.h:52
void findFIRFilterResponseMinLtoR(const double *const flt, const int fltlen, double &ming, double &minth, const double thend)
Locates normalized frequency at which the minimum filter gain is reached.
Definition r8butil.h:89