cwDspTransforms.h/cpp,cwDspFlow.cpp,cwFlowProc.cpp : Added limiter and DC filter.

This commit is contained in:
kevin 2022-12-05 17:21:54 -05:00
parent b680d46487
commit 859df98d12
4 changed files with 146 additions and 0 deletions

View File

@ -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 ) 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>(); 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; 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 ) cw::rc_t cw::dsp::recorder::create( obj_t*& pRef, real_t srate, real_t max_secs, unsigned chN )
{ {

View File

@ -46,6 +46,40 @@ namespace cw
void set_rms_wnd_ms( obj_t* p, real_t ms ); 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 namespace recorder
{ {
typedef struct typedef struct

View File

@ -37,7 +37,9 @@ namespace cw
{ "pv_synthesis", &pv_synthesis::members }, { "pv_synthesis", &pv_synthesis::members },
{ "spec_dist", &spec_dist::members }, { "spec_dist", &spec_dist::members },
{ "compressor", &compressor::members }, { "compressor", &compressor::members },
{ "limiter", &limiter::members },
{ "audio_delay", &audio_delay::members }, { "audio_delay", &audio_delay::members },
{ "dc_filter", &dc_filter::members },
{ "balance", &balance::members }, { "balance", &balance::members },
{ nullptr, nullptr } { nullptr, nullptr }
}; };

View File

@ -16,7 +16,9 @@ namespace cw
namespace pv_synthesis { extern class_members_t members; } namespace pv_synthesis { extern class_members_t members; }
namespace spec_dist { extern class_members_t members; } namespace spec_dist { extern class_members_t members; }
namespace compressor { 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 audio_delay { extern class_members_t members; }
namespace dc_filter { extern class_members_t members; }
namespace balance { extern class_members_t members; } namespace balance { extern class_members_t members; }
} }
} }