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#ifndef R8BUTIL_INCLUDED
17#define R8BUTIL_INCLUDED
18
19#include "r8bbase.h"
20
21namespace r8b {
22
30inline double convertResponseToLog( const double re, const double im )
31{
32 return( 4.34294481903251828 * log( re * re + im * im + 1e-100 ));
33}
34
49inline void updateScanStep( double& step, const double curg,
50 double& prevg_log, const double prec, const double maxstep,
51 const double minstep = 1e-11 )
52{
53 double curg_log = 4.34294481903251828 * log( curg + 1e-100 );
54 curg_log += ( prevg_log - curg_log ) * 0.7;
55
56 const double slope = fabs( curg_log - prevg_log );
57 prevg_log = curg_log;
58
59 if( slope > 0.0 )
60 {
61 step /= prec * slope;
62 step = max( min( step, maxstep ), minstep );
63 }
64}
65
84inline void findFIRFilterResponseMinLtoR( const double* const flt,
85 const int fltlen, double& ming, double& minth, const double thend )
86{
87 const double maxstep = minth * 2e-3;
88 double curth = minth;
89 double re;
90 double im;
91 calcFIRFilterResponse( flt, fltlen, R8B_PI * curth, re, im );
92 double prevg_log = convertResponseToLog( re, im );
93 double step = 1e-11;
94
95 while( true )
96 {
97 curth += step;
98
99 if( curth > thend )
100 {
101 break;
102 }
103
104 calcFIRFilterResponse( flt, fltlen, R8B_PI * curth, re, im );
105 const double curg = re * re + im * im;
106
107 if( curg > ming )
108 {
109 ming = curg;
110 minth = curth;
111 break;
112 }
113
114 ming = curg;
115 minth = curth;
116
117 updateScanStep( step, curg, prevg_log, 0.31, maxstep );
118 }
119}
120
140inline void findFIRFilterResponseMaxLtoR( const double* const flt,
141 const int fltlen, double& maxg, double& maxth, const double thend )
142{
143 const double maxstep = maxth * 1e-4;
144 double premaxth = maxth;
145 double premaxg = maxg;
146 double postmaxth = maxth;
147 double postmaxg = maxg;
148
149 double prevth = maxth;
150 double prevg = maxg;
151 double curth = maxth;
152 double re;
153 double im;
154 calcFIRFilterResponse( flt, fltlen, R8B_PI * curth, re, im );
155 double prevg_log = convertResponseToLog( re, im );
156 double step = 1e-11;
157
158 bool WasPeak = false;
159 int AfterPeakCount = 0;
160
161 while( true )
162 {
163 curth += step;
164
165 if( curth > thend )
166 {
167 break;
168 }
169
170 calcFIRFilterResponse( flt, fltlen, R8B_PI * curth, re, im );
171 const double curg = re * re + im * im;
172
173 if( curg > maxg )
174 {
175 premaxth = prevth;
176 premaxg = prevg;
177 maxg = curg;
178 maxth = curth;
179 WasPeak = true;
180 AfterPeakCount = 0;
181 }
182 else
183 if( WasPeak )
184 {
185 if( AfterPeakCount == 0 )
186 {
187 postmaxth = curth;
188 postmaxg = curg;
189 }
190
191 if( AfterPeakCount == 5 )
192 {
193 // Perform 2 approximate binary searches.
194
195 int k;
196
197 for( k = 0; k < 2; k++ )
198 {
199 double l = ( k == 0 ? premaxth : maxth );
200 double curgl = ( k == 0 ? premaxg : maxg );
201 double r = ( k == 0 ? maxth : postmaxth );
202 double curgr = ( k == 0 ? maxg : postmaxg );
203
204 while( true )
205 {
206 const double c = ( l + r ) * 0.5;
207 calcFIRFilterResponse( flt, fltlen, R8B_PI * c,
208 re, im );
209
210 const double curg = re * re + im * im;
211
212 if( curgl > curgr )
213 {
214 r = c;
215 curgr = curg;
216 }
217 else
218 {
219 l = c;
220 curgl = curg;
221 }
222
223 if( r - l < 1e-11 )
224 {
225 if( curgl > curgr )
226 {
227 maxth = l;
228 maxg = curgl;
229 }
230 else
231 {
232 maxth = r;
233 maxg = curgr;
234 }
235
236 break;
237 }
238 }
239 }
240
241 break;
242 }
243
244 AfterPeakCount++;
245 }
246
247 prevth = curth;
248 prevg = curg;
249
250 updateScanStep( step, curg, prevg_log, 1.0, maxstep );
251 }
252}
253
270inline void findFIRFilterResponseLevelRtoL( const double* const flt,
271 const int fltlen, const double maxg, double& th, const double thend )
272{
273 // Perform exact binary search.
274
275 double l = thend;
276 double r = th;
277
278 while( true )
279 {
280 const double c = ( l + r ) * 0.5;
281
282 if( r - l < 1e-14 )
283 {
284 th = c;
285 break;
286 }
287
288 double re;
289 double im;
290 calcFIRFilterResponse( flt, fltlen, R8B_PI * c, re, im );
291 const double curg = re * re + im * im;
292
293 if( curg > maxg )
294 {
295 l = c;
296 }
297 else
298 {
299 r = c;
300 }
301 }
302}
303
304} // namespace r8b
305
306#endif // R8BUTIL_INCLUDED
The "base" inclusion file with basic classes and functions.
#define R8B_PI
Definition: r8bbase.h:119
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21
void findFIRFilterResponseMaxLtoR(const double *const flt, const int fltlen, double &maxg, double &maxth, const double thend)
Definition: r8butil.h:140
double convertResponseToLog(const double re, const double im)
Definition: r8butil.h:30
void calcFIRFilterResponse(const double *flt, int fltlen, const double th, double &re0, double &im0, const int fltlat=0)
Definition: r8bbase.h:817
void findFIRFilterResponseLevelRtoL(const double *const flt, const int fltlen, const double maxg, double &th, const double thend)
Definition: r8butil.h:270
T min(const T &v1, const T &v2)
Definition: r8bbase.h:1063
T max(const T &v1, const T &v2)
Definition: r8bbase.h:1080
void updateScanStep(double &step, const double curg, double &prevg_log, const double prec, const double maxstep, const double minstep=1e-11)
Definition: r8butil.h:49
void findFIRFilterResponseMinLtoR(const double *const flt, const int fltlen, double &ming, double &minth, const double thend)
Definition: r8butil.h:84