cwDspTransforms.h/cpp,cwDspFlow.cpp,cwFlowProc.cpp : Added limiter and DC filter.
This commit is contained in:
parent
b680d46487
commit
859df98d12
@ -29,6 +29,10 @@ namespace cw
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
// compressor
|
||||
//
|
||||
|
||||
cw::rc_t cw::dsp::compressor::create( obj_t*& p, real_t srate, unsigned procSmpCnt, real_t inGain, real_t rmsWndMaxMs, real_t rmsWndMs, real_t threshDb, real_t ratio_num, real_t atkMs, real_t rlsMs, real_t outGain, bool bypassFl )
|
||||
{
|
||||
p = mem::allocZ<obj_t>();
|
||||
@ -162,7 +166,111 @@ void cw::dsp::compressor::set_rms_wnd_ms( obj_t* p, real_t ms )
|
||||
p->rmsWndCnt = p->rmsWndAllocCnt;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
// Limiter
|
||||
//
|
||||
|
||||
cw::rc_t cw::dsp::limiter::create( obj_t*& p, real_t srate, unsigned procSmpCnt, real_t thresh, real_t igain, real_t ogain, bool bypassFl )
|
||||
{
|
||||
p = mem::allocZ<obj_t>();
|
||||
|
||||
p->procSmpCnt = procSmpCnt;
|
||||
p->thresh = thresh;
|
||||
p->igain = igain;
|
||||
p->ogain = ogain;
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
cw::rc_t cw::dsp::limiter::destroy( obj_t*& p )
|
||||
{
|
||||
mem::release(p);
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
cw::rc_t cw::dsp::limiter::exec( obj_t* p, const sample_t* x, sample_t* y, unsigned n )
|
||||
{
|
||||
if( p->bypassFl )
|
||||
{
|
||||
vop::copy(y,x,n); // copy through - with no input gain
|
||||
return kOkRC;
|
||||
}
|
||||
else
|
||||
{
|
||||
real_t T = p->thresh * p->ogain;
|
||||
|
||||
for(unsigned i=0; i<n; ++i)
|
||||
{
|
||||
sample_t mx = 0.999;
|
||||
sample_t s = x[i] < 0.0 ? -mx : mx;
|
||||
sample_t v = fabsf(x[i]) * p->igain;
|
||||
|
||||
if( v >= mx )
|
||||
y[i] = s;
|
||||
else
|
||||
{
|
||||
if( v < p->thresh )
|
||||
{
|
||||
y[i] = s * T * v/p->thresh;
|
||||
}
|
||||
else
|
||||
{
|
||||
// apply a linear limiting function
|
||||
y[i] = s * (T + (1.0f-T) * (v-p->thresh)/(1.0f-p->thresh));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
// dc-filter
|
||||
//
|
||||
|
||||
cw::rc_t cw::dsp::dc_filter::create( obj_t*& p, real_t srate, unsigned procSmpCnt, real_t gain, bool bypassFl )
|
||||
{
|
||||
p = mem::allocZ<obj_t>();
|
||||
|
||||
p->gain = gain;
|
||||
p->bypassFl = bypassFl;
|
||||
p->b0 = 1;
|
||||
p->b[0] = -1;
|
||||
p->a[0] = -0.999;
|
||||
p->d[0] = 0;
|
||||
p->d[1] = 0;
|
||||
|
||||
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
cw::rc_t cw::dsp::dc_filter::destroy( obj_t*& pp )
|
||||
{
|
||||
mem::release(pp);
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
cw::rc_t cw::dsp::dc_filter::exec( obj_t* p, const sample_t* x, sample_t* y, unsigned n )
|
||||
{
|
||||
|
||||
if( p->bypassFl )
|
||||
vop::copy(y,x,n);
|
||||
else
|
||||
vop::filter<sample_t,real_t>(y,n,x,n,p->b0, p->b, p->a, p->d, 1 );
|
||||
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
cw::rc_t cw::dsp::dc_filter::set( obj_t* p, real_t gain, bool bypassFl )
|
||||
{
|
||||
p->gain = gain;
|
||||
p->bypassFl = bypassFl;
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
// Recorder
|
||||
//
|
||||
|
||||
cw::rc_t cw::dsp::recorder::create( obj_t*& pRef, real_t srate, real_t max_secs, unsigned chN )
|
||||
{
|
||||
|
@ -46,6 +46,40 @@ namespace cw
|
||||
void set_rms_wnd_ms( obj_t* p, real_t ms );
|
||||
}
|
||||
|
||||
namespace limiter
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
unsigned procSmpCnt;
|
||||
real_t igain; // applied before thresholding
|
||||
real_t thresh; // linear (0.0-1.0) threshold.
|
||||
real_t ogain; // applied after thresholding
|
||||
bool bypassFl;
|
||||
} obj_t;
|
||||
|
||||
rc_t create( obj_t*& p, real_t srate, unsigned procSmpCnt, real_t thresh, real_t igain, real_t ogain, bool bypassFl );
|
||||
rc_t destroy( obj_t*& pp );
|
||||
rc_t exec( obj_t* p, const sample_t* x, sample_t* y, unsigned n );
|
||||
}
|
||||
|
||||
namespace dc_filter
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
real_t d[2]; //
|
||||
real_t b[1]; //
|
||||
real_t a[1]; // a[dn] feedback coeff's
|
||||
real_t b0; // feedforward coeff 0
|
||||
bool bypassFl;
|
||||
real_t gain;
|
||||
} obj_t;
|
||||
|
||||
rc_t create( obj_t*& p, real_t srate, unsigned procSmpCnt, real_t gain, bool bypassFl );
|
||||
rc_t destroy( obj_t*& pp );
|
||||
rc_t exec( obj_t* p, const sample_t* x, sample_t* y, unsigned n );
|
||||
rc_t set( obj_t* p, real_t gain, bool bypassFl );
|
||||
}
|
||||
|
||||
namespace recorder
|
||||
{
|
||||
typedef struct
|
||||
|
@ -37,7 +37,9 @@ namespace cw
|
||||
{ "pv_synthesis", &pv_synthesis::members },
|
||||
{ "spec_dist", &spec_dist::members },
|
||||
{ "compressor", &compressor::members },
|
||||
{ "limiter", &limiter::members },
|
||||
{ "audio_delay", &audio_delay::members },
|
||||
{ "dc_filter", &dc_filter::members },
|
||||
{ "balance", &balance::members },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
@ -16,7 +16,9 @@ namespace cw
|
||||
namespace pv_synthesis { extern class_members_t members; }
|
||||
namespace spec_dist { extern class_members_t members; }
|
||||
namespace compressor { extern class_members_t members; }
|
||||
namespace limiter { extern class_members_t members; }
|
||||
namespace audio_delay { extern class_members_t members; }
|
||||
namespace dc_filter { extern class_members_t members; }
|
||||
namespace balance { extern class_members_t members; }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user