Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
401
Src/external_dependencies/openmpt-trunk/include/r8brain/CDSPHBDownsampler.h
vendored
Normal file
401
Src/external_dependencies/openmpt-trunk/include/r8brain/CDSPHBDownsampler.h
vendored
Normal file
|
@ -0,0 +1,401 @@
|
|||
//$ nobt
|
||||
//$ nocpp
|
||||
|
||||
/**
|
||||
* @file CDSPHBDownsampler.h
|
||||
*
|
||||
* @brief Half-band downsampling convolver class.
|
||||
*
|
||||
* This file includes half-band downsampling convolver class.
|
||||
*
|
||||
* r8brain-free-src Copyright (c) 2013-2022 Aleksey Vaneev
|
||||
* See the "LICENSE" file for license.
|
||||
*/
|
||||
|
||||
#ifndef R8B_CDSPHBDOWNSAMPLER_INCLUDED
|
||||
#define R8B_CDSPHBDOWNSAMPLER_INCLUDED
|
||||
|
||||
#include "CDSPHBUpsampler.h"
|
||||
|
||||
namespace r8b {
|
||||
|
||||
/**
|
||||
* @brief Half-band downsampler class.
|
||||
*
|
||||
* Class implements brute-force half-band 2X downsampling that uses small
|
||||
* sparse symmetric FIR filters. The output has 2.0 gain.
|
||||
*/
|
||||
|
||||
class CDSPHBDownsampler : public CDSPProcessor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor initalizes the half-band downsampler.
|
||||
*
|
||||
* @param ReqAtten Required half-band filter attentuation.
|
||||
* @param SteepIndex Steepness index - 0=steepest. Corresponds to general
|
||||
* downsampling ratio, e.g. at 4x downsampling 0 is used, at 8x
|
||||
* downsampling 1 is used, etc.
|
||||
* @param IsThird "True" if 1/3 resampling is performed.
|
||||
* @param PrevLatency Latency, in samples (any value >=0), which was left
|
||||
* in the output signal by a previous process. Whole-number latency will
|
||||
* be consumed by *this object while remaining fractional latency can be
|
||||
* obtained via the getLatencyFrac() function.
|
||||
*/
|
||||
|
||||
CDSPHBDownsampler( const double ReqAtten, const int SteepIndex,
|
||||
const bool IsThird, const double PrevLatency )
|
||||
{
|
||||
static const CConvolveFn FltConvFn[ 14 ] = {
|
||||
&CDSPHBDownsampler :: convolve1, &CDSPHBDownsampler :: convolve2,
|
||||
&CDSPHBDownsampler :: convolve3, &CDSPHBDownsampler :: convolve4,
|
||||
&CDSPHBDownsampler :: convolve5, &CDSPHBDownsampler :: convolve6,
|
||||
&CDSPHBDownsampler :: convolve7, &CDSPHBDownsampler :: convolve8,
|
||||
&CDSPHBDownsampler :: convolve9, &CDSPHBDownsampler :: convolve10,
|
||||
&CDSPHBDownsampler :: convolve11, &CDSPHBDownsampler :: convolve12,
|
||||
&CDSPHBDownsampler :: convolve13,
|
||||
&CDSPHBDownsampler :: convolve14 };
|
||||
|
||||
int fltt;
|
||||
double att;
|
||||
|
||||
if( IsThird )
|
||||
{
|
||||
CDSPHBUpsampler :: getHBFilterThird( ReqAtten, SteepIndex, fltp,
|
||||
fltt, att );
|
||||
}
|
||||
else
|
||||
{
|
||||
CDSPHBUpsampler :: getHBFilter( ReqAtten, SteepIndex, fltp, fltt,
|
||||
att );
|
||||
}
|
||||
|
||||
convfn = FltConvFn[ fltt - 1 ];
|
||||
fll = fltt * 2 - 1;
|
||||
fl2 = fll;
|
||||
flo = fll + fl2;
|
||||
flb = BufLen - fll;
|
||||
BufRP = Buf + fll;
|
||||
|
||||
LatencyFrac = PrevLatency * 0.5;
|
||||
Latency = (int) LatencyFrac;
|
||||
LatencyFrac -= Latency;
|
||||
|
||||
R8BASSERT( Latency >= 0 );
|
||||
|
||||
R8BCONSOLE( "CDSPHBDownsampler: taps=%i third=%i att=%.1f io=1/2\n",
|
||||
fltt, (int) IsThird, att );
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
virtual int getLatency() const
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
virtual double getLatencyFrac() const
|
||||
{
|
||||
return( LatencyFrac );
|
||||
}
|
||||
|
||||
virtual int getMaxOutLen( const int MaxInLen ) const
|
||||
{
|
||||
R8BASSERT( MaxInLen >= 0 );
|
||||
|
||||
return(( MaxInLen + 1 ) >> 1 );
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
LatencyLeft = Latency;
|
||||
BufLeft = 0;
|
||||
WritePos = 0;
|
||||
ReadPos = flb; // Set "read" position to account for filter's latency.
|
||||
|
||||
memset( &Buf[ ReadPos ], 0, ( BufLen - flb ) * sizeof( Buf[ 0 ]));
|
||||
}
|
||||
|
||||
virtual int process( double* ip, int l, double*& op0 )
|
||||
{
|
||||
R8BASSERT( l >= 0 );
|
||||
|
||||
double* op = op0;
|
||||
|
||||
while( l > 0 )
|
||||
{
|
||||
// Add new input samples to both halves of the ring buffer.
|
||||
|
||||
const int b = min( min( l, BufLen - WritePos ), flb - BufLeft );
|
||||
|
||||
double* const wp1 = Buf + WritePos;
|
||||
memcpy( wp1, ip, b * sizeof( wp1[ 0 ]));
|
||||
|
||||
if( WritePos < flo )
|
||||
{
|
||||
const int c = min( b, flo - WritePos );
|
||||
memcpy( wp1 + BufLen, wp1, c * sizeof( wp1[ 0 ]));
|
||||
}
|
||||
|
||||
ip += b;
|
||||
WritePos = ( WritePos + b ) & BufLenMask;
|
||||
l -= b;
|
||||
BufLeft += b;
|
||||
|
||||
// Produce output.
|
||||
|
||||
if( BufLeft > fl2 )
|
||||
{
|
||||
const int c = ( BufLeft - fl2 + 1 ) >> 1;
|
||||
|
||||
double* const opend = op + c;
|
||||
( *convfn )( op, opend, fltp, BufRP, ReadPos );
|
||||
|
||||
op = opend;
|
||||
const int c2 = c + c;
|
||||
ReadPos = ( ReadPos + c2 ) & BufLenMask;
|
||||
BufLeft -= c2;
|
||||
}
|
||||
}
|
||||
|
||||
int ol = (int) ( op - op0 );
|
||||
|
||||
if( LatencyLeft != 0 )
|
||||
{
|
||||
if( LatencyLeft >= ol )
|
||||
{
|
||||
LatencyLeft -= ol;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
ol -= LatencyLeft;
|
||||
op0 += LatencyLeft;
|
||||
LatencyLeft = 0;
|
||||
}
|
||||
|
||||
return( ol );
|
||||
}
|
||||
|
||||
private:
|
||||
static const int BufLenBits = 10; ///< The length of the ring buffer,
|
||||
///< expressed as Nth power of 2. This value can be reduced if it is
|
||||
///< known that only short input buffers will be passed to the
|
||||
///< interpolator. The minimum value of this parameter is 5, and
|
||||
///< 1 << BufLenBits should be at least 3 times larger than the
|
||||
///< FilterLen.
|
||||
///<
|
||||
static const int BufLen = 1 << BufLenBits; ///< The length of the ring
|
||||
///< buffer. The actual length is twice as long to allow "beyond max
|
||||
///< position" positioning.
|
||||
///<
|
||||
static const int BufLenMask = BufLen - 1; ///< Mask used for quick buffer
|
||||
///< position wrapping.
|
||||
///<
|
||||
double Buf[ BufLen + 54 ]; ///< The ring buffer, including overrun
|
||||
///< protection for the largest filter.
|
||||
///<
|
||||
const double* fltp; ///< Half-band filter taps.
|
||||
///<
|
||||
int fll; ///< Input latency.
|
||||
///<
|
||||
int fl2; ///< Right-side filter length.
|
||||
///<
|
||||
int flo; ///< Overrun length.
|
||||
///<
|
||||
int flb; ///< Initial read position and maximal buffer write length.
|
||||
///<
|
||||
const double* BufRP; ///< Offseted Buf pointer at ReadPos=0.
|
||||
///<
|
||||
int Latency; ///< Initial latency that should be removed from the output.
|
||||
///<
|
||||
double LatencyFrac; ///< Fractional latency left on the output.
|
||||
///<
|
||||
int BufLeft; ///< The number of samples left in the buffer to process.
|
||||
///< When this value is below FilterLenD2Plus1, the interpolation
|
||||
///< cycle ends.
|
||||
///<
|
||||
int WritePos; ///< The current buffer write position. Incremented together
|
||||
///< with the BufLeft variable.
|
||||
///<
|
||||
int ReadPos; ///< The current buffer read position.
|
||||
///<
|
||||
int LatencyLeft; ///< Latency left to remove.
|
||||
///<
|
||||
typedef void( *CConvolveFn )( double* op, double* const opend,
|
||||
const double* const flt, const double* const rp0, int rpos ); ///<
|
||||
///< Convolution function type.
|
||||
///<
|
||||
CConvolveFn convfn; ///< Convolution function in use.
|
||||
///<
|
||||
|
||||
#define R8BHBC1( fn ) \
|
||||
static void fn( double* op, double* const opend, const double* const flt, \
|
||||
const double* const rp0, int rpos ) \
|
||||
{ \
|
||||
while( op != opend ) \
|
||||
{ \
|
||||
const double* const rp = rp0 + rpos; \
|
||||
*op = rp[ 0 ] +
|
||||
|
||||
#define R8BHBC2 \
|
||||
rpos = ( rpos + 2 ) & BufLenMask; \
|
||||
op++; \
|
||||
} \
|
||||
}
|
||||
|
||||
R8BHBC1( convolve1 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve2 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve3 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve4 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve5 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve6 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve7 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
|
||||
flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve8 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
|
||||
flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
|
||||
flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve9 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
|
||||
flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
|
||||
flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
|
||||
flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve10 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
|
||||
flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
|
||||
flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
|
||||
flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
|
||||
flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve11 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
|
||||
flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
|
||||
flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
|
||||
flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
|
||||
flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]) +
|
||||
flt[ 10 ] * ( rp[ 21 ] + rp[ -21 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve12 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
|
||||
flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
|
||||
flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
|
||||
flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
|
||||
flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]) +
|
||||
flt[ 10 ] * ( rp[ 21 ] + rp[ -21 ]) +
|
||||
flt[ 11 ] * ( rp[ 23 ] + rp[ -23 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve13 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
|
||||
flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
|
||||
flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
|
||||
flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
|
||||
flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]) +
|
||||
flt[ 10 ] * ( rp[ 21 ] + rp[ -21 ]) +
|
||||
flt[ 11 ] * ( rp[ 23 ] + rp[ -23 ]) +
|
||||
flt[ 12 ] * ( rp[ 25 ] + rp[ -25 ]);
|
||||
R8BHBC2
|
||||
|
||||
R8BHBC1( convolve14 )
|
||||
flt[ 0 ] * ( rp[ 1 ] + rp[ -1 ]) +
|
||||
flt[ 1 ] * ( rp[ 3 ] + rp[ -3 ]) +
|
||||
flt[ 2 ] * ( rp[ 5 ] + rp[ -5 ]) +
|
||||
flt[ 3 ] * ( rp[ 7 ] + rp[ -7 ]) +
|
||||
flt[ 4 ] * ( rp[ 9 ] + rp[ -9 ]) +
|
||||
flt[ 5 ] * ( rp[ 11 ] + rp[ -11 ]) +
|
||||
flt[ 6 ] * ( rp[ 13 ] + rp[ -13 ]) +
|
||||
flt[ 7 ] * ( rp[ 15 ] + rp[ -15 ]) +
|
||||
flt[ 8 ] * ( rp[ 17 ] + rp[ -17 ]) +
|
||||
flt[ 9 ] * ( rp[ 19 ] + rp[ -19 ]) +
|
||||
flt[ 10 ] * ( rp[ 21 ] + rp[ -21 ]) +
|
||||
flt[ 11 ] * ( rp[ 23 ] + rp[ -23 ]) +
|
||||
flt[ 12 ] * ( rp[ 25 ] + rp[ -25 ]) +
|
||||
flt[ 13 ] * ( rp[ 27 ] + rp[ -27 ]);
|
||||
R8BHBC2
|
||||
|
||||
#undef R8BHBC1
|
||||
#undef R8BHBC2
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
} // namespace r8b
|
||||
|
||||
#endif // R8B_CDSPHBDOWNSAMPLER_INCLUDED
|
Loading…
Add table
Add a link
Reference in a new issue