Flan
CDSPFracInterpolator.h
Go to the documentation of this file.
1 //$ nobt
2 //$ nocpp
3 
15 #ifndef R8B_CDSPFRACINTERPOLATOR_INCLUDED
16 #define R8B_CDSPFRACINTERPOLATOR_INCLUDED
17 
18 #include "CDSPSincFilterGen.h"
19 #include "CDSPProcessor.h"
20 
21 namespace r8b {
22 
23 #if R8B_FLTTEST
24  extern int InterpFilterFracs;
25  extern int InterpFilterFracsThird;
28 #endif // R8B_FLTTEST
31 
42 {
43  R8BNOCTOR( CDSPFracDelayFilterBank );
44 
45  friend class CDSPFracDelayFilterBankCache;
46 
47 public:
64  CDSPFracDelayFilterBank( const int aFilterFracs, const int aElementSize,
65  const int aInterpPoints, const double aReqAtten, const bool aIsThird )
66  : InitFilterFracs( aFilterFracs )
67  , ElementSize( aElementSize )
68  , InterpPoints( aInterpPoints )
69  , ReqAtten( aReqAtten )
70  , IsThird( aIsThird )
71  , Next( NULL )
72  , RefCount( 1 )
73  {
74  R8BASSERT( ElementSize >= 1 && ElementSize <= 4 );
75 
76  // Kaiser window function Params, for half and third-band.
77 
78  const double* const Params = getWinParams( ReqAtten, IsThird,
79  FilterLen );
80 
81  FilterSize = FilterLen * ElementSize;
82 
83  if( InitFilterFracs == -1 )
84  {
85  FilterFracs = (int) ceil( 1.792462178761753 *
86  exp( 0.033300466782047 * ReqAtten ));
87 
88  #if R8B_FLTTEST
89 
90  if( IsThird )
91  {
92  if( InterpFilterFracsThird != -1 )
93  {
94  FilterFracs = InterpFilterFracsThird;
95  }
96  }
97  else
98  {
99  if( InterpFilterFracs != -1 )
100  {
101  FilterFracs = InterpFilterFracs;
102  }
103  }
104 
105  #endif // R8B_FLTTEST
106  }
107  else
108  {
109  FilterFracs = InitFilterFracs;
110  }
111 
112  Table.alloc( FilterSize * ( FilterFracs + InterpPoints ));
113 
114  CDSPSincFilterGen sinc;
115  sinc.Len2 = FilterLen / 2;
116 
117  double* p = Table;
118  const int pc2 = InterpPoints / 2;
119  int i;
120 
121  for( i = -pc2 + 1; i <= FilterFracs + pc2; i++ )
122  {
123  sinc.FracDelay = (double) ( FilterFracs - i ) / FilterFracs;
124  sinc.initFrac( CDSPSincFilterGen :: wftKaiser, Params, true );
126  ElementSize );
127 
128  normalizeFIRFilter( p, FilterLen, 1.0, ElementSize );
129  p += FilterSize;
130  }
131 
132  const int TablePos2 = FilterSize;
133  const int TablePos3 = FilterSize * 2;
134  const int TablePos4 = FilterSize * 3;
135  const int TablePos5 = FilterSize * 4;
136  const int TablePos6 = FilterSize * 5;
137  const int TablePos7 = FilterSize * 6;
138  const int TablePos8 = FilterSize * 7;
139  double* const TableEnd = Table + ( FilterFracs + 1 ) * FilterSize;
140  p = Table;
141 
142  if( InterpPoints == 8 )
143  {
144  if( ElementSize == 3 )
145  {
146  // Calculate 2nd order spline (polynomial) interpolation
147  // coefficients using 8 points.
148 
149  while( p < TableEnd )
150  {
151  calcSpline2p8Coeffs( p, p[ 0 ], p[ TablePos2 ],
152  p[ TablePos3 ], p[ TablePos4 ], p[ TablePos5 ],
153  p[ TablePos6 ], p[ TablePos7 ], p[ TablePos8 ]);
154 
155  p += ElementSize;
156  }
157  }
158  else
159  if( ElementSize == 4 )
160  {
161  // Calculate 3rd order spline (polynomial) interpolation
162  // coefficients using 8 points.
163 
164  while( p < TableEnd )
165  {
166  calcSpline3p8Coeffs( p, p[ 0 ], p[ TablePos2 ],
167  p[ TablePos3 ], p[ TablePos4 ], p[ TablePos5 ],
168  p[ TablePos6 ], p[ TablePos7 ], p[ TablePos8 ]);
169 
170  p += ElementSize;
171  }
172  }
173  }
174  else
175  {
176  if( ElementSize == 2 )
177  {
178  // Calculate linear interpolation coefficients.
179 
180  while( p < TableEnd )
181  {
182  p[ 1 ] = p[ TablePos2 ] - p[ 0 ];
183  p += ElementSize;
184  }
185  }
186  }
187 
188  R8BCONSOLE( "CDSPFracDelayFilterBank: fracs=%i order=%i taps=%i "
189  "att=%.1f third=%i\n", FilterFracs, ElementSize - 1, FilterLen,
190  ReqAtten, (int) IsThird );
191  }
192 
194  {
195  delete Next;
196  }
197 
207  static void roundReqAtten( double& att, const bool aIsThird )
208  {
209  int tmp;
210  getWinParams( att, aIsThird, tmp );
211  }
212 
217  int getFilterLen() const
218  {
219  return( FilterLen );
220  }
221 
227  int getFilterFracs() const
228  {
229  return( FilterFracs );
230  }
231 
237  const double& operator []( const int i ) const
238  {
239  R8BASSERT( i >= 0 && i <= FilterFracs );
240 
241  return( Table[ i * FilterSize ]);
242  }
243 
249  void unref();
250 
251 private:
252  int FilterLen;
253  int FilterFracs;
255  int InitFilterFracs;
257  int ElementSize;
260  int InterpPoints;
262  double ReqAtten;
264  bool IsThird;
266  int FilterSize;
268  CFixedBuffer< double > Table;
275  int RefCount;
277 
290  static const double* getWinParams( double& att, const bool aIsThird,
291  int& fltlen )
292  {
293  const int CoeffCount = 13;
294  static const double Coeffs[ CoeffCount ][ 3 ] = {
295  { 2.6504246356892924, 1.9035845248358245, 51.7280 }, // 0.0516
296  { 4.0759654812373016, 1.5747323142948524, 67.1095 }, // 0.0048
297  { 4.9036508646352033, 1.6207644759455790, 81.8379 }, // 0.0009
298  { 5.6131421124830716, 1.6947677220415129, 96.4021 }, // 0.0002
299  { 5.9433751253133691, 1.8730186383321272, 111.1300 }, // 0.0000
300  { 6.8308658253825660, 1.8549555120377224, 125.4649 }, // 0.0000
301  { 7.6648458853758372, 1.8565765953924642, 139.7378 }, // 0.0000
302  { 8.2038730802326842, 1.9269521308895179, 154.0532 }, // 0.0000
303  { 8.7865151489187561, 1.9775307528231671, 168.2101 }, // 0.0000
304  { 9.5945013206755156, 1.9718457932433306, 182.1076 }, // 0.0000
305  { 10.5163048616210250, 1.9504085061576968, 195.5668 }, // 0.0000
306  { 10.2382664677006100, 2.1608878780497056, 209.0609 }, // 0.0000
307  { 10.9976663155261660, 2.1536415815428249, 222.5009 }, // 0.0000
308  };
309 
310  const int CoeffCountThird = 10;
311  static const double CoeffsThird[ CoeffCountThird ][ 3 ] = {
312  { 4.0738201365282452, 1.5774150265957998, 67.2431 }, // 0.0050
313  { 4.9502289040040495, 1.7149006172407628, 86.4870 }, // 0.0008
314  { 5.5995071332976192, 1.8930163359641823, 106.1171 }, // 0.0001
315  { 6.3627287856776054, 1.9945748303811506, 125.2304 }, // 0.0000
316  { 7.4299554386534528, 1.9893399585993299, 144.3469 }, // 0.0000
317  { 8.0667710807396436, 2.0928202837610885, 163.4098 }, // 0.0000
318  { 8.7469991933128526, 2.1640274270903488, 181.0694 }, // 0.0000
319  { 10.0823164330540570, 2.0896732996403280, 199.2880 }, // 0.0000
320  { 19.1718281840114810, 1.2030083075440616, 215.2990 }, // 0.0000
321  { 21.0914128488567630, 1.1919045429676862, 233.9152 }, // 0.0000
322  };
323 
324  const double* Params;
325  int i = 0;
326 
327  if( aIsThird )
328  {
329  while( i != CoeffCountThird - 1 && CoeffsThird[ i ][ 2 ] < att )
330  {
331  i++;
332  }
333 
334  Params = &CoeffsThird[ i ][ 0 ];
335  att = CoeffsThird[ i ][ 2 ];
336  }
337  else
338  {
339  while( i != CoeffCount - 1 && Coeffs[ i ][ 2 ] < att )
340  {
341  i++;
342  }
343 
344  Params = &Coeffs[ i ][ 0 ];
345  att = Coeffs[ i ][ 2 ];
346  }
347 
348  fltlen = ( i + 3 ) * 2;
349 
350  return( Params );
351  }
352 };
353 
361 {
363 
364  friend class CDSPFracDelayFilterBank;
365 
366 public:
372  static int getObjCount()
373  {
374  R8BSYNC( StateSync );
375 
376  return( ObjCount );
377  }
378 
394  static CDSPFracDelayFilterBank& getFilterBank( const int aFilterFracs,
395  const int aElementSize, const int aInterpPoints,
396  double ReqAtten, const bool IsThird, const bool IsStatic )
397  {
398  CDSPFracDelayFilterBank :: roundReqAtten( ReqAtten, IsThird );
399 
400  R8BSYNC( StateSync );
401 
402  if( IsStatic )
403  {
404  CDSPFracDelayFilterBank* CurObj = StaticObjects;
405 
406  while( CurObj != NULL )
407  {
408  if( CurObj -> InitFilterFracs == aFilterFracs &&
409  CurObj -> ElementSize == aElementSize &&
410  CurObj -> InterpPoints == aInterpPoints &&
411  CurObj -> ReqAtten == ReqAtten &&
412  CurObj -> IsThird == IsThird )
413  {
414  return( *CurObj );
415  }
416 
417  CurObj = CurObj -> Next;
418  }
419 
420  // Create a new filter bank and build it.
421 
422  CurObj = new CDSPFracDelayFilterBank( aFilterFracs, aElementSize,
423  aInterpPoints, ReqAtten, IsThird );
424 
425  // Insert the bank at the start of the list.
426 
427  CurObj -> Next = StaticObjects.unkeep();
428  StaticObjects = CurObj;
429 
430  return( *CurObj );
431  }
432 
433  CDSPFracDelayFilterBank* PrevObj = NULL;
434  CDSPFracDelayFilterBank* CurObj = Objects;
435 
436  while( CurObj != NULL )
437  {
438  if( CurObj -> InitFilterFracs == aFilterFracs &&
439  CurObj -> ElementSize == aElementSize &&
440  CurObj -> InterpPoints == aInterpPoints &&
441  CurObj -> ReqAtten == ReqAtten &&
442  CurObj -> IsThird == IsThird )
443  {
444  break;
445  }
446 
447  if( CurObj -> Next == NULL && ObjCount >= R8B_FRACBANK_CACHE_MAX )
448  {
449  if( CurObj -> RefCount == 0 )
450  {
451  // Delete the last bank which is not used.
452 
453  PrevObj -> Next = NULL;
454  delete CurObj;
455  ObjCount--;
456  }
457  else
458  {
459  // Move the last bank to the top of the list since it
460  // seems to be in use for a long time.
461 
462  PrevObj -> Next = NULL;
463  CurObj -> Next = Objects.unkeep();
464  Objects = CurObj;
465  }
466 
467  CurObj = NULL;
468  break;
469  }
470 
471  PrevObj = CurObj;
472  CurObj = CurObj -> Next;
473  }
474 
475  if( CurObj != NULL )
476  {
477  CurObj -> RefCount++;
478 
479  if( PrevObj == NULL )
480  {
481  return( *CurObj );
482  }
483 
484  // Remove the bank from the list temporarily.
485 
486  PrevObj -> Next = CurObj -> Next;
487  }
488  else
489  {
490  // Create a new filter bank (with RefCount == 1) and build it.
491 
492  CurObj = new CDSPFracDelayFilterBank( aFilterFracs, aElementSize,
493  aInterpPoints, ReqAtten, IsThird );
494 
495  ObjCount++;
496  }
497 
498  // Insert the bank at the start of the list.
499 
500  CurObj -> Next = Objects.unkeep();
501  Objects = CurObj;
502 
503  return( *CurObj );
504  }
505 
506 private:
507  static CSyncObject StateSync;
510  static CPtrKeeper< CDSPFracDelayFilterBank* > StaticObjects;
513  static int ObjCount;
516 };
519 
520 // ---------------------------------------------------------------------------
521 // CDSPFracDelayFilterBank PUBLIC
522 // ---------------------------------------------------------------------------
523 
525 {
526  R8BSYNC( CDSPFracDelayFilterBankCache :: StateSync );
527 
528  RefCount--;
529 }
530 
539 inline bool findGCD( double l, double s, double& GCD )
540 {
541  int it = 0;
542 
543  while( it < 50 )
544  {
545  if( s <= 0.0 )
546  {
547  GCD = l;
548  return( true );
549  }
550 
551  const double r = l - s;
552  l = s;
553  s = ( r < 0.0 ? -r : r );
554  it++;
555  }
556 
557  return( false );
558 }
559 
573 inline bool getWholeStepping( const double SSampleRate,
574  const double DSampleRate, int& ResInStep, int& ResOutStep )
575 {
576  double GCD;
577 
578  if( !findGCD( SSampleRate, DSampleRate, GCD ) || GCD < 1.0 )
579  {
580  return( false );
581  }
582 
583  const double InStep0 = SSampleRate / GCD;
584  ResInStep = (int) InStep0;
585  const double OutStep0 = DSampleRate / GCD;
586  ResOutStep = (int) OutStep0;
587 
588  if( InStep0 != ResInStep || OutStep0 != ResOutStep )
589  {
590  return( false );
591  }
592 
593  if( ResOutStep > 1500 )
594  {
595  // Do not allow large output stepping due to low cache
596  // performance of large filter banks.
597 
598  return( false );
599  }
600 
601  return( true );
602 }
603 
620 {
621 public:
636  CDSPFracInterpolator( const double aSrcSampleRate,
637  const double aDstSampleRate, const double ReqAtten,
638  const bool IsThird, const double PrevLatency )
639  : SrcSampleRate( aSrcSampleRate )
640  , DstSampleRate( aDstSampleRate )
641  #if R8B_FASTTIMING
642  , FracStep( aSrcSampleRate / aDstSampleRate )
643  #endif // R8B_FASTTIMING
644  {
645  R8BASSERT( SrcSampleRate > 0.0 );
646  R8BASSERT( DstSampleRate > 0.0 );
647  R8BASSERT( PrevLatency >= 0.0 );
648  R8BASSERT( BufLenBits >= 5 );
649  R8BASSERT(( 1 << BufLenBits ) >= FilterLen * 3 );
650 
651  InitFracPos = PrevLatency;
652  Latency = (int) InitFracPos;
653  InitFracPos -= Latency;
654 
655  #if R8B_FLTTEST
656 
657  IsWhole = false;
658  LatencyFrac = 0.0;
659  FilterBank = new CDSPFracDelayFilterBank( -1, 3, 8, ReqAtten,
660  IsThird );
661 
662  #else // R8B_FLTTEST
663 
664  IsWhole = getWholeStepping( SrcSampleRate, DstSampleRate, InStep,
665  OutStep );
666 
667  if( IsWhole )
668  {
669  InitFracPosW = (int) ( InitFracPos * OutStep );
670  LatencyFrac = InitFracPos - (double) InitFracPosW / OutStep;
672  OutStep, 1, 2, ReqAtten, IsThird, false );
673  }
674  else
675  {
676  LatencyFrac = 0.0;
678  -1, 3, 8, ReqAtten, IsThird, true );
679  }
680 
681  #endif // R8B_FLTTEST
682 
683  FilterLen = FilterBank -> getFilterLen();
684  fl2 = FilterLen >> 1;
685  fll = fl2 - 1;
686  flo = fll + fl2;
687 
688  static const CConvolveFn FltConvFn0[ 13 ] = {
689  &CDSPFracInterpolator :: convolve0< 6 >,
690  &CDSPFracInterpolator :: convolve0< 8 >,
691  &CDSPFracInterpolator :: convolve0< 10 >,
692  &CDSPFracInterpolator :: convolve0< 12 >,
693  &CDSPFracInterpolator :: convolve0< 14 >,
694  &CDSPFracInterpolator :: convolve0< 16 >,
695  &CDSPFracInterpolator :: convolve0< 18 >,
696  &CDSPFracInterpolator :: convolve0< 20 >,
697  &CDSPFracInterpolator :: convolve0< 22 >,
698  &CDSPFracInterpolator :: convolve0< 24 >,
699  &CDSPFracInterpolator :: convolve0< 26 >,
700  &CDSPFracInterpolator :: convolve0< 28 >,
701  &CDSPFracInterpolator :: convolve0< 30 >
702  };
703 
704  convfn = ( IsWhole ? FltConvFn0[ fl2 - 3 ] :
705  &CDSPFracInterpolator :: convolve2 );
706 
707  R8BCONSOLE( "CDSPFracInterpolator: src=%.2f dst=%.2f taps=%i "
708  "fracs=%i third=%i step=%.6f\n", SrcSampleRate, DstSampleRate,
709  FilterLen, ( IsWhole ? OutStep : FilterBank -> getFilterFracs() ),
710  (int) IsThird, aSrcSampleRate / aDstSampleRate );
711 
712  clear();
713  }
714 
715  virtual ~CDSPFracInterpolator()
716  {
717  #if R8B_FLTTEST
718 
719  delete FilterBank;
720 
721  #else // R8B_FLTTEST
722 
723  FilterBank -> unref();
724 
725  #endif // R8B_FLTTEST
726  }
727 
728  virtual int getLatency() const
729  {
730  return( 0 );
731  }
732 
733  virtual double getLatencyFrac() const
734  {
735  return( LatencyFrac );
736  }
737 
738  virtual int getMaxOutLen( const int MaxInLen ) const
739  {
740  R8BASSERT( MaxInLen >= 0 );
741 
742  return( (int) ceil( MaxInLen * DstSampleRate / SrcSampleRate ) + 1 );
743  }
744 
745  virtual void clear()
746  {
747  LatencyLeft = Latency;
748  BufLeft = 0;
749  WritePos = 0;
750  ReadPos = BufLen - fll; // Set "read" position to account for filter's
751  // latency at zero fractional delay.
752 
753  memset( &Buf[ ReadPos ], 0, fll * sizeof( double ));
754 
755  if( IsWhole )
756  {
757  InPosFracW = InitFracPosW;
758  }
759  else
760  {
761  InPosFrac = InitFracPos;
762 
763  #if !R8B_FASTTIMING
764  InCounter = 0;
765  InPosInt = 0;
766  InPosShift = InitFracPos * DstSampleRate / SrcSampleRate;
767  #endif // !R8B_FASTTIMING
768  }
769  }
770 
771  virtual int process( double* ip, int l, double*& op0 )
772  {
773  R8BASSERT( l >= 0 );
774  R8BASSERT( ip != op0 || l == 0 || SrcSampleRate > DstSampleRate );
775 
776  if( LatencyLeft > 0 )
777  {
778  if( LatencyLeft >= l )
779  {
780  LatencyLeft -= l;
781  return( 0 );
782  }
783 
784  l -= LatencyLeft;
785  ip += LatencyLeft;
786  LatencyLeft = 0;
787  }
788 
789  double* op = op0;
790 
791  while( l > 0 )
792  {
793  // Add new input samples to both halves of the ring buffer.
794 
795  const int b = min( min( l, BufLen - WritePos ),
796  BufLen - fll - BufLeft );
797 
798  double* const wp1 = Buf + WritePos;
799  memcpy( wp1, ip, b * sizeof( double ));
800 
801  if( WritePos < flo )
802  {
803  const int c = min( b, flo - WritePos );
804  memcpy( wp1 + BufLen, wp1, c * sizeof( double ));
805  }
806 
807  ip += b;
808  WritePos = ( WritePos + b ) & BufLenMask;
809  l -= b;
810  BufLeft += b;
811 
812  // Produce as many output samples as possible.
813 
814  op = ( *this.*convfn )( op );
815  }
816 
817  #if !R8B_FASTTIMING
818 
819  if( !IsWhole && InCounter > 1000 )
820  {
821  // Reset the interpolation position counter to achieve a
822  // higher sample timing precision.
823 
824  InCounter = 0;
825  InPosInt = 0;
826  InPosShift = InPosFrac * DstSampleRate / SrcSampleRate;
827  }
828 
829  #endif // !R8B_FASTTIMING
830 
831  return( (int) ( op - op0 ));
832  }
833 
834 private:
835  static const int BufLenBits = 8;
836  static const int BufLen = 1 << BufLenBits;
845  static const int BufLenMask = BufLen - 1;
849  int FilterLen;
852  int fl2;
854  int fll;
856  int flo;
858  double Buf[ BufLen + 29 ];
860  double SrcSampleRate;
863  double DstSampleRate;
865  bool IsWhole;
867  int InStep;
869  int OutStep;
871  double InitFracPos;
874  int InitFracPosW;
877  int Latency;
880  double LatencyFrac;
882  int BufLeft;
884  int WritePos;
886  int ReadPos;
889  int LatencyLeft;
891  double InPosFrac;
893  int InPosFracW;
895  CDSPFracDelayFilterBank* FilterBank;
899 #if R8B_FASTTIMING
902  double FracStep;
903 #else // R8B_FASTTIMING
904  int InCounter;
905  int InPosInt;
907  double InPosShift;
909 #endif // R8B_FASTTIMING
911 
912  typedef double*( CDSPFracInterpolator :: *CConvolveFn )( double* op );
913  CConvolveFn convfn;
916 
926  template< int fltlen >
927  double* convolve0( double* op )
928  {
929  while( BufLeft > fl2 )
930  {
931  const double* const ftp = &(*FilterBank)[ InPosFracW ];
932  const double* const rp = Buf + ReadPos;
933  double s = 0.0;
934  int i;
935 
936  for( i = 0; i < fltlen; i++ )
937  {
938  s += ftp[ i ] * rp[ i ];
939  }
940 
941  *op = s;
942  op++;
943 
944  InPosFracW += InStep;
945  const int PosIncr = InPosFracW / OutStep;
946  InPosFracW -= PosIncr * OutStep;
947 
948  ReadPos = ( ReadPos + PosIncr ) & BufLenMask;
949  BufLeft -= PosIncr;
950  }
951 
952  return( op );
953  }
954 
962  double* convolve2( double* op )
963  {
964  while( BufLeft > fl2 )
965  {
966  double x = InPosFrac * FilterBank -> getFilterFracs();
967  const int fti = (int) x; // Function table index.
968  x -= fti; // Coefficient for interpolation between
969  // adjacent fractional delay filters.
970  const double x2 = x * x;
971  const double* const ftp = &(*FilterBank)[ fti ];
972  const double* const rp = Buf + ReadPos;
973  double s = 0.0;
974  int ii = 0;
975  int i;
976 
977  for( i = 0; i < FilterLen; i++ )
978  {
979  s += ( ftp[ ii ] + ftp[ ii + 1 ] * x +
980  ftp[ ii + 2 ] * x2 ) * rp[ i ];
981 
982  ii += 3;
983  }
984 
985  *op = s;
986  op++;
987 
988  #if R8B_FASTTIMING
989 
990  InPosFrac += FracStep;
991  const int PosIncr = (int) InPosFrac;
992  InPosFrac -= PosIncr;
993 
994  #else // R8B_FASTTIMING
995 
996  InCounter++;
997  const double NextInPos = ( InCounter + InPosShift ) *
998  SrcSampleRate / DstSampleRate;
999 
1000  const int NextInPosInt = (int) NextInPos;
1001  const int PosIncr = NextInPosInt - InPosInt;
1002  InPosInt = NextInPosInt;
1003  InPosFrac = NextInPos - NextInPosInt;
1004 
1005  #endif // R8B_FASTTIMING
1006 
1007  ReadPos = ( ReadPos + PosIncr ) & BufLenMask;
1008  BufLeft -= PosIncr;
1009  }
1010 
1011  return( op );
1012  }
1013 };
1014 
1015 // ---------------------------------------------------------------------------
1016 
1017 } // namespace r8b
1018 
1019 #endif // R8B_CDSPFRACINTERPOLATOR_INCLUDED
virtual int getLatency() const
Definition: CDSPFracInterpolator.h:728
const double & operator[](const int i) const
Definition: CDSPFracInterpolator.h:237
#define R8BCONSOLE(...)
Console output macro, used to output various resampler status strings, including filter design parame...
Definition: r8bconf.h:85
void calcSpline2p8Coeffs(double *c, const double xm3, const double xm2, const double xm1, const double x0, const double x1, const double x2, const double x3, const double x4)
Function calculates coefficients used to calculate 2rd order spline (polynomial) on the equidistant l...
Definition: r8bbase.h:1019
#define R8BASSERT(e)
Assertion macro used to check for certain run-time conditions.
Definition: r8bconf.h:72
Sinc function-based fractional delay filter bank class.
Definition: CDSPFracInterpolator.h:41
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
void initFrac(const EWindowFunctionType WinType=wftCosine, const double *const Params=NULL, const bool UsePower=false)
Function initializes *this structure for generation of full-bandwidth fractional delay sinc filter ke...
Definition: CDSPSincFilterGen.h:184
Pointer-to-object "keeper" class with automatic deletion.
Definition: r8bbase.h:429
double FracDelay
Fractional delay in the range [0; 1], used.
Definition: CDSPSincFilterGen.h:62
Sinc function-based FIR filter generator class.
Definition: CDSPSincFilterGen.h:31
Fractional delay filter cache class.
Definition: CDSPFracInterpolator.h:360
The base virtual class for DSP processing algorithms.
CDSPFracInterpolator(const double aSrcSampleRate, const double aDstSampleRate, const double ReqAtten, const bool IsThird, const double PrevLatency)
Constructor initalizes the interpolator.
Definition: CDSPFracInterpolator.h:636
#define R8BNOCTOR(ClassName)
A special macro that defines empty copy-constructor and copy operator with the "private:" prefix...
Definition: r8bbase.h:144
static CDSPFracDelayFilterBank & getFilterBank(const int aFilterFracs, const int aElementSize, const int aInterpPoints, double ReqAtten, const bool IsThird, const bool IsStatic)
Function calculates or returns reference to a previously calculated (cached) fractional delay filter ...
Definition: CDSPFracInterpolator.h:394
static int getObjCount()
Definition: CDSPFracInterpolator.h:372
Multi-threaded synchronization object class.
Definition: r8bbase.h:526
CDSPFracDelayFilterBank(const int aFilterFracs, const int aElementSize, const int aInterpPoints, const double aReqAtten, const bool aIsThird)
Constructor.
Definition: CDSPFracInterpolator.h:64
bool findGCD(double l, double s, double &GCD)
Definition: CDSPFracInterpolator.h:539
T min(const T &v1, const T &v2)
Definition: r8bbase.h:1118
virtual int process(double *ip, int l, double *&op0)
Function performs DSP processing.
Definition: CDSPFracInterpolator.h:771
bool getWholeStepping(const double SSampleRate, const double DSampleRate, int &ResInStep, int &ResOutStep)
Function evaluates source and destination sample rate ratio and returns the required input and output...
Definition: CDSPFracInterpolator.h:573
#define R8B_FASTTIMING
This macro, when equal to 1, enables fast approach to interpolation sample timing.
Definition: r8bconf.h:155
Sinc function-based FIR filter generator class.
int getFilterFracs() const
Function returns the number of fractional positions sampled by the bank.
Definition: CDSPFracInterpolator.h:227
virtual int getMaxOutLen(const int MaxInLen) const
Definition: CDSPFracInterpolator.h:738
double Len2
Required half filter kernel&#39;s length in samples (can be.
Definition: CDSPSincFilterGen.h:34
#define R8BSYNC(SyncObject)
The synchronization macro.
Definition: r8bbase.h:664
virtual double getLatencyFrac() const
Definition: CDSPFracInterpolator.h:733
Kaiser window function.
Definition: CDSPSincFilterGen.h:81
void generateFrac(T *op, CWindowFunc wfunc=&CDSPSincFilterGen ::calcWindowBlackman, const int opinc=1)
Function calculates windowed fractional delay filter kernel.
Definition: CDSPSincFilterGen.h:432
static void roundReqAtten(double &att, const bool aIsThird)
Function "rounds" the specified attenuation to the nearest effective value.
Definition: CDSPFracInterpolator.h:207
The base virtual class for DSP processing algorithms.
Definition: CDSPProcessor.h:31
void calcSpline3p8Coeffs(double *c, const double xm3, const double xm2, const double xm1, const double x0, const double x1, const double x2, const double x3, const double x4)
Function calculates coefficients used to calculate 3rd order spline (polynomial) on the equidistant l...
Definition: r8bbase.h:987
virtual void clear()
Function clears (resets) the state of *this object and returns it to the state after construction...
Definition: CDSPFracInterpolator.h:745
Fractional delay filter bank-based interpolator class.
Definition: CDSPFracInterpolator.h:619
#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
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21
void unref()
This function should be called when the filter obtained via the filter bank cache is no longer needed...
Definition: CDSPFracInterpolator.h:524
#define R8B_FRACBANK_CACHE_MAX
This macro specifies the number of whole-number stepping fractional delay filter banks kept in the ca...
Definition: r8bconf.h:130
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
int getFilterLen() const
Function returns the length of the filter.
Definition: CDSPFracInterpolator.h:217
double calcWindowKaiser()
Definition: CDSPSincFilterGen.h:246