Flan
CDSPFIRFilter.h
Go to the documentation of this file.
1 //$ nobt
2 //$ nocpp
3 
15 #ifndef R8B_CDSPFIRFILTER_INCLUDED
16 #define R8B_CDSPFIRFILTER_INCLUDED
17 
18 #include "CDSPSincFilterGen.h"
19 #include "CDSPRealFFT.h"
20 
21 namespace r8b {
22 
28 {
34 };
47 
58 {
59  R8BNOCTOR( CDSPFIRFilter );
60 
61  friend class CDSPFIRFilterCache;
62 
63 public:
64  ~CDSPFIRFilter()
65  {
66  R8BASSERT( RefCount == 0 );
67 
68  delete Next;
69  }
70 
76  static double getLPMinTransBand()
77  {
78  return( 0.5 );
79  }
80 
86  static double getLPMaxTransBand()
87  {
88  return( 45.0 );
89  }
90 
96  static double getLPMinAtten()
97  {
98  return( 49.0 );
99  }
100 
106  static double getLPMaxAtten()
107  {
108  return( 218.0 );
109  }
110 
115  bool isZeroPhase() const
116  {
117  return( IsZeroPhase );
118  }
119 
124  int getLatency() const
125  {
126  return( Latency );
127  }
128 
134  double getLatencyFrac() const
135  {
136  return( LatencyFrac );
137  }
138 
144  int getKernelLen() const
145  {
146  return( KernelLen );
147  }
148 
154  int getBlockLenBits() const
155  {
156  return( BlockLenBits );
157  }
158 
167  const double* getKernelBlock() const
168  {
169  return( KernelBlock );
170  }
171 
177  void unref();
178 
179 private:
180  double ReqNormFreq;
181  double ReqTransBand;
183  double ReqAtten;
186  EDSPFilterPhaseResponse ReqPhase;
189  double ReqGain;
191  CDSPFIRFilter* Next;
193  int RefCount;
195  bool IsZeroPhase;
197  int Latency;
200  double LatencyFrac;
202  int KernelLen;
204  int BlockLenBits;
206  CFixedBuffer< double > KernelBlock;
210 
215  CDSPFIRFilter()
216  : RefCount( 1 )
217  {
218  }
219 
227  void buildLPFilter( const double* const ExtAttenCorrs )
228  {
229  const double tb = ReqTransBand * 0.01;
230  double pwr;
231  double fo1;
232  double hl;
233  double atten = -ReqAtten;
234 
235  if( tb >= 0.25 )
236  {
237  if( ReqAtten >= 117.0 )
238  {
239  atten -= 1.60;
240  }
241  else
242  if( ReqAtten >= 60.0 )
243  {
244  atten -= 1.91;
245  }
246  else
247  {
248  atten -= 2.25;
249  }
250  }
251  else
252  if( tb >= 0.10 )
253  {
254  if( ReqAtten >= 117.0 )
255  {
256  atten -= 0.69;
257  }
258  else
259  if( ReqAtten >= 60.0 )
260  {
261  atten -= 0.73;
262  }
263  else
264  {
265  atten -= 1.13;
266  }
267  }
268  else
269  {
270  if( ReqAtten >= 117.0 )
271  {
272  atten -= 0.21;
273  }
274  else
275  if( ReqAtten >= 60.0 )
276  {
277  atten -= 0.25;
278  }
279  else
280  {
281  atten -= 0.36;
282  }
283  }
284 
285  static const int AttenCorrCount = 264;
286  static const double AttenCorrMin = 49.0;
287  static const double AttenCorrDiff = 176.25;
288  int AttenCorr = (int) floor(( -atten - AttenCorrMin ) *
289  AttenCorrCount / AttenCorrDiff + 0.5 );
290 
291  AttenCorr = min( AttenCorrCount, max( 0, AttenCorr ));
292 
293  if( ExtAttenCorrs != NULL )
294  {
295  atten -= ExtAttenCorrs[ AttenCorr ];
296  }
297  else
298  if( tb >= 0.25 )
299  {
300  static const double AttenCorrScale = 101.0;
301  static const signed char AttenCorrs[] = {
302  -127, -127, -125, -125, -122, -119, -115, -110, -104, -97,
303  -91, -82, -75, -24, -16, -6, 4, 14, 24, 29, 30, 32, 37, 44,
304  51, 57, 63, 67, 65, 50, 53, 56, 58, 60, 63, 64, 66, 68, 74,
305  77, 78, 78, 78, 79, 79, 60, 60, 60, 61, 59, 52, 47, 41, 36,
306  30, 24, 17, 9, 0, -8, -10, -11, -14, -13, -18, -25, -31, -38,
307  -44, -50, -57, -63, -68, -74, -81, -89, -96, -101, -104, -107,
308  -109, -110, -86, -84, -85, -82, -80, -77, -73, -67, -62, -55,
309  -48, -42, -35, -30, -20, -11, -2, 5, 6, 6, 7, 11, 16, 21, 26,
310  34, 41, 46, 49, 52, 55, 56, 48, 49, 51, 51, 52, 52, 52, 52,
311  52, 51, 51, 50, 47, 47, 50, 48, 46, 42, 38, 35, 31, 27, 24,
312  20, 16, 12, 11, 12, 10, 8, 4, -1, -6, -11, -16, -19, -17, -21,
313  -24, -27, -32, -34, -37, -38, -40, -41, -40, -40, -42, -41,
314  -44, -45, -43, -41, -34, -31, -28, -24, -21, -18, -14, -10,
315  -5, -1, 2, 5, 8, 7, 4, 3, 2, 2, 4, 6, 8, 9, 9, 10, 10, 10, 10,
316  9, 8, 9, 11, 14, 13, 12, 11, 10, 8, 7, 6, 5, 3, 2, 2, -1, -1,
317  -3, -3, -4, -4, -5, -4, -6, -7, -9, -5, -1, -1, 0, 1, 0, -2,
318  -3, -4, -5, -5, -8, -13, -13, -13, -12, -13, -12, -11, -11,
319  -9, -8, -7, -5, -3, -1, 2, 4, 6, 9, 10, 11, 14, 18, 21, 24,
320  27, 30, 34, 37, 37, 39, 40 };
321 
322  atten -= AttenCorrs[ AttenCorr ] / AttenCorrScale;
323  }
324  else
325  if( tb >= 0.10 )
326  {
327  static const double AttenCorrScale = 210.0;
328  static const signed char AttenCorrs[] = {
329  -113, -118, -122, -125, -126, -97, -95, -92, -92, -89, -82,
330  -75, -69, -48, -42, -36, -30, -22, -14, -5, -2, 1, 6, 13, 22,
331  28, 35, 41, 48, 55, 56, 56, 61, 65, 71, 77, 81, 83, 85, 85,
332  74, 74, 73, 72, 71, 70, 68, 64, 59, 56, 49, 52, 46, 42, 36,
333  32, 26, 20, 13, 7, -2, -6, -10, -15, -20, -27, -33, -38, -44,
334  -43, -48, -53, -57, -63, -69, -73, -75, -79, -81, -74, -76,
335  -77, -77, -78, -81, -80, -80, -78, -76, -65, -62, -59, -56,
336  -51, -48, -44, -38, -33, -25, -19, -13, -5, -1, 2, 7, 13, 17,
337  21, 25, 30, 35, 40, 45, 50, 53, 56, 57, 55, 58, 59, 62, 64,
338  67, 67, 68, 68, 62, 61, 61, 59, 59, 57, 57, 55, 52, 48, 42,
339  38, 35, 31, 26, 20, 15, 13, 10, 7, 3, -2, -8, -13, -17, -23,
340  -28, -34, -37, -40, -41, -45, -48, -50, -53, -57, -59, -62,
341  -63, -63, -57, -57, -56, -56, -54, -54, -53, -49, -48, -41,
342  -38, -33, -31, -26, -23, -18, -12, -9, -7, -7, -3, 0, 5, 9,
343  14, 16, 20, 22, 21, 23, 25, 27, 28, 29, 34, 33, 35, 33, 31,
344  30, 29, 29, 26, 26, 25, 24, 20, 19, 15, 10, 8, 4, 1, -2, -6,
345  -10, -16, -19, -23, -26, -27, -30, -34, -39, -43, -47, -51,
346  -52, -54, -56, -58, -59, -62, -63, -66, -65, -65, -64, -59,
347  -57, -54, -52, -48, -44, -42, -37, -32, -22, -17, -10, -3, 5,
348  13, 22, 30, 40, 50, 60, 72 };
349 
350  atten -= AttenCorrs[ AttenCorr ] / AttenCorrScale;
351  }
352  else
353  {
354  static const double AttenCorrScale = 196.0;
355  static const signed char AttenCorrs[] = {
356  -15, -17, -20, -20, -20, -21, -20, -16, -17, -18, -17, -13,
357  -12, -11, -9, -7, -5, -4, -1, 1, 3, 4, 5, 6, 7, 9, 9, 10, 10,
358  10, 11, 11, 11, 12, 12, 12, 10, 11, 10, 10, 8, 10, 11, 10, 11,
359  11, 13, 14, 15, 19, 27, 26, 23, 18, 14, 8, 4, -2, -6, -12,
360  -17, -23, -28, -33, -37, -42, -46, -49, -53, -57, -60, -61,
361  -64, -65, -67, -66, -66, -66, -65, -64, -61, -59, -56, -52,
362  -48, -42, -38, -31, -27, -19, -13, -7, -1, 8, 14, 22, 29, 37,
363  45, 52, 59, 66, 73, 80, 86, 91, 96, 100, 104, 108, 111, 114,
364  115, 117, 118, 120, 120, 118, 117, 114, 113, 111, 107, 103,
365  99, 95, 89, 84, 78, 72, 66, 60, 52, 44, 37, 30, 21, 14, 6, -3,
366  -11, -18, -26, -34, -43, -51, -58, -65, -73, -78, -85, -90,
367  -97, -102, -107, -113, -115, -118, -121, -125, -125, -126,
368  -126, -126, -125, -124, -121, -119, -115, -111, -109, -101,
369  -102, -95, -88, -81, -73, -67, -63, -54, -47, -40, -33, -26,
370  -18, -11, -5, 2, 8, 14, 19, 25, 31, 36, 37, 43, 47, 49, 51,
371  52, 57, 57, 56, 57, 58, 58, 58, 57, 56, 52, 52, 50, 48, 44,
372  41, 39, 37, 33, 31, 26, 24, 21, 18, 14, 11, 8, 4, 2, -2, -5,
373  -7, -9, -11, -13, -15, -16, -18, -19, -20, -23, -24, -24, -25,
374  -27, -26, -27, -29, -30, -31, -32, -35, -36, -39, -40, -44,
375  -46, -51, -54, -59, -63, -69, -76, -83, -91, -98 };
376 
377  atten -= AttenCorrs[ AttenCorr ] / AttenCorrScale;
378  }
379 
380  pwr = 7.43932822146293e-8 * sqr( atten ) + 0.000102747434588003 *
381  cos( 0.00785021930010397 * atten ) * cos( 0.633854318781239 +
382  0.103208573657699 * atten ) - 0.00798132247867036 -
383  0.000903555213543865 * atten - 0.0969365532127236 * exp(
384  0.0779275237937911 * atten ) - 1.37304948662012e-5 * atten * cos(
385  0.00785021930010397 * atten );
386 
387  if( pwr <= 0.067665322581 )
388  {
389  if( tb >= 0.25 )
390  {
391  hl = 2.6778150875894 / tb + 300.547590563091 * atan( atan(
392  2.68959772209918 * pwr )) / ( 5.5099277187035 * tb - tb *
393  tanh( cos( asinh( atten ))));
394 
395  fo1 = 0.987205355829873 * tb + 1.00011788929851 * atan2(
396  -0.321432067051302 - 6.19131357321578 * sqrt( pwr ),
397  hl + -1.14861472207245 / ( hl - 14.1821147585957 ) + pow(
398  0.9521145021664, pow( atan2( 1.12018764830637, tb ),
399  2.10988901686912 * hl - 20.9691278378345 )));
400  }
401  else
402  if( tb >= 0.10 )
403  {
404  hl = ( 1.56688617018066 + 142.064321294568 * pwr +
405  0.00419441117131136 * cos( 243.633511747297 * pwr ) -
406  0.022953443903576 * atten - 0.026629568860284 * cos(
407  127.715550622571 * pwr )) / tb;
408 
409  fo1 = 0.982299356642411 * tb + 0.999441744774215 * asinh((
410  -0.361783054039583 - 5.80540593623676 * sqrt( pwr )) /
411  hl );
412  }
413  else
414  {
415  hl = ( 2.45739657014937 + 269.183679500541 * pwr * cos(
416  5.73225668178813 + atan2( cosh( 0.988861169868941 -
417  17.2201556280744 * pwr ), 1.08340138240431 * pwr ))) / tb;
418 
419  fo1 = 2.291956939 * tb + 0.01942450693 * sqr( tb ) * hl -
420  4.67538973161837 * pwr * tb - 1.668433124 * tb *
421  pow( pwr, pwr );
422  }
423  }
424  else
425  {
426  if( tb >= 0.25 )
427  {
428  hl = ( 1.50258368698213 + 158.556968859477 * asinh( pwr ) *
429  tanh( 57.9466246871383 * tanh( pwr )) -
430  0.0105440479814834 * atten ) / tb;
431 
432  fo1 = 0.994024401639321 * tb + ( -0.236282717577215 -
433  6.8724924545387 * sqrt( sin( pwr ))) / hl;
434  }
435  else
436  if( tb >= 0.10 )
437  {
438  hl = ( 1.50277377248945 + 158.222625721046 * asinh( pwr ) *
439  tanh( 1.02875299001715 + 42.072277322604 * pwr ) -
440  0.0108380943845632 * atten ) / tb;
441 
442  fo1 = 0.992539376734551 * tb + ( -0.251747813037178 -
443  6.74159892452584 * sqrt( tanh( tanh( tan( pwr ))))) / hl;
444  }
445  else
446  {
447  hl = ( 1.15990238966306 * pwr - 5.02124037125213 * sqr(
448  pwr ) - 0.158676856669827 * atten * cos( 1.1609073390614 *
449  pwr - 6.33932586197475 * pwr * sqr( pwr ))) / tb;
450 
451  fo1 = 0.867344453126885 * tb + 0.052693817907757 * tb * log(
452  pwr ) + 0.0895511178735932 * tb * atan( 59.7538527741309 *
453  pwr ) - 0.0745653568081453 * pwr * tb;
454  }
455  }
456 
457  double WinParams[ 2 ];
458  WinParams[ 0 ] = 125.0;
459  WinParams[ 1 ] = pwr;
460 
461  CDSPSincFilterGen sinc;
462  sinc.Len2 = 0.25 * hl / ReqNormFreq;
463  sinc.Freq1 = 0.0;
464  sinc.Freq2 = M_PI * ( 1.0 - fo1 ) * ReqNormFreq;
465  sinc.initBand( CDSPSincFilterGen :: wftKaiser, WinParams, true );
466 
467  KernelLen = sinc.KernelLen;
468  BlockLenBits = getBitOccupancy( KernelLen - 1 ) + R8B_EXTFFT;
469  const int BlockLen = 1 << BlockLenBits;
470 
471  KernelBlock.alloc( BlockLen * 2 );
472  sinc.generateBand( &KernelBlock[ 0 ],
474 
475  if( ReqPhase == fprLinearPhase )
476  {
477  IsZeroPhase = true;
478  Latency = sinc.fl2;
479  LatencyFrac = 0.0;
480  }
481  else
482  {
483  IsZeroPhase = false;
484  double DCGroupDelay;
485 
486  calcMinPhaseTransform( &KernelBlock[ 0 ], KernelLen, 16, false,
487  &DCGroupDelay );
488 
489  Latency = (int) DCGroupDelay;
490  LatencyFrac = DCGroupDelay - Latency;
491  }
492 
493  CDSPRealFFTKeeper ffto( BlockLenBits + 1 );
494 
495  if( IsZeroPhase )
496  {
497  // Calculate DC gain.
498 
499  double s = 0.0;
500  int i;
501 
502  for( i = 0; i < KernelLen; i++ )
503  {
504  s += KernelBlock[ i ];
505  }
506 
507  s = ffto -> getInvMulConst() * ReqGain / s;
508 
509  // Time-shift the filter so that zero-phase response is produced.
510  // Simultaneously multiply by "s".
511 
512  for( i = 0; i <= sinc.fl2; i++ )
513  {
514  KernelBlock[ i ] = KernelBlock[ sinc.fl2 + i ] * s;
515  }
516 
517  for( i = 1; i <= sinc.fl2; i++ )
518  {
519  KernelBlock[ BlockLen * 2 - i ] = KernelBlock[ i ];
520  }
521 
522  memset( &KernelBlock[ sinc.fl2 + 1 ], 0,
523  ( BlockLen * 2 - KernelLen ) * sizeof( double ));
524  }
525  else
526  {
527  normalizeFIRFilter( &KernelBlock[ 0 ], KernelLen,
528  ffto -> getInvMulConst() * ReqGain );
529 
530  memset( &KernelBlock[ KernelLen ], 0,
531  ( BlockLen * 2 - KernelLen ) * sizeof( double ));
532  }
533 
534  ffto -> forward( KernelBlock );
535 
536  if( IsZeroPhase )
537  {
538  ffto -> convertToZ( KernelBlock );
539  }
540 
541  R8BCONSOLE( "CDSPFIRFilter: flt_len=%i latency=%i nfreq=%.4f "
542  "tb=%.1f att=%.1f gain=%.3f\n", KernelLen, Latency,
543  ReqNormFreq, ReqTransBand, ReqAtten, ReqGain );
544  }
545 };
546 
555 {
557 
558  friend class CDSPFIRFilter;
559 
560 public:
566  static int getObjCount()
567  {
568  R8BSYNC( StateSync );
569 
570  return( ObjCount );
571  }
572 
602  static CDSPFIRFilter& getLPFilter( const double ReqNormFreq,
603  const double ReqTransBand, const double ReqAtten,
604  const EDSPFilterPhaseResponse ReqPhase, const double ReqGain,
605  const double* const AttenCorrs = NULL )
606  {
607  R8BASSERT( ReqNormFreq > 0.0 && ReqNormFreq <= 1.0 );
608  R8BASSERT( ReqTransBand >= CDSPFIRFilter :: getLPMinTransBand() );
609  R8BASSERT( ReqTransBand <= CDSPFIRFilter :: getLPMaxTransBand() );
610  R8BASSERT( ReqAtten >= CDSPFIRFilter :: getLPMinAtten() );
611  R8BASSERT( ReqAtten <= CDSPFIRFilter :: getLPMaxAtten() );
612  R8BASSERT( ReqGain > 0.0 );
613 
614  R8BSYNC( StateSync );
615 
616  CDSPFIRFilter* PrevObj = NULL;
617  CDSPFIRFilter* CurObj = Objects;
618 
619  while( CurObj != NULL )
620  {
621  if( CurObj -> ReqNormFreq == ReqNormFreq &&
622  CurObj -> ReqTransBand == ReqTransBand &&
623  CurObj -> ReqAtten == ReqAtten &&
624  CurObj -> ReqPhase == ReqPhase &&
625  CurObj -> ReqGain == ReqGain )
626  {
627  break;
628  }
629 
630  if( CurObj -> Next == NULL && ObjCount >= R8B_FILTER_CACHE_MAX )
631  {
632  if( CurObj -> RefCount == 0 )
633  {
634  // Delete the last filter which is not used.
635 
636  PrevObj -> Next = NULL;
637  delete CurObj;
638  ObjCount--;
639  }
640  else
641  {
642  // Move the last filter to the top of the list since it
643  // seems to be in use for a long time.
644 
645  PrevObj -> Next = NULL;
646  CurObj -> Next = Objects.unkeep();
647  Objects = CurObj;
648  }
649 
650  CurObj = NULL;
651  break;
652  }
653 
654  PrevObj = CurObj;
655  CurObj = CurObj -> Next;
656  }
657 
658  if( CurObj != NULL )
659  {
660  CurObj -> RefCount++;
661 
662  if( PrevObj == NULL )
663  {
664  return( *CurObj );
665  }
666 
667  // Remove the filter from the list temporarily.
668 
669  PrevObj -> Next = CurObj -> Next;
670  }
671  else
672  {
673  // Create a new filter object (with RefCount == 1) and build the
674  // filter kernel.
675 
676  CurObj = new CDSPFIRFilter();
677  CurObj -> ReqNormFreq = ReqNormFreq;
678  CurObj -> ReqTransBand = ReqTransBand;
679  CurObj -> ReqAtten = ReqAtten;
680  CurObj -> ReqPhase = ReqPhase;
681  CurObj -> ReqGain = ReqGain;
682  ObjCount++;
683 
684  CurObj -> buildLPFilter( AttenCorrs );
685  }
686 
687  // Insert the filter at the start of the list.
688 
689  CurObj -> Next = Objects.unkeep();
690  Objects = CurObj;
691 
692  return( *CurObj );
693  }
694 
695 private:
696  static CSyncObject StateSync;
697  static CPtrKeeper< CDSPFIRFilter* > Objects;
699  static int ObjCount;
702 };
705 
706 // ---------------------------------------------------------------------------
707 // CDSPFIRFilter PUBLIC
708 // ---------------------------------------------------------------------------
709 
711 {
712  R8BSYNC( CDSPFIRFilterCache :: StateSync );
713 
714  RefCount--;
715 }
716 
717 // ---------------------------------------------------------------------------
718 
719 } // namespace r8b
720 
721 #endif // R8B_CDSPFIRFILTER_INCLUDED
double asinh(const double v)
Definition: r8bbase.h:1205
int getBitOccupancy(const int v)
Definition: r8bbase.h:775
static double getLPMaxAtten()
Definition: CDSPFIRFilter.h:106
int getKernelLen() const
Definition: CDSPFIRFilter.h:144
#define R8BCONSOLE(...)
Console output macro, used to output various resampler status strings, including filter design parame...
Definition: r8bconf.h:85
#define R8BASSERT(e)
Assertion macro used to check for certain run-time conditions.
Definition: r8bconf.h:72
void normalizeFIRFilter(double *const p, const int l, const double DCGain, const int pstep=1)
Function normalizes FIR filter so that its frequency response at DC is equal to DCGain.
Definition: r8bbase.h:943
static int getObjCount()
Definition: CDSPFIRFilter.h:566
const double * getKernelBlock() const
Definition: CDSPFIRFilter.h:167
double Freq1
Required corner circular frequency 1 [0; pi].
Definition: CDSPSincFilterGen.h:50
Pointer-to-object "keeper" class with automatic deletion.
Definition: r8bbase.h:429
Linear-phase response.
Definition: CDSPFIRFilter.h:29
Sinc function-based FIR filter generator class.
Definition: CDSPSincFilterGen.h:31
Calculation and storage class for FIR filters.
Definition: CDSPFIRFilter.h:57
int fl2
Internal "half kernel length" value.
Definition: CDSPSincFilterGen.h:41
void generateBand(T *op, CWindowFunc wfunc=&CDSPSincFilterGen ::calcWindowBlackman)
Function calculates band-limited windowed sinc function-based filter kernel.
Definition: CDSPSincFilterGen.h:330
Minimum-phase response.
Definition: CDSPFIRFilter.h:33
#define R8BNOCTOR(ClassName)
A special macro that defines empty copy-constructor and copy operator with the "private:" prefix...
Definition: r8bbase.h:144
Multi-threaded synchronization object class.
Definition: r8bbase.h:526
void initBand(const EWindowFunctionType WinType=wftCosine, const double *const Params=NULL, const bool UsePower=false)
Function initializes *this structure for generation of band-limited sinc filter kernel.
Definition: CDSPSincFilterGen.h:131
int KernelLen
Resulting length of the filter kernel, this variable.
Definition: CDSPSincFilterGen.h:38
#define R8B_EXTFFT
This macro, when equal to 1, extends length of low-pass filters&#39; FFT block by a factor of 2 by zero-p...
Definition: r8bconf.h:168
T max(const T &v1, const T &v2)
Definition: r8bbase.h:1134
T min(const T &v1, const T &v2)
Definition: r8bbase.h:1118
FIR filter cache class.
Definition: CDSPFIRFilter.h:554
double sqr(const double x)
Definition: r8bbase.h:1174
#define M_PI
The macro equals to "pi" constant, fits 53-bit floating point mantissa.
Definition: r8bbase.h:94
Sinc function-based FIR filter generator class.
A "keeper" class for real-valued FFT transform objects.
Definition: CDSPRealFFT.h:461
int getBlockLenBits() const
Definition: CDSPFIRFilter.h:154
double Freq2
Required corner circular frequency 2 [0; pi].
Definition: CDSPSincFilterGen.h:53
double Len2
Required half filter kernel&#39;s length in samples (can be.
Definition: CDSPSincFilterGen.h:34
Real-valued FFT transform class.
#define R8B_FILTER_CACHE_MAX
This macro specifies the number of filters kept in the cache at most.
Definition: r8bconf.h:118
#define R8BSYNC(SyncObject)
The synchronization macro.
Definition: r8bbase.h:664
double getLatencyFrac() const
Definition: CDSPFIRFilter.h:134
int getLatency() const
Definition: CDSPFIRFilter.h:124
Kaiser window function.
Definition: CDSPSincFilterGen.h:81
static double getLPMinAtten()
Definition: CDSPFIRFilter.h:96
static CDSPFIRFilter & getLPFilter(const double ReqNormFreq, const double ReqTransBand, const double ReqAtten, const EDSPFilterPhaseResponse ReqPhase, const double ReqGain, const double *const AttenCorrs=NULL)
Function calculates or returns reference to a previously calculated (cached) low-pass FIR filter...
Definition: CDSPFIRFilter.h:602
static double getLPMaxTransBand()
Definition: CDSPFIRFilter.h:86
#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:99
EDSPFilterPhaseResponse
Enumeration of filter&#39;s phase responses.
Definition: CDSPFIRFilter.h:27
bool isZeroPhase() const
Definition: CDSPFIRFilter.h:115
void calcMinPhaseTransform(double *const Kernel, const int KernelLen, const int LenMult=2, const bool DoFinalMul=true, double *const DCGroupDelay=NULL)
Function calculates the minimum-phase transform of the filter kernel, using a discrete Hilbert transf...
Definition: CDSPRealFFT.h:609
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21
static double getLPMinTransBand()
Definition: CDSPFIRFilter.h:76
void alloc(const int Capacity)
Function allocates memory so that the specified number of elements of type T can be stored in *this b...
Definition: r8bbase.h:318
double calcWindowKaiser()
Definition: CDSPSincFilterGen.h:246
void unref()
This function should be called when the filter obtained via the filter cache is no longer needed...
Definition: CDSPFIRFilter.h:710