Flan
CDSPHBDownsampler.h
Go to the documentation of this file.
1 //$ nobt
2 //$ nocpp
3 
15 #ifndef R8B_CDSPHBDOWNSAMPLER_INCLUDED
16 #define R8B_CDSPHBDOWNSAMPLER_INCLUDED
17 
18 #include "CDSPHBUpsampler.h"
19 
20 namespace r8b {
21 
30 {
31 public:
46  CDSPHBDownsampler( const double ReqAtten, const int SteepIndex,
47  const bool IsThird, const double PrevLatency )
48  {
49  static const CConvolveFn FltConvFn[ 14 ] = {
50  &CDSPHBDownsampler :: convolve1, &CDSPHBDownsampler :: convolve2,
51  &CDSPHBDownsampler :: convolve3, &CDSPHBDownsampler :: convolve4,
52  &CDSPHBDownsampler :: convolve5, &CDSPHBDownsampler :: convolve6,
53  &CDSPHBDownsampler :: convolve7, &CDSPHBDownsampler :: convolve8,
54  &CDSPHBDownsampler :: convolve9, &CDSPHBDownsampler :: convolve10,
55  &CDSPHBDownsampler :: convolve11, &CDSPHBDownsampler :: convolve12,
56  &CDSPHBDownsampler :: convolve13,
57  &CDSPHBDownsampler :: convolve14 };
58 
59  int fltt;
60  double att;
61 
62  if( IsThird )
63  {
64  CDSPHBUpsampler :: getHBFilterThird( ReqAtten, SteepIndex, fltp,
65  fltt, att );
66  }
67  else
68  {
69  CDSPHBUpsampler :: getHBFilter( ReqAtten, SteepIndex, fltp, fltt,
70  att );
71  }
72 
73  convfn = FltConvFn[ fltt - 1 ];
74  fll = fltt * 2 - 1;
75  fl2 = fll;
76  flo = fll + fl2;
77 
78  LatencyFrac = PrevLatency * 0.5;
79  Latency = (int) LatencyFrac;
80  LatencyFrac -= Latency;
81 
82  R8BCONSOLE( "CDSPHBDownsampler: taps=%i third=%i att=%.1f io=1/2\n",
83  fltt, (int) IsThird, att );
84 
85  clear();
86  }
87 
88  virtual int getLatency() const
89  {
90  return( 0 );
91  }
92 
93  virtual double getLatencyFrac() const
94  {
95  return( LatencyFrac );
96  }
97 
98  virtual int getMaxOutLen( const int MaxInLen ) const
99  {
100  R8BASSERT( MaxInLen >= 0 );
101 
102  return(( MaxInLen + 1 ) / 2 );
103  }
104 
105  virtual void clear()
106  {
107  LatencyLeft = Latency;
108  BufLeft = 0;
109  WritePos = 0;
110  ReadPos = BufLen - fll; // Set "read" position to
111  // account for filter's latency.
112 
113  memset( &Buf[ ReadPos ], 0, fll * sizeof( double ));
114  }
115 
116  virtual int process( double* ip, int l, double*& op0 )
117  {
118  R8BASSERT( l >= 0 );
119 
120  double* op = op0;
121 
122  while( l > 0 )
123  {
124  // Add new input samples to both halves of the ring buffer.
125 
126  const int b = min( min( l, BufLen - WritePos ),
127  BufLen - fll - BufLeft );
128 
129  double* const wp1 = Buf + WritePos;
130  memcpy( wp1, ip, b * sizeof( double ));
131 
132  if( WritePos < flo )
133  {
134  const int c = min( b, flo - WritePos );
135  memcpy( wp1 + BufLen, wp1, c * sizeof( double ));
136  }
137 
138  ip += b;
139  WritePos = ( WritePos + b ) & BufLenMask;
140  l -= b;
141  BufLeft += b;
142 
143  if( BufLeft > fl2 )
144  {
145  const int c = ( BufLeft - fl2 + 1 ) >> 1;
146 
147  double* const opend = op + c;
148  ( *convfn )( op, opend, fltp, Buf + fll, ReadPos );
149 
150  op = opend;
151  BufLeft -= c + c;
152  }
153  }
154 
155  int ol = (int) ( op - op0 );
156 
157  if( LatencyLeft > 0 )
158  {
159  if( LatencyLeft >= ol )
160  {
161  LatencyLeft -= ol;
162  return( 0 );
163  }
164 
165  ol -= LatencyLeft;
166  op0 += LatencyLeft;
167  LatencyLeft = 0;
168  }
169 
170  return( ol );
171  }
172 
173 private:
174  static const int BufLenBits = 8;
175  static const int BufLen = 1 << BufLenBits;
182  static const int BufLenMask = BufLen - 1;
186  double Buf[ BufLen + 54 ];
189  const double* fltp;
192  int fll;
194  int fl2;
196  int flo;
198  int Latency;
200  double LatencyFrac;
202  int BufLeft;
204  int WritePos;
208  int ReadPos;
211  int LatencyLeft;
213  typedef void( *CConvolveFn )( double* op, double* const opend,
215  const double* const flt, const double* const rp0, int& ReadPos0 );
216  CConvolveFn convfn;
219 
221 #define R8BHBC1( fn ) \
222  static void fn( double* op, double* const opend, const double* const flt, \
223  const double* const rp0, int& ReadPos0 ) \
224  { \
225  int rpos = ReadPos0; \
226  while( op < opend ) \
227  { \
228  const double* const rp = rp0 + rpos; \
229  *op = rp[ 0 ] +
230 
231 #define R8BHBC2 \
232  rpos = ( rpos + 2 ) & BufLenMask; \
233  op++; \
234  } \
235  ReadPos0 = rpos; \
236  }
237 
238  R8BHBC1( convolve1 )
239  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]);
240  R8BHBC2
241 
242  R8BHBC1( convolve2 )
243  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
244  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]);
245  R8BHBC2
246 
247  R8BHBC1( convolve3 )
248  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
249  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
250  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]);
251  R8BHBC2
252 
253  R8BHBC1( convolve4 )
254  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
255  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
256  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
257  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]);
258  R8BHBC2
259 
260  R8BHBC1( convolve5 )
261  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
262  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
263  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
264  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
265  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]);
266  R8BHBC2
267 
268  R8BHBC1( convolve6 )
269  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
270  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
271  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
272  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
273  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
274  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]);
275  R8BHBC2
276 
277  R8BHBC1( convolve7 )
278  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
279  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
280  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
281  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
282  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
283  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
284  flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]);
285  R8BHBC2
286 
287  R8BHBC1( convolve8 )
288  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
289  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
290  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
291  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
292  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
293  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
294  flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
295  flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]);
296  R8BHBC2
297 
298  R8BHBC1( convolve9 )
299  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
300  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
301  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
302  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
303  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
304  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
305  flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
306  flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
307  flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]);
308  R8BHBC2
309 
310  R8BHBC1( convolve10 )
311  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
312  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
313  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
314  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
315  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
316  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
317  flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
318  flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
319  flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
320  flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]);
321  R8BHBC2
322 
323  R8BHBC1( convolve11 )
324  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
325  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
326  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
327  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
328  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
329  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
330  flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
331  flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
332  flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
333  flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]) +
334  flt[ 10 ] * ( rp[ 21 ] + rp[ -21 ]);
335  R8BHBC2
336 
337  R8BHBC1( convolve12 )
338  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
339  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
340  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
341  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
342  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
343  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
344  flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
345  flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
346  flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
347  flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]) +
348  flt[ 10 ] * ( rp[ 21 ] + rp[ -21 ]) +
349  flt[ 11 ] * ( rp[ 23 ] + rp[ -23 ]);
350  R8BHBC2
351 
352  R8BHBC1( convolve13 )
353  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
354  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
355  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
356  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
357  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
358  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
359  flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
360  flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
361  flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
362  flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]) +
363  flt[ 10 ] * ( rp[ 21 ] + rp[ -21 ]) +
364  flt[ 11 ] * ( rp[ 23 ] + rp[ -23 ]) +
365  flt[ 12 ] * ( rp[ 25 ] + rp[ -25 ]);
366  R8BHBC2
367 
368  R8BHBC1( convolve14 )
369  flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
370  flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
371  flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
372  flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
373  flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
374  flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
375  flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
376  flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
377  flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
378  flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]) +
379  flt[ 10 ] * ( rp[ 21 ] + rp[ -21 ]) +
380  flt[ 11 ] * ( rp[ 23 ] + rp[ -23 ]) +
381  flt[ 12 ] * ( rp[ 25 ] + rp[ -25 ]) +
382  flt[ 13 ] * ( rp[ 27 ] + rp[ -27 ]);
383  R8BHBC2
384 
385 #undef R8BHBC1
386 #undef R8BHBC2
387 };
388 
389 // ---------------------------------------------------------------------------
390 
391 } // namespace r8b
392 
393 #endif // R8B_CDSPHBDOWNSAMPLER_INCLUDED
static void getHBFilterThird(const double ReqAtten, const int SteepIndex, const double *&flt, int &fltt, double &att)
Function that provides filter data for various steepness indices and attenuations.
Definition: CDSPHBUpsampler.h:301
#define R8BCONSOLE(...)
Console output macro, used to output various resampler status strings, including filter design parame...
Definition: r8bconf.h:85
virtual void clear()
Function clears (resets) the state of *this object and returns it to the state after construction...
Definition: CDSPHBDownsampler.h:105
virtual double getLatencyFrac() const
Definition: CDSPHBDownsampler.h:93
virtual int getMaxOutLen(const int MaxInLen) const
Definition: CDSPHBDownsampler.h:98
#define R8BASSERT(e)
Assertion macro used to check for certain run-time conditions.
Definition: r8bconf.h:72
virtual int getLatency() const
Definition: CDSPHBDownsampler.h:88
Half-band downsampler class.
Definition: CDSPHBDownsampler.h:29
T min(const T &v1, const T &v2)
Definition: r8bbase.h:1118
CDSPHBDownsampler(const double ReqAtten, const int SteepIndex, const bool IsThird, const double PrevLatency)
Constructor initalizes the half-band downsampler.
Definition: CDSPHBDownsampler.h:46
static void getHBFilter(const double ReqAtten, const int SteepIndex, const double *&flt, int &fltt, double &att)
Function that provides filter data for various steepness indices and attenuations.
Definition: CDSPHBUpsampler.h:43
virtual int process(double *ip, int l, double *&op0)
Function performs DSP processing.
Definition: CDSPHBDownsampler.h:116
The base virtual class for DSP processing algorithms.
Definition: CDSPProcessor.h:31
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21
Half-band upsampling class.