r8brain-free-src
High-quality pro audio sample rate converter library
 
Loading...
Searching...
No Matches
CDSPFIRFilter.h
Go to the documentation of this file.
1//$ nobt
2//$ nocpp
3
15
16#ifndef R8B_CDSPFIRFILTER_INCLUDED
17#define R8B_CDSPFIRFILTER_INCLUDED
18
19#include "CDSPSincFilterGen.h"
20#include "CDSPRealFFT.h"
21
22namespace r8b {
23
27
48
57
58class CDSPFIRFilter : public R8B_BASECLASS
59{
60 R8BNOCTOR( CDSPFIRFilter )
61
62 friend class CDSPFIRFilterCache;
63
64public:
65 ~CDSPFIRFilter()
66 {
67 R8BASSERT( RefCount == 0 );
68
69 delete Next;
70 }
71
76
77 static double getLPMinTransBand()
78 {
79 return( 0.5 );
80 }
81
86
87 static double getLPMaxTransBand()
88 {
89 return( 45.0 );
90 }
91
96
97 static double getLPMinAtten()
98 {
99 return( 49.0 );
100 }
101
106
107 static double getLPMaxAtten()
108 {
109 return( 218.0 );
110 }
111
116
117 bool isZeroPhase() const
118 {
119 return( IsZeroPhase );
120 }
121
125
126 int getLatency() const
127 {
128 return( Latency );
129 }
130
135
136 double getLatencyFrac() const
137 {
138 return( LatencyFrac );
139 }
140
145
146 int getKernelLen() const
147 {
148 return( KernelLen );
149 }
150
155
156 int getBlockLenBits() const
157 {
158 return( BlockLenBits );
159 }
160
170
171 const double* getKernelBlock() const
172 {
173 return( KernelBlock );
174 }
175
182
183 void unref();
184
185private:
186 double ReqNormFreq;
187 double ReqTransBand;
189 double ReqAtten;
191 EDSPFilterPhaseResponse ReqPhase;
192 double ReqGain;
193 CDSPFIRFilter* Next;
194 int RefCount;
195 bool IsZeroPhase;
197 int Latency;
198 double LatencyFrac;
199 int KernelLen;
200 int BlockLenBits;
203 CFixedBuffer< double > KernelBlock;
207
209 : RefCount( 1 )
210 {
211 }
212
219
220 void buildLPFilter( const double* const ExtAttenCorrs )
221 {
222 const double tb = ReqTransBand * 0.01;
223 double pwr;
224 double fo1;
225 double hl;
226 double atten = -ReqAtten;
227
228 if( tb >= 0.25 )
229 {
230 if( ReqAtten >= 117.0 )
231 {
232 atten -= 1.60;
233 }
234 else
235 if( ReqAtten >= 60.0 )
236 {
237 atten -= 1.91;
238 }
239 else
240 {
241 atten -= 2.25;
242 }
243 }
244 else
245 if( tb >= 0.10 )
246 {
247 if( ReqAtten >= 117.0 )
248 {
249 atten -= 0.69;
250 }
251 else
252 if( ReqAtten >= 60.0 )
253 {
254 atten -= 0.73;
255 }
256 else
257 {
258 atten -= 1.13;
259 }
260 }
261 else
262 {
263 if( ReqAtten >= 117.0 )
264 {
265 atten -= 0.21;
266 }
267 else
268 if( ReqAtten >= 60.0 )
269 {
270 atten -= 0.25;
271 }
272 else
273 {
274 atten -= 0.36;
275 }
276 }
277
278 static const int AttenCorrCount = 264;
279 static const double AttenCorrMin = 49.0;
280 static const double AttenCorrDiff = 176.25;
281 int AttenCorr = (int) floor(( -atten - AttenCorrMin ) *
282 AttenCorrCount / AttenCorrDiff + 0.5 );
283
284 AttenCorr = min( AttenCorrCount, max( 0, AttenCorr ));
285
286 if( ExtAttenCorrs != R8B_NULL )
287 {
288 atten -= ExtAttenCorrs[ AttenCorr ];
289 }
290 else
291 if( tb >= 0.25 )
292 {
293 static const double AttenCorrScale = 101.0;
294 static const signed char AttenCorrs[] = {
295 -127, -127, -125, -125, -122, -119, -115, -110, -104, -97,
296 -91, -82, -75, -24, -16, -6, 4, 14, 24, 29, 30, 32, 37, 44,
297 51, 57, 63, 67, 65, 50, 53, 56, 58, 60, 63, 64, 66, 68, 74,
298 77, 78, 78, 78, 79, 79, 60, 60, 60, 61, 59, 52, 47, 41, 36,
299 30, 24, 17, 9, 0, -8, -10, -11, -14, -13, -18, -25, -31, -38,
300 -44, -50, -57, -63, -68, -74, -81, -89, -96, -101, -104, -107,
301 -109, -110, -86, -84, -85, -82, -80, -77, -73, -67, -62, -55,
302 -48, -42, -35, -30, -20, -11, -2, 5, 6, 6, 7, 11, 16, 21, 26,
303 34, 41, 46, 49, 52, 55, 56, 48, 49, 51, 51, 52, 52, 52, 52,
304 52, 51, 51, 50, 47, 47, 50, 48, 46, 42, 38, 35, 31, 27, 24,
305 20, 16, 12, 11, 12, 10, 8, 4, -1, -6, -11, -16, -19, -17, -21,
306 -24, -27, -32, -34, -37, -38, -40, -41, -40, -40, -42, -41,
307 -44, -45, -43, -41, -34, -31, -28, -24, -21, -18, -14, -10,
308 -5, -1, 2, 5, 8, 7, 4, 3, 2, 2, 4, 6, 8, 9, 9, 10, 10, 10, 10,
309 9, 8, 9, 11, 14, 13, 12, 11, 10, 8, 7, 6, 5, 3, 2, 2, -1, -1,
310 -3, -3, -4, -4, -5, -4, -6, -7, -9, -5, -1, -1, 0, 1, 0, -2,
311 -3, -4, -5, -5, -8, -13, -13, -13, -12, -13, -12, -11, -11,
312 -9, -8, -7, -5, -3, -1, 2, 4, 6, 9, 10, 11, 14, 18, 21, 24,
313 27, 30, 34, 37, 37, 39, 40 };
314
315 atten -= AttenCorrs[ AttenCorr ] / AttenCorrScale;
316 }
317 else
318 if( tb >= 0.10 )
319 {
320 static const double AttenCorrScale = 210.0;
321 static const signed char AttenCorrs[] = {
322 -113, -118, -122, -125, -126, -97, -95, -92, -92, -89, -82,
323 -75, -69, -48, -42, -36, -30, -22, -14, -5, -2, 1, 6, 13, 22,
324 28, 35, 41, 48, 55, 56, 56, 61, 65, 71, 77, 81, 83, 85, 85,
325 74, 74, 73, 72, 71, 70, 68, 64, 59, 56, 49, 52, 46, 42, 36,
326 32, 26, 20, 13, 7, -2, -6, -10, -15, -20, -27, -33, -38, -44,
327 -43, -48, -53, -57, -63, -69, -73, -75, -79, -81, -74, -76,
328 -77, -77, -78, -81, -80, -80, -78, -76, -65, -62, -59, -56,
329 -51, -48, -44, -38, -33, -25, -19, -13, -5, -1, 2, 7, 13, 17,
330 21, 25, 30, 35, 40, 45, 50, 53, 56, 57, 55, 58, 59, 62, 64,
331 67, 67, 68, 68, 62, 61, 61, 59, 59, 57, 57, 55, 52, 48, 42,
332 38, 35, 31, 26, 20, 15, 13, 10, 7, 3, -2, -8, -13, -17, -23,
333 -28, -34, -37, -40, -41, -45, -48, -50, -53, -57, -59, -62,
334 -63, -63, -57, -57, -56, -56, -54, -54, -53, -49, -48, -41,
335 -38, -33, -31, -26, -23, -18, -12, -9, -7, -7, -3, 0, 5, 9,
336 14, 16, 20, 22, 21, 23, 25, 27, 28, 29, 34, 33, 35, 33, 31,
337 30, 29, 29, 26, 26, 25, 24, 20, 19, 15, 10, 8, 4, 1, -2, -6,
338 -10, -16, -19, -23, -26, -27, -30, -34, -39, -43, -47, -51,
339 -52, -54, -56, -58, -59, -62, -63, -66, -65, -65, -64, -59,
340 -57, -54, -52, -48, -44, -42, -37, -32, -22, -17, -10, -3, 5,
341 13, 22, 30, 40, 50, 60, 72 };
342
343 atten -= AttenCorrs[ AttenCorr ] / AttenCorrScale;
344 }
345 else
346 {
347 static const double AttenCorrScale = 196.0;
348 static const signed char AttenCorrs[] = {
349 -15, -17, -20, -20, -20, -21, -20, -16, -17, -18, -17, -13,
350 -12, -11, -9, -7, -5, -4, -1, 1, 3, 4, 5, 6, 7, 9, 9, 10, 10,
351 10, 11, 11, 11, 12, 12, 12, 10, 11, 10, 10, 8, 10, 11, 10, 11,
352 11, 13, 14, 15, 19, 27, 26, 23, 18, 14, 8, 4, -2, -6, -12,
353 -17, -23, -28, -33, -37, -42, -46, -49, -53, -57, -60, -61,
354 -64, -65, -67, -66, -66, -66, -65, -64, -61, -59, -56, -52,
355 -48, -42, -38, -31, -27, -19, -13, -7, -1, 8, 14, 22, 29, 37,
356 45, 52, 59, 66, 73, 80, 86, 91, 96, 100, 104, 108, 111, 114,
357 115, 117, 118, 120, 120, 118, 117, 114, 113, 111, 107, 103,
358 99, 95, 89, 84, 78, 72, 66, 60, 52, 44, 37, 30, 21, 14, 6, -3,
359 -11, -18, -26, -34, -43, -51, -58, -65, -73, -78, -85, -90,
360 -97, -102, -107, -113, -115, -118, -121, -125, -125, -126,
361 -126, -126, -125, -124, -121, -119, -115, -111, -109, -101,
362 -102, -95, -88, -81, -73, -67, -63, -54, -47, -40, -33, -26,
363 -18, -11, -5, 2, 8, 14, 19, 25, 31, 36, 37, 43, 47, 49, 51,
364 52, 57, 57, 56, 57, 58, 58, 58, 57, 56, 52, 52, 50, 48, 44,
365 41, 39, 37, 33, 31, 26, 24, 21, 18, 14, 11, 8, 4, 2, -2, -5,
366 -7, -9, -11, -13, -15, -16, -18, -19, -20, -23, -24, -24, -25,
367 -27, -26, -27, -29, -30, -31, -32, -35, -36, -39, -40, -44,
368 -46, -51, -54, -59, -63, -69, -76, -83, -91, -98 };
369
370 atten -= AttenCorrs[ AttenCorr ] / AttenCorrScale;
371 }
372
373 pwr = 7.43932822146293e-8 * sqr( atten ) + 0.000102747434588003 *
374 cos( 0.00785021930010397 * atten ) * cos( 0.633854318781239 +
375 0.103208573657699 * atten ) - 0.00798132247867036 -
376 0.000903555213543865 * atten - 0.0969365532127236 * exp(
377 0.0779275237937911 * atten ) - 1.37304948662012e-5 * atten * cos(
378 0.00785021930010397 * atten );
379
380 if( pwr <= 0.067665322581 )
381 {
382 if( tb >= 0.25 )
383 {
384 hl = 2.6778150875894 / tb + 300.547590563091 * atan( atan(
385 2.68959772209918 * pwr )) / ( 5.5099277187035 * tb - tb *
386 tanh( cos( asinh( atten ))));
387
388 fo1 = 0.987205355829873 * tb + 1.00011788929851 * atan2(
389 -0.321432067051302 - 6.19131357321578 * sqrt( pwr ),
390 hl + -1.14861472207245 / ( hl - 14.1821147585957 ) + pow(
391 0.9521145021664, pow( atan2( 1.12018764830637, tb ),
392 2.10988901686912 * hl - 20.9691278378345 )));
393 }
394 else
395 if( tb >= 0.10 )
396 {
397 hl = ( 1.56688617018066 + 142.064321294568 * pwr +
398 0.00419441117131136 * cos( 243.633511747297 * pwr ) -
399 0.022953443903576 * atten - 0.026629568860284 * cos(
400 127.715550622571 * pwr )) / tb;
401
402 fo1 = 0.982299356642411 * tb + 0.999441744774215 * asinh((
403 -0.361783054039583 - 5.80540593623676 * sqrt( pwr )) /
404 hl );
405 }
406 else
407 {
408 hl = ( 2.45739657014937 + 269.183679500541 * pwr * cos(
409 5.73225668178813 + atan2( cosh( 0.988861169868941 -
410 17.2201556280744 * pwr ), 1.08340138240431 * pwr ))) / tb;
411
412 fo1 = 2.291956939 * tb + 0.01942450693 * sqr( tb ) * hl -
413 4.67538973161837 * pwr * tb - 1.668433124 * tb *
414 pow( pwr, pwr );
415 }
416 }
417 else
418 {
419 if( tb >= 0.25 )
420 {
421 hl = ( 1.50258368698213 + 158.556968859477 * asinh( pwr ) *
422 tanh( 57.9466246871383 * tanh( pwr )) -
423 0.0105440479814834 * atten ) / tb;
424
425 fo1 = 0.994024401639321 * tb + ( -0.236282717577215 -
426 6.8724924545387 * sqrt( sin( pwr ))) / hl;
427 }
428 else
429 if( tb >= 0.10 )
430 {
431 hl = ( 1.50277377248945 + 158.222625721046 * asinh( pwr ) *
432 tanh( 1.02875299001715 + 42.072277322604 * pwr ) -
433 0.0108380943845632 * atten ) / tb;
434
435 fo1 = 0.992539376734551 * tb + ( -0.251747813037178 -
436 6.74159892452584 * sqrt( tanh( tanh( tan( pwr ))))) / hl;
437 }
438 else
439 {
440 hl = ( 1.15990238966306 * pwr - 5.02124037125213 * sqr(
441 pwr ) - 0.158676856669827 * atten * cos( 1.1609073390614 *
442 pwr - 6.33932586197475 * pwr * sqr( pwr ))) / tb;
443
444 fo1 = 0.867344453126885 * tb + 0.052693817907757 * tb * log(
445 pwr ) + 0.0895511178735932 * tb * atan( 59.7538527741309 *
446 pwr ) - 0.0745653568081453 * pwr * tb;
447 }
448 }
449
450 double WinParams[ 2 ];
451 WinParams[ 0 ] = 125.0;
452 WinParams[ 1 ] = pwr;
453
454 CDSPSincFilterGen sinc;
455 sinc.Len2 = 0.25 * hl / ReqNormFreq;
456 sinc.Freq1 = 0.0;
457 sinc.Freq2 = R8B_PI * ( 1.0 - fo1 ) * ReqNormFreq;
458 sinc.initBand( CDSPSincFilterGen :: wftKaiser, WinParams, true );
459
460 KernelLen = sinc.KernelLen;
461 BlockLenBits = getBitOccupancy( KernelLen - 1 ) + R8B_EXTFFT;
462 const int BlockLen = 1 << BlockLenBits;
463
464 KernelBlock.alloc( BlockLen * 2 );
465 sinc.generateBand( &KernelBlock[ 0 ],
466 &CDSPSincFilterGen :: calcWindowKaiser );
467
468 if( ReqPhase == fprLinearPhase )
469 {
470 IsZeroPhase = true;
471 Latency = sinc.fl2;
472 LatencyFrac = 0.0;
473 }
474 else
475 {
476 IsZeroPhase = false;
477 double DCGroupDelay;
478
479 calcMinPhaseTransform( &KernelBlock[ 0 ], KernelLen, 16, false,
480 &DCGroupDelay );
481
482 Latency = (int) DCGroupDelay;
483 LatencyFrac = DCGroupDelay - Latency;
484 }
485
486 CDSPRealFFTKeeper ffto( BlockLenBits + 1 );
487
488 if( IsZeroPhase )
489 {
490 // Calculate DC gain.
491
492 double s = 0.0;
493 int i;
494
495 for( i = 0; i < KernelLen; i++ )
496 {
497 s += KernelBlock[ i ];
498 }
499
500 s = ffto -> getInvMulConst() * ReqGain / s;
501
502 // Time-shift the filter so that zero-phase response is produced.
503 // Simultaneously multiply by "s".
504
505 for( i = 0; i <= sinc.fl2; i++ )
506 {
507 KernelBlock[ i ] = KernelBlock[ sinc.fl2 + i ] * s;
508 }
509
510 for( i = 1; i <= sinc.fl2; i++ )
511 {
512 KernelBlock[ BlockLen * 2 - i ] = KernelBlock[ i ];
513 }
514
515 memset( &KernelBlock[ sinc.fl2 + 1 ], 0,
516 (size_t) ( BlockLen * 2 - KernelLen ) *
517 sizeof( KernelBlock[ 0 ]));
518
519 ffto -> forward( KernelBlock );
520 ffto -> convertToZP( KernelBlock );
521 }
522 else
523 {
524 normalizeFIRFilter( &KernelBlock[ 0 ], KernelLen,
525 ffto -> getInvMulConst() * ReqGain );
526
527 memset( &KernelBlock[ KernelLen ], 0,
528 (size_t) ( BlockLen * 2 - KernelLen ) *
529 sizeof( KernelBlock[ 0 ]));
530
531 ffto -> forward( KernelBlock );
532 }
533
534 R8BCONSOLE( "CDSPFIRFilter: flt_len=%i latency=%i nfreq=%.4f "
535 "tb=%.1f att=%.1f gain=%.3f\n", KernelLen, Latency,
536 ReqNormFreq, ReqTransBand, ReqAtten, ReqGain );
537 }
538};
539
546
548{
550
551 friend class CDSPFIRFilter;
552
553public:
558
559 static int getObjCount()
560 {
562
563 return( getObjCountStatic() );
564 }
565
597
598 static CDSPFIRFilter& getLPFilter( const double ReqNormFreq,
599 const double ReqTransBand, const double ReqAtten,
600 const EDSPFilterPhaseResponse ReqPhase, const double ReqGain,
601 const double* const AttenCorrs = R8B_NULL )
602 {
603 R8BASSERT( ReqNormFreq > 0.0 && ReqNormFreq <= 1.0 );
604 R8BASSERT( ReqTransBand >= CDSPFIRFilter :: getLPMinTransBand() );
605 R8BASSERT( ReqTransBand <= CDSPFIRFilter :: getLPMaxTransBand() );
606 R8BASSERT( ReqAtten >= CDSPFIRFilter :: getLPMinAtten() );
607 R8BASSERT( ReqAtten <= CDSPFIRFilter :: getLPMaxAtten() );
608 R8BASSERT( ReqGain > 0.0 );
609
610 R8B_EXITDTOR static CPtrKeeper< CDSPFIRFilter > Objects; // The chain
611 // of cached objects.
612
614
615 int& ObjCount = getObjCountStatic();
616 CDSPFIRFilter* PrevObj = R8B_NULL;
617 CDSPFIRFilter* CurObj = Objects;
618
619 while( CurObj != R8B_NULL )
620 {
621 if( CurObj -> ReqNormFreq == ReqNormFreq &&
622 CurObj -> ReqTransBand == ReqTransBand &&
623 CurObj -> ReqGain == ReqGain &&
624 CurObj -> ReqAtten == ReqAtten &&
625 CurObj -> ReqPhase == ReqPhase )
626 {
627 break;
628 }
629
630 if( CurObj -> Next == R8B_NULL &&
631 ObjCount >= R8B_FILTER_CACHE_MAX )
632 {
633 if( CurObj -> RefCount == 0 )
634 {
635 // Delete the last filter which is not used.
636
637 PrevObj -> Next = R8B_NULL;
638 delete CurObj;
639 ObjCount--;
640 }
641 else
642 {
643 // Move the last filter to the top of the list since it
644 // seems to be in use for a long time.
645
646 PrevObj -> Next = R8B_NULL;
647 CurObj -> Next = Objects.unkeep();
648 Objects = CurObj;
649 }
650
651 CurObj = R8B_NULL;
652 break;
653 }
654
655 PrevObj = CurObj;
656 CurObj = CurObj -> Next;
657 }
658
659 if( CurObj != R8B_NULL )
660 {
661 CurObj -> RefCount++;
662
663 if( PrevObj == R8B_NULL )
664 {
665 return( *CurObj );
666 }
667
668 // Remove the filter from the list temporarily.
669
670 PrevObj -> Next = CurObj -> Next;
671 }
672 else
673 {
674 // Create a new filter object (with RefCount == 1) and build the
675 // filter kernel.
676
677 CurObj = new CDSPFIRFilter();
678 CurObj -> ReqNormFreq = ReqNormFreq;
679 CurObj -> ReqTransBand = ReqTransBand;
680 CurObj -> ReqAtten = ReqAtten;
681 CurObj -> ReqPhase = ReqPhase;
682 CurObj -> ReqGain = ReqGain;
683 ObjCount++;
684
685 CurObj -> buildLPFilter( AttenCorrs );
686 }
687
688 // Insert the filter at the start of the list.
689
690 CurObj -> Next = Objects.unkeep();
691 Objects = CurObj;
692
693 return( *CurObj );
694 }
695
696protected:
700
702 {
703 R8B_EXITDTOR static CSyncObject StateSync;
704
705 return( StateSync );
706 }
707
711
712 static int& getObjCountStatic()
713 {
714 R8B_EXITDTOR static int ObjCount = 0; // The number of objects
715 // currently preset in the cache.
716
717 return( ObjCount );
718 }
719};
720
721// ---------------------------------------------------------------------------
722// CDSPFIRFilter PUBLIC
723// ---------------------------------------------------------------------------
724
725inline void CDSPFIRFilter :: unref()
726{
727 R8BSYNC( CDSPFIRFilterCache :: getStateSync() );
728
729 RefCount--;
730}
731
732// ---------------------------------------------------------------------------
733
734} // namespace r8b
735
736#endif // R8B_CDSPFIRFILTER_INCLUDED
Real-valued FFT transform class.
Sinc function-based FIR filter generator class.
#define R8BSYNC(SyncObject)
Thread synchronization macro.
Definition r8bbase.h:655
#define R8B_EXITDTOR
Macro that defines the attribute specifying that the exit-time destructor should be called for a stat...
Definition r8bbase.h:149
#define R8B_NULL
The "null pointer" value, portable between C++11 and earlier C++ versions.
Definition r8bbase.h:101
#define R8BNOCTOR(ClassName)
Macro that defines empty copy-constructor and copy operator with the "private:" prefix.
Definition r8bbase.h:198
#define R8B_EXTFFT
This macro, when equal to 1, extends length of low-pass filters' FFT block by a factor of 2,...
Definition r8bconf.h:146
#define R8BASSERT(e)
Assertion macro used to check for certain run-time conditions. By default, no action is taken if asse...
Definition r8bconf.h:28
#define R8B_BASECLASS
Macro defines the name of the class from which all classes that are designed to be created on heap ar...
Definition r8bconf.h:56
#define R8BCONSOLE(...)
Console output macro, used to output various resampler status strings, including filter design parame...
Definition r8bconf.h:41
#define R8B_FILTER_CACHE_MAX
Macro specifies the number of filters kept in the cache at most.
Definition r8bconf.h:90
The "r8brain-free-src" library namespace.
Definition CDSPBlockConvolver.h:22
R8B_CONST double R8B_PI
Equals pi.
Definition r8bbase.h:179
EDSPFilterPhaseResponse
Enumeration of filter's phase responses.
Definition CDSPFIRFilter.h:29
@ fprMinPhase
Minimum-phase response. Features a minimal-latency response, but the response's phase is non-linear....
Definition CDSPFIRFilter.h:33
@ fprLinearPhase
Linear-phase response. Features a linear-phase, high-latency response, with the latency expressed as ...
Definition CDSPFIRFilter.h:30
T min(const T &v1, const T &v2)
Returns minimum of two values.
Definition r8bbase.h:1079
int getBitOccupancy(const int v)
Calculate the exact number of bits a value needs for representation.
Definition r8bbase.h:766
double asinh(const double v)
Hyperbolic sine of a value.
Definition r8bbase.h:1178
void calcMinPhaseTransform(double *const Kernel, const int KernelLen, const int LenMult=2, const bool DoFinalMul=true, double *const DCGroupDelay=R8B_NULL)
Calculates the minimum-phase transform of the filter kernel, using a discrete Hilbert transform in ce...
Definition CDSPRealFFT.h:681
T max(const T &v1, const T &v2)
Returns maximum of two values.
Definition r8bbase.h:1098
void normalizeFIRFilter(double *const p, const int l, const double DCGain, const int pstep=1)
FIR filter's gain normalization.
Definition r8bbase.h:934
double sqr(const double x)
Returns square ot a value.
Definition r8bbase.h:1140
Calculation and storage class for FIR filters.
Definition CDSPFIRFilter.h:59
int getBlockLenBits() const
Returns filter's block length, expressed as Nth power of 2. The actual length is twice as large due t...
Definition CDSPFIRFilter.h:156
int getLatency() const
Returns filter's latency, in samples (integer part).
Definition CDSPFIRFilter.h:126
static double getLPMaxTransBand()
Returns the maximal allowed low-pass filter's transition band, in percent.
Definition CDSPFIRFilter.h:87
void unref()
Reduces reference count to this object.
Definition CDSPFIRFilter.h:725
double getLatencyFrac() const
Returns filter's latency, in samples (fractional part). Always zero for linear-phase filters.
Definition CDSPFIRFilter.h:136
static double getLPMinAtten()
Returns the minimal allowed low-pass filter's stop-band attenuation, in decibel.
Definition CDSPFIRFilter.h:97
int getKernelLen() const
Returns filter kernel length, in samples. Not to be confused with the block length.
Definition CDSPFIRFilter.h:146
const double * getKernelBlock() const
Returns pointer to filter's kernel block, in complex-numbered form obtained via the CDSPRealFFT::forw...
Definition CDSPFIRFilter.h:171
static double getLPMaxAtten()
Returns the maximal allowed low-pass filter's stop-band attenuation, in decibel.
Definition CDSPFIRFilter.h:107
static double getLPMinTransBand()
Returns the minimal allowed low-pass filter's transition band, in percent.
Definition CDSPFIRFilter.h:77
bool isZeroPhase() const
Returns true if kernel block of this filter has zero-phase response.
Definition CDSPFIRFilter.h:117
FIR filter cache class.
Definition CDSPFIRFilter.h:548
static CDSPFIRFilter & getLPFilter(const double ReqNormFreq, const double ReqTransBand, const double ReqAtten, const EDSPFilterPhaseResponse ReqPhase, const double ReqGain, const double *const AttenCorrs=R8B_NULL)
Calculates or returns reference to a previously calculated (cached) low-pass FIR filter.
Definition CDSPFIRFilter.h:598
static int getObjCount()
Returns the number of filters present in the cache now. This value can be monitored for debugging "fo...
Definition CDSPFIRFilter.h:559
static int & getObjCountStatic()
Returns reference to variable containing cache object count.
Definition CDSPFIRFilter.h:712
static CSyncObject & getStateSync()
Returns reference to filter cache sync object.
Definition CDSPFIRFilter.h:701
Pointer-to-object "keeper" class with automatic deletion.
Definition r8bbase.h:405
Multi-threaded synchronization object class.
Definition r8bbase.h:513