15 #ifndef R8B_CDSPBLOCKCONVOLVER_INCLUDED 16 #define R8B_CDSPBLOCKCONVOLVER_INCLUDED 63 const int aDownFactor,
const double PrevLatency = 0.0,
64 const bool aDoConsumeLatency =
true )
66 , UpFactor( aUpFactor )
67 , DownFactor( aDownFactor )
68 , DoConsumeLatency( aDoConsumeLatency )
69 , BlockLen2( 2 << Filter -> getBlockLenBits() )
78 if(( 1 << UpShift ) == UpFactor )
80 fftinBits = Filter -> getBlockLenBits() + 1 - UpShift;
81 PrevInputLen = ( Filter -> getKernelLen() - 1 + UpFactor - 1 ) /
84 InputLen = BlockLen2 - PrevInputLen * UpFactor;
89 fftinBits = Filter -> getBlockLenBits() + 1;
90 PrevInputLen = Filter -> getKernelLen() - 1;
91 InputLen = BlockLen2 - PrevInputLen;
94 OutOffset = ( Filter -> isZeroPhase() ? Filter ->
getLatency() : 0 );
96 Latency = (int) LatencyFrac;
97 const int InLatency = Latency + Filter ->
getLatency() - OutOffset;
98 LatencyFrac -= Latency;
99 LatencyFrac /= DownFactor;
109 if(( 1 << DownShift ) == DownFactor )
111 fftoutBits = Filter -> getBlockLenBits() + 1 - DownShift;
127 const int ilc = InputLen & ( DownFactor - 1 );
134 const int lc = InLatency & ( DownFactor - 1 );
138 InputDelay = DownFactor - lc;
141 if( !DoConsumeLatency )
143 Latency /= DownFactor;
150 fftoutBits = Filter -> getBlockLenBits() + 1;
153 if( !DoConsumeLatency && DownFactor > 1 )
155 DownSkipInit = Latency % DownFactor;
156 Latency /= DownFactor;
162 if( fftoutBits == fftinBits )
172 WorkBlocks.
alloc( BlockLen2 * 2 + PrevInputLen );
173 CurInput = &WorkBlocks[ 0 ];
174 CurOutput = &WorkBlocks[ BlockLen2 ];
176 PrevInput = &WorkBlocks[ BlockLen2 * 2 ];
180 R8BCONSOLE(
"CDSPBlockConvolver: flt_len=%i in_len=%i io=%i/%i " 181 "fft=%i/%i latency=%i\n", Filter -> getKernelLen(), InputLen,
182 UpFactor, DownFactor, (*fftin) -> getLen(), (*fftout) -> getLen(),
193 return( DoConsumeLatency ? 0 : Latency );
198 return( LatencyFrac );
205 return(( MaxInLen * UpFactor + DownFactor - 1 ) / DownFactor );
210 memset( &PrevInput[ 0 ], 0, PrevInputLen *
sizeof(
double ));
212 if( DoConsumeLatency )
214 LatencyLeft = Latency;
222 memset( &CurOutput[ 0 ], 0, ( BlockLen2 >> DownShift ) *
227 memset( &CurOutput[ BlockLen2 - OutOffset ], 0, OutOffset *
230 memset( &CurOutput[ 0 ], 0, ( InputLen - OutOffset ) *
235 memset( CurInput, 0, InputDelay *
sizeof(
double ));
237 InDataLeft = InputLen - InputDelay;
239 DownSkip = DownSkipInit;
242 virtual int process(
double* ip,
int l0,
double*& op0 )
245 R8BASSERT( UpFactor / DownFactor <= 1 || ip != op0 || l0 == 0 );
248 int l = l0 * UpFactor;
253 const int Offs = InputLen - InDataLeft;
261 memcpy( &CurInput[ Offs >> UpShift ], ip,
262 ( l >> UpShift ) *
sizeof(
double ));
266 copyUpsample( ip, &CurInput[ Offs ], l );
269 copyToOutput( Offs - OutOffset, op, l, l0 );
273 const int b = InDataLeft;
275 InDataLeft = InputLen;
280 const int bu = b >> UpShift;
281 memcpy( &CurInput[ Offs >> UpShift ], ip,
282 bu *
sizeof(
double ));
285 ilu = InputLen >> UpShift;
289 copyUpsample( ip, &CurInput[ Offs ], b );
293 const int pil = (int) ( PrevInputLen *
sizeof(
double ));
294 memcpy( &CurInput[ ilu ], PrevInput, pil );
295 memcpy( PrevInput, &CurInput[ ilu - PrevInputLen ], pil );
297 (*fftin) -> forward( CurInput );
302 mirrorInputSpectrum( (
float*) CurInput );
303 #else // R8B_FLOATFFT 304 mirrorInputSpectrum( CurInput );
305 #endif // R8B_FLOATFFT 308 if( Filter -> isZeroPhase() )
310 (*fftout) -> multiplyBlocksZ( Filter -> getKernelBlock(),
315 (*fftout) -> multiplyBlocks( Filter -> getKernelBlock(),
321 const int z = BlockLen2 >> DownShift;
324 float*
const kb = (
float*) Filter -> getKernelBlock();
325 float*
const p = (
float*) CurInput;
326 #else // R8B_FLOATFFT 327 const double*
const kb = Filter -> getKernelBlock();
328 double*
const p = CurInput;
329 #endif // R8B_FLOATFFT 331 p[ 1 ] = kb[ z ] * p[ z ] - kb[ z + 1 ] * p[ z + 1 ];
334 (*fftout) -> inverse( CurInput );
336 copyToOutput( Offs - OutOffset, op, b, l0 );
338 double*
const tmp = CurInput;
339 CurInput = CurOutput;
361 bool DoConsumeLatency;
429 void copyUpsample(
double*& ip0,
double* op,
int l0 )
431 int b =
min( UpSkip, l0 );
450 int l = l0 / UpFactor;
451 int lz = l0 - l * UpFactor;
452 const int upf = UpFactor;
488 for( j = 1; j < upf; j++ )
504 UpSkip = UpFactor - lz;
529 void copyToOutput(
int Offs,
double*& op0,
int b,
int& l0 )
539 copyToOutput( Offs + BlockLen2, op0, -Offs, l0 );
545 if( LatencyLeft > 0 )
547 if( LatencyLeft >= b )
558 const int df = DownFactor;
562 int Skip = Offs & ( df - 1 );
573 b = ( b + df - 1 ) >> DownShift;
574 memcpy( op0, &CurOutput[ Offs >> DownShift ],
575 b *
sizeof(
double ));
585 const double* ip = &CurOutput[ Offs + DownSkip ];
586 int l = ( b + df - 1 - DownSkip ) / df;
587 DownSkip += l * df - b;
603 memcpy( op0, &CurOutput[ Offs ], b *
sizeof(
double ));
619 void mirrorInputSpectrum( T*
const p )
621 const int bl1 = BlockLen2 >> UpShift;
622 const int bl2 = bl1 + bl1;
625 for( i = bl1 + 2; i < bl2; i += 2 )
627 p[ i ] = p[ bl2 - i ];
628 p[ i + 1 ] = -p[ bl2 - i + 1 ];
635 for( i = 1; i < UpShift; i++ )
637 const int z = bl1 << i;
638 memcpy( &p[ z ], p, z *
sizeof( T ));
646 #endif // R8B_CDSPBLOCKCONVOLVER_INCLUDED int getBitOccupancy(const int v)
Definition: r8bbase.h:775
#define R8BCONSOLE(...)
Console output macro, used to output various resampler status strings, including filter design parame...
Definition: r8bconf.h:85
virtual int getLatency() const
Definition: CDSPBlockConvolver.h:191
#define R8BASSERT(e)
Assertion macro used to check for certain run-time conditions.
Definition: r8bconf.h:72
Pointer-to-object "keeper" class with automatic deletion.
Definition: r8bbase.h:429
Calculation and storage class for FIR filters.
Definition: CDSPFIRFilter.h:57
The base virtual class for DSP processing algorithms.
virtual void clear()
Function clears (resets) the state of *this object and returns it to the state after construction...
Definition: CDSPBlockConvolver.h:208
CDSPBlockConvolver(CDSPFIRFilter &aFilter, const int aUpFactor, const int aDownFactor, const double PrevLatency=0.0, const bool aDoConsumeLatency=true)
Constructor initializes internal variables and constants of *this object.
Definition: CDSPBlockConvolver.h:62
T min(const T &v1, const T &v2)
Definition: r8bbase.h:1118
Single-block overlap-save convolution processing class.
Definition: CDSPBlockConvolver.h:38
virtual double getLatencyFrac() const
Definition: CDSPBlockConvolver.h:196
A "keeper" class for real-valued FFT transform objects.
Definition: CDSPRealFFT.h:461
virtual int process(double *ip, int l0, double *&op0)
Function performs DSP processing.
Definition: CDSPBlockConvolver.h:242
FIR filter generator and filter cache classes.
virtual int getMaxOutLen(const int MaxInLen) const
Definition: CDSPBlockConvolver.h:201
The base virtual class for DSP processing algorithms.
Definition: CDSPProcessor.h:31
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21
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