Updates in preparation for variable length FT windows.

This commit is contained in:
kevin 2022-12-05 17:19:58 -05:00
parent df3a948608
commit d034b87f51
9 changed files with 434 additions and 48 deletions

View File

@ -119,7 +119,7 @@ namespace cw
for(unsigned i=0; i<p->chCnt; ++i) for(unsigned i=0; i<p->chCnt; ++i)
{ {
if((rc = dsp::pv_anl::create( p->anlA[i], p->procSmpN, ctx->srcSrate, p->wndSmpN, p->hopSmpN, dsp::pv_anl::kNoCalcHzPvaFl )) != kOkRC ) if((rc = dsp::pv_anl::create( p->anlA[i], p->procSmpN, ctx->srcSrate, p->wndSmpN, p->wndSmpN, p->hopSmpN, dsp::pv_anl::kNoCalcHzPvaFl )) != kOkRC )
{ {
rc = cwLogError(rc,"PVOC analysis component create failed."); rc = cwLogError(rc,"PVOC analysis component create failed.");
goto errLabel; goto errLabel;

View File

@ -234,7 +234,7 @@ namespace cw
unsigned flags = kCalcHzPvaFl; unsigned flags = kCalcHzPvaFl;
unsigned wndTypeId = wnd_func::kHannWndId; unsigned wndTypeId = wnd_func::kHannWndId;
if((rc = create( pva, procSmpCnt, srate, wndSmpCnt, hopSmpCnt, flags )) != kOkRC ) if((rc = create( pva, procSmpCnt, srate, wndSmpCnt, wndSmpCnt, hopSmpCnt, flags )) != kOkRC )
{ {
} }

View File

@ -500,6 +500,10 @@ namespace cw
unsigned flags; unsigned flags;
unsigned procSmpCnt; unsigned procSmpCnt;
T srate; T srate;
unsigned maxWndSmpCnt;
unsigned maxBinCnt;
unsigned wndSmpCnt; unsigned wndSmpCnt;
unsigned hopSmpCnt; unsigned hopSmpCnt;
unsigned binCnt; unsigned binCnt;
@ -514,7 +518,7 @@ namespace cw
typedef obj_str< double> dobj_t; typedef obj_str< double> dobj_t;
template< typename T > template< typename T >
rc_t create( struct obj_str<T>*& p, unsigned procSmpCnt, const T& srate, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned flags ) rc_t create( struct obj_str<T>*& p, unsigned procSmpCnt, const T& srate, unsigned maxWndSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt, unsigned flags )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -527,6 +531,8 @@ namespace cw
p->flags = flags; p->flags = flags;
p->procSmpCnt = procSmpCnt; p->procSmpCnt = procSmpCnt;
p->maxWndSmpCnt = maxWndSmpCnt;
p->maxBinCnt = fft::window_sample_count_to_bin_count(maxWndSmpCnt);
p->wndSmpCnt = wndSmpCnt; p->wndSmpCnt = wndSmpCnt;
p->hopSmpCnt = hopSmpCnt; p->hopSmpCnt = hopSmpCnt;
p->binCnt = p->ft->binN; p->binCnt = p->ft->binN;

View File

@ -12,6 +12,12 @@
// fft // fft
// //
unsigned cw::dsp::fft::window_sample_count_to_bin_count( unsigned wndSmpN )
{ return wndSmpN/2 + 1; }
unsigned cw::dsp::fft::bin_count_to_window_sample_count( unsigned binN )
{ return (binN-1) * 2; }
cw::rc_t cw::dsp::fft::test() cw::rc_t cw::dsp::fft::test()
{ {
typedef float real_t; typedef float real_t;

View File

@ -196,6 +196,10 @@ namespace cw
namespace fft namespace fft
{ {
unsigned window_sample_count_to_bin_count( unsigned wndSmpN );
unsigned bin_count_to_window_sample_count( unsigned binN );
enum enum
{ {
kToPolarFl = 0x01, // convert to polar (magn./phase) kToPolarFl = 0x01, // convert to polar (magn./phase)
@ -231,7 +235,7 @@ namespace cw
p->flags = flags; p->flags = flags;
p->inN = xN; p->inN = xN;
p->binN = xN/2 + 1; p->binN = window_sample_count_to_bin_count(xN);
p->magV = mem::allocZ<T>(p->binN); p->magV = mem::allocZ<T>(p->binN);
p->phsV = mem::allocZ<T>(p->binN); p->phsV = mem::allocZ<T>(p->binN);
@ -368,7 +372,7 @@ namespace cw
p = mem::allocZ< obj_str<T> >(1); p = mem::allocZ< obj_str<T> >(1);
p->binN = binN; p->binN = binN;
p->outN = (binN-1)*2; p->outN = fft::bin_count_to_window_sample_count(binN);
if( std::is_same<T,float>::value ) if( std::is_same<T,float>::value )
{ {

View File

@ -1396,8 +1396,9 @@ namespace cw
enum { enum {
kInPId, kInPId,
kHopSmpNPId, kMaxWndSmpNPId,
kWndSmpNPId, kWndSmpNPId,
kHopSmpNPId,
kHzFlPId, kHzFlPId,
kOutPId kOutPId
}; };
@ -1406,6 +1407,7 @@ namespace cw
{ {
pv_t** pvA; // pvA[ srcBuf.chN ] pv_t** pvA; // pvA[ srcBuf.chN ]
unsigned pvN; unsigned pvN;
unsigned maxWndSmpN;
unsigned wndSmpN; unsigned wndSmpN;
unsigned hopSmpN; unsigned hopSmpN;
bool hzFl; bool hzFl;
@ -1422,8 +1424,9 @@ namespace cw
if((rc = var_register_and_get( ctx, kAnyChIdx, if((rc = var_register_and_get( ctx, kAnyChIdx,
kInPId, "in", srcBuf, kInPId, "in", srcBuf,
kHopSmpNPId, "hopSmpN", inst->hopSmpN, kMaxWndSmpNPId, "maxWndSmpN", inst->maxWndSmpN,
kWndSmpNPId, "wndSmpN", inst->wndSmpN, kWndSmpNPId, "wndSmpN", inst->wndSmpN,
kHopSmpNPId, "hopSmpN", inst->hopSmpN,
kHzFlPId, "hzFl", inst->hzFl )) != kOkRC ) kHzFlPId, "hzFl", inst->hzFl )) != kOkRC )
{ {
goto errLabel; goto errLabel;
@ -1441,7 +1444,7 @@ namespace cw
// create a pv anlaysis object for each input channel // create a pv anlaysis object for each input channel
for(unsigned i=0; i<srcBuf->chN; ++i) for(unsigned i=0; i<srcBuf->chN; ++i)
{ {
if((rc = create( inst->pvA[i], ctx->ctx->framesPerCycle, srcBuf->srate, inst->wndSmpN, inst->hopSmpN, flags )) != kOkRC ) if((rc = create( inst->pvA[i], ctx->ctx->framesPerCycle, srcBuf->srate, inst->maxWndSmpN, inst->wndSmpN, inst->hopSmpN, flags )) != kOkRC )
{ {
rc = cwLogError(kOpFailRC,"The PV analysis object create failed on the instance '%s'.",ctx->label); rc = cwLogError(kOpFailRC,"The PV analysis object create failed on the instance '%s'.",ctx->label);
goto errLabel; goto errLabel;
@ -1456,7 +1459,7 @@ namespace cw
goto errLabel; goto errLabel;
// create the fbuf 'out' // create the fbuf 'out'
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, inst->pvA[0]->binCnt, inst->pvA[0]->hopSmpCnt, magV, phsV, hzV ); rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, inst->pvA[0]->maxBinCnt, srcBuf->chN, inst->pvA[0]->binCnt, inst->pvA[0]->hopSmpCnt, magV, phsV, hzV );
} }
@ -1515,7 +1518,7 @@ namespace cw
if( dsp::pv_anl::exec( inst->pvA[i], srcBuf->buf + i*srcBuf->frameN, srcBuf->frameN ) ) if( dsp::pv_anl::exec( inst->pvA[i], srcBuf->buf + i*srcBuf->frameN, srcBuf->frameN ) )
{ {
// rescale the frequency domain magnitude // rescale the frequency domain magnitude
vop::mul(dstBuf->magV[i], dstBuf->binN/2, dstBuf->binN); vop::mul(dstBuf->magV[i], dstBuf->binN_V[i]/2, dstBuf->binN_V[i]);
dstBuf->readyFlV[i] = true; dstBuf->readyFlV[i] = true;
@ -1580,9 +1583,9 @@ namespace cw
// create a pv anlaysis object for each input channel // create a pv anlaysis object for each input channel
for(unsigned i=0; i<srcBuf->chN; ++i) for(unsigned i=0; i<srcBuf->chN; ++i)
{ {
unsigned wndSmpN = (srcBuf->binN-1)*2; unsigned wndSmpN = (srcBuf->binN_V[i]-1)*2;
if((rc = create( inst->pvA[i], ctx->ctx->framesPerCycle, srcBuf->srate, wndSmpN, srcBuf->hopSmpN )) != kOkRC ) if((rc = create( inst->pvA[i], ctx->ctx->framesPerCycle, srcBuf->srate, wndSmpN, srcBuf->hopSmpN_V[i] )) != kOkRC )
{ {
rc = cwLogError(kOpFailRC,"The PV synthesis object create failed on the instance '%s'.",ctx->label); rc = cwLogError(kOpFailRC,"The PV synthesis object create failed on the instance '%s'.",ctx->label);
goto errLabel; goto errLabel;
@ -1719,7 +1722,7 @@ namespace cw
// create a spec_dist object for each input channel // create a spec_dist object for each input channel
for(unsigned i=0; i<srcBuf->chN; ++i) for(unsigned i=0; i<srcBuf->chN; ++i)
{ {
if((rc = create( inst->sdA[i], srcBuf->binN )) != kOkRC ) if((rc = create( inst->sdA[i], srcBuf->binN_V[i] )) != kOkRC )
{ {
rc = cwLogError(kOpFailRC,"The 'spec dist' object create failed on the instance '%s'.",ctx->label); rc = cwLogError(kOpFailRC,"The 'spec dist' object create failed on the instance '%s'.",ctx->label);
goto errLabel; goto errLabel;
@ -1746,7 +1749,7 @@ namespace cw
} }
// create the output buffer // create the output buffer
if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->binN, srcBuf->hopSmpN, magV, phsV, hzV )) != kOkRC ) if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->maxBinN, srcBuf->chN, srcBuf->binN_V, srcBuf->hopSmpN_V, magV, phsV, hzV )) != kOkRC )
goto errLabel; goto errLabel;
} }
@ -1820,7 +1823,7 @@ namespace cw
dstBuf->readyFlV[i] = false; dstBuf->readyFlV[i] = false;
if( srcBuf->readyFlV[i] ) if( srcBuf->readyFlV[i] )
{ {
dsp::spec_dist::exec( inst->sdA[i], srcBuf->magV[i], srcBuf->phsV[i], srcBuf->binN ); dsp::spec_dist::exec( inst->sdA[i], srcBuf->magV[i], srcBuf->phsV[i], srcBuf->binN_V[i] );
dstBuf->readyFlV[i] = true; dstBuf->readyFlV[i] = true;
//If == 0 ) //If == 0 )
@ -1897,7 +1900,8 @@ namespace cw
// create a compressor object for each input channel // create a compressor object for each input channel
for(unsigned i=0; i<srcBuf->chN; ++i) for(unsigned i=0; i<srcBuf->chN; ++i)
{ {
real_t igain, maxWnd_ms, wnd_ms, thresh, ratio, atk_ms, rls_ms, ogain, bypassFl; real_t igain, maxWnd_ms, wnd_ms, thresh, ratio, atk_ms, rls_ms, ogain;
bool bypassFl;
// get the compressor variable values // get the compressor variable values
@ -2033,6 +2037,184 @@ namespace cw
}; };
} }
//------------------------------------------------------------------------------------------------------------------
//
// Limiter
//
namespace limiter
{
enum
{
kInPId,
kBypassPId,
kInGainPId,
kThreshPId,
kOutGainPId,
kOutPId,
};
typedef dsp::limiter::obj_t limiter_t;
typedef struct
{
limiter_t** limA;
unsigned limN;
} inst_t;
rc_t create( instance_t* ctx )
{
rc_t rc = kOkRC;
const abuf_t* srcBuf = nullptr; //
inst_t* inst = mem::allocZ<inst_t>();
ctx->userPtr = inst;
// verify that a source buffer exists
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",srcBuf )) != kOkRC )
{
rc = cwLogError(rc,"The instance '%s' does not have a valid input connection.",ctx->label);
goto errLabel;
}
else
{
// allocate pv channel array
inst->limN = srcBuf->chN;
inst->limA = mem::allocZ<limiter_t*>( inst->limN );
// create a limiter object for each input channel
for(unsigned i=0; i<srcBuf->chN; ++i)
{
real_t igain, thresh, ogain;
bool bypassFl;
// get the limiter variable values
if((rc = var_register_and_get( ctx, i,
kBypassPId, "bypass", bypassFl,
kInGainPId, "igain", igain,
kThreshPId, "thresh", thresh,
kOutGainPId, "ogain", ogain )) != kOkRC )
{
goto errLabel;
}
// create the limiter instance
if((rc = dsp::limiter::create( inst->limA[i], srcBuf->srate, srcBuf->frameN, igain, thresh, ogain, bypassFl)) != kOkRC )
{
rc = cwLogError(kOpFailRC,"The 'limiter' object create failed on the instance '%s'.",ctx->label);
goto errLabel;
}
}
// create the output audio buffer
if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->frameN )) != kOkRC )
goto errLabel;
}
errLabel:
return rc;
}
rc_t destroy( instance_t* ctx )
{
rc_t rc = kOkRC;
inst_t* inst = (inst_t*)ctx->userPtr;
for(unsigned i=0; i<inst->limN; ++i)
destroy(inst->limA[i]);
mem::release(inst->limA);
mem::release(inst);
return rc;
}
rc_t value( instance_t* ctx, variable_t* var )
{
rc_t rc = kOkRC;
inst_t* inst = (inst_t*)ctx->userPtr;
real_t rtmp;
bool btmp;
if( var->chIdx != kAnyChIdx && var->chIdx < inst->limN )
{
limiter_t* c = inst->limA[ var->chIdx ];
switch( var->vid )
{
case kBypassPId: rc = var_get( var, btmp ); c->bypassFl=btmp; break;
case kInGainPId: rc = var_get( var, rtmp ); c->igain=rtmp; break;
case kOutGainPId: rc = var_get( var, rtmp ); c->ogain=rtmp; break;
case kThreshPId: rc = var_get( var, rtmp ); c->thresh=rtmp; break;
default:
cwLogWarning("Unhandled variable id '%i' on instance: %s.", var->vid, ctx->label );
}
//printf("lim byp:%i igain:%f ogain:%f rat:%f thresh:%f atk:%i rls:%i wnd:%i : rc:%i val:%f\n",
// c->bypassFl, c->inGain, c->outGain,c->ratio_num,c->threshDb,c->atkSmp,c->rlsSmp,c->rmsWndCnt,rc,tmp);
}
return rc;
}
rc_t exec( instance_t* ctx )
{
rc_t rc = kOkRC;
inst_t* inst = (inst_t*)ctx->userPtr;
const abuf_t* srcBuf = nullptr;
abuf_t* dstBuf = nullptr;
unsigned chN = 0;
// get the src buffer
if((rc = var_get(ctx,kInPId, kAnyChIdx, srcBuf )) != kOkRC )
goto errLabel;
// get the dst buffer
if((rc = var_get(ctx,kOutPId, kAnyChIdx, dstBuf)) != kOkRC )
goto errLabel;
chN = std::min(srcBuf->chN,inst->limN);
for(unsigned i=0; i<chN; ++i)
{
dsp::limiter::exec( inst->limA[i], srcBuf->buf + i*srcBuf->frameN, dstBuf->buf + i*srcBuf->frameN, srcBuf->frameN );
}
errLabel:
return rc;
}
rc_t report( instance_t* ctx )
{
rc_t rc = kOkRC;
inst_t* inst = (inst_t*)ctx->userPtr;
for(unsigned i=0; i<inst->limN; ++i)
{
limiter_t* c = inst->limA[i];
cwLogInfo("%s ch:%i : bypass:%i procSmpN:%i igain:%f threshdb:%f ogain:%f",
ctx->label,i,c->bypassFl,c->procSmpCnt,c->igain,c->thresh,c->ogain );
}
return rc;
}
class_members_t members = {
.create = create,
.destroy = destroy,
.value = value,
.exec = exec,
.report = report
};
}
//------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------
// //
// audio_delay // audio_delay
@ -2177,6 +2359,158 @@ namespace cw
} }
//------------------------------------------------------------------------------------------------------------------
//
// DC Filter
//
namespace dc_filter
{
enum
{
kInPId,
kBypassPId,
kGainPId,
kOutPId,
};
typedef dsp::dc_filter::obj_t dc_filter_t;
typedef struct
{
dc_filter_t** dcfA;
unsigned dcfN;
} inst_t;
rc_t create( instance_t* ctx )
{
rc_t rc = kOkRC;
const abuf_t* srcBuf = nullptr; //
inst_t* inst = mem::allocZ<inst_t>();
ctx->userPtr = inst;
// verify that a source buffer exists
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",srcBuf )) != kOkRC )
{
rc = cwLogError(rc,"The instance '%s' does not have a valid input connection.",ctx->label);
goto errLabel;
}
else
{
// allocate channel array
inst->dcfN = srcBuf->chN;
inst->dcfA = mem::allocZ<dc_filter_t*>( inst->dcfN );
// create a dc_filter object for each input channel
for(unsigned i=0; i<srcBuf->chN; ++i)
{
real_t gain;
bool bypassFl;
// get the dc_filter variable values
if((rc = var_register_and_get( ctx, i,
kBypassPId, "bypass", bypassFl,
kGainPId, "gain", gain )) != kOkRC )
{
goto errLabel;
}
// create the dc_filter instance
if((rc = dsp::dc_filter::create( inst->dcfA[i], srcBuf->srate, srcBuf->frameN, gain, bypassFl)) != kOkRC )
{
rc = cwLogError(kOpFailRC,"The 'dc_filter' object create failed on the instance '%s'.",ctx->label);
goto errLabel;
}
}
// create the output audio buffer
if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->frameN )) != kOkRC )
goto errLabel;
}
errLabel:
return rc;
}
rc_t destroy( instance_t* ctx )
{
rc_t rc = kOkRC;
inst_t* inst = (inst_t*)ctx->userPtr;
for(unsigned i=0; i<inst->dcfN; ++i)
destroy(inst->dcfA[i]);
mem::release(inst->dcfA);
mem::release(inst);
return rc;
}
rc_t value( instance_t* ctx, variable_t* var )
{
return kOkRC;
}
rc_t exec( instance_t* ctx )
{
rc_t rc = kOkRC;
inst_t* inst = (inst_t*)ctx->userPtr;
const abuf_t* srcBuf = nullptr;
abuf_t* dstBuf = nullptr;
unsigned chN = 0;
// get the src buffer
if((rc = var_get(ctx,kInPId, kAnyChIdx, srcBuf )) != kOkRC )
goto errLabel;
// get the dst buffer
if((rc = var_get(ctx,kOutPId, kAnyChIdx, dstBuf)) != kOkRC )
goto errLabel;
chN = std::min(srcBuf->chN,inst->dcfN);
for(unsigned i=0; i<chN; ++i)
{
real_t gain = val_get<real_t>( ctx, kGainPId, i );
bool bypassFl = val_get<bool>( ctx, kBypassPId, i );
dsp::dc_filter::set( inst->dcfA[i], gain, bypassFl );
dsp::dc_filter::exec( inst->dcfA[i], srcBuf->buf + i*srcBuf->frameN, dstBuf->buf + i*srcBuf->frameN, srcBuf->frameN );
}
errLabel:
return rc;
}
rc_t report( instance_t* ctx )
{
rc_t rc = kOkRC;
inst_t* inst = (inst_t*)ctx->userPtr;
for(unsigned i=0; i<inst->dcfN; ++i)
{
dc_filter_t* c = inst->dcfA[i];
cwLogInfo("%s ch:%i : bypass:%i gain:%f",
ctx->label,i,c->bypassFl,c->gain );
}
return rc;
}
class_members_t members = {
.create = create,
.destroy = destroy,
.value = value,
.exec = exec,
.report = report
};
}
} }

View File

@ -903,26 +903,33 @@ const cw::flow::sample_t* cw::flow::abuf_get_channel( abuf_t* abuf, unsigned c
return abuf->buf + (chIdx*abuf->frameN); return abuf->buf + (chIdx*abuf->frameN);
} }
cw::flow::fbuf_t* cw::flow::fbuf_create( srate_t srate, unsigned maxBinN, unsigned chN, const unsigned* binN_V, const unsigned* hopSmpN_V, const sample_t** magV, const sample_t** phsV, const sample_t** hzV )
cw::flow::fbuf_t* cw::flow::fbuf_create( srate_t srate, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV, const sample_t** phsV, const sample_t** hzV )
{ {
unsigned curMaxBinN = vop::max(binN_V,chN);
if( curMaxBinN > maxBinN )
{
cwLogWarning("A channel bin count (%i) execeeds the max bin count (%i). Max. bin count increased to:%i.",curMaxBinN,maxBinN,curMaxBinN);
maxBinN = curMaxBinN;
}
fbuf_t* f = mem::allocZ<fbuf_t>(); fbuf_t* f = mem::allocZ<fbuf_t>();
f->srate = srate; f->srate = srate;
f->maxBinN = maxBinN;
f->chN = chN; f->chN = chN;
f->binN_V = mem::allocZ<unsigned>(chN);; f->binN_V = mem::allocZ<unsigned>(chN);;
f->hopSmpN_V = mem::allocZ<unsigned>(chN); f->hopSmpN_V = mem::allocZ<unsigned>(chN);
f->magV = mem::allocZ<sample_t*>(chN); f->magV = mem::allocZ<sample_t*>(chN);
f->phsV = mem::allocZ<sample_t*>(chN); f->phsV = mem::allocZ<sample_t*>(chN);
f->hzV = mem::allocZ<sample_t*>(chN); f->hzV = mem::allocZ<sample_t*>(chN);
f->readyFlV= mem::allocZ<bool>(chN); f->readyFlV = mem::allocZ<bool>(chN);
vop::copy( f->binN_V, binN_V, chN );
vop::copy( f->hopSmpN_V, hopSmpN_V, chN );
for(unsigned chIdx=0; chIdx<chN; ++chIdx)
{
f->binN_V[chIdx] = binN;
f->hohpSmpN_V[chIdx] = hopSmpN;
}
if( magV != nullptr || phsV != nullptr || hzV != nullptr ) if( magV != nullptr || phsV != nullptr || hzV != nullptr )
{ {
@ -935,13 +942,15 @@ cw::flow::fbuf_t* cw::flow::fbuf_create( srate_t srate, unsigned chN, unsigned
} }
else else
{ {
sample_t* buf = mem::allocZ<sample_t>( chN * kFbufVectN * binN ); sample_t* buf = mem::allocZ<sample_t>( kFbufVectN * maxBinN );
sample_t* m = buf;
for(unsigned chIdx=0,j=0; chIdx<chN; ++chIdx,j+=kFbufVectN*binN) for(unsigned chIdx=0; chIdx<chN; ++chIdx)
{ {
f->magV[chIdx] = buf + j + 0 * binN; f->magV[chIdx] = m + 0 * f->binN_V[chIdx];
f->phsV[chIdx] = buf + j + 1 * binN; f->phsV[chIdx] = m + 1 * f->binN_V[chIdx];
f->hzV[ chIdx] = buf + j + 2 * binN; f->hzV[ chIdx] = m + 2 * f->binN_V[chIdx];
m += f->binN_V[chIdx];
assert( m <= buf + kFbufVectN * maxBinN );
} }
f->buf = buf; f->buf = buf;
@ -951,6 +960,20 @@ cw::flow::fbuf_t* cw::flow::fbuf_create( srate_t srate, unsigned chN, unsigned
return f; return f;
} }
cw::flow::fbuf_t* cw::flow::fbuf_create( srate_t srate, unsigned maxBinN, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV, const sample_t** phsV, const sample_t** hzV )
{
unsigned binN_V[ chN ];
unsigned hopSmpN_V[ chN ];
vop::fill( binN_V, chN, binN );
vop::fill( hopSmpN_V, chN, binN );
return fbuf_create( srate, maxBinN, chN, binN_V, hopSmpN_V, magV, phsV, hzV );
}
void cw::flow::fbuf_destroy( fbuf_t*& fbuf ) void cw::flow::fbuf_destroy( fbuf_t*& fbuf )
{ {
if( fbuf == nullptr ) if( fbuf == nullptr )
@ -958,9 +981,9 @@ void cw::flow::fbuf_destroy( fbuf_t*& fbuf )
mem::release( fbuf->binN_V ); mem::release( fbuf->binN_V );
mem::release( fbuf->hopSmpN_V); mem::release( fbuf->hopSmpN_V);
mem::release( fbuf->magV); //mem::release( fbuf->magV);
mem::release( fbuf->phsV); //mem::release( fbuf->phsV);
mem::release( fbuf->hzV); //mem::release( fbuf->hzV);
mem::release( fbuf->buf); mem::release( fbuf->buf);
mem::release( fbuf->readyFlV); mem::release( fbuf->readyFlV);
mem::release( fbuf); mem::release( fbuf);
@ -968,7 +991,8 @@ void cw::flow::fbuf_destroy( fbuf_t*& fbuf )
cw::flow::fbuf_t* cw::flow::fbuf_duplicate( const fbuf_t* src ) cw::flow::fbuf_t* cw::flow::fbuf_duplicate( const fbuf_t* src )
{ {
fbuf_t* fbuf = fbuf_create( src->srate, src->chN, src->binN, src->hopSmpN ); fbuf_t* fbuf = fbuf_create( src->srate, src->maxBinN, src->chN, src->binN_V, src->hopSmpN_V );
for(unsigned i=0; i<fbuf->chN; ++i) for(unsigned i=0; i<fbuf->chN; ++i)
{ {
fbuf->binN_V[i] = src->binN_V[i]; fbuf->binN_V[i] = src->binN_V[i];
@ -1340,11 +1364,11 @@ cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* va
return rc; return rc;
} }
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV, const sample_t** phsV, const sample_t** hzV ) cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned maxBinN, unsigned chN, const unsigned* binN_V, const unsigned* hopSmpN_V, const sample_t** magV, const sample_t** phsV, const sample_t** hzV )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
fbuf_t* fbuf; fbuf_t* fbuf;
if((fbuf = fbuf_create( srate, chN, binN, hopSmpN, magV, phsV, hzV )) == nullptr ) if((fbuf = fbuf_create( srate, maxBinN, chN, binN_V, hopSmpN_V, magV, phsV, hzV )) == nullptr )
return cwLogError(kOpFailRC,"fbuf create failed on instance:'%s' variable:'%s'.", inst->label, var_label); return cwLogError(kOpFailRC,"fbuf create failed on instance:'%s' variable:'%s'.", inst->label, var_label);
if((rc = _var_register_and_set( inst, var_label, vid, chIdx, fbuf )) != kOkRC ) if((rc = _var_register_and_set( inst, var_label, vid, chIdx, fbuf )) != kOkRC )
@ -1353,6 +1377,15 @@ cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label
return rc; return rc;
} }
cw::rc_t cw::flow::var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned maxBinN, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV, const sample_t** phsV, const sample_t** hzV )
{
unsigned binN_V[ chN ];
unsigned hopSmpN_V[ chN ];
vop::fill(binN_V,chN,binN);
vop::fill(hopSmpN_V,chN, hopSmpN );
return var_register_and_set(inst,var_label,vid,chIdx,srate,maxBinN, chN,binN_V, hopSmpN_V, magV, phsV, hzV);
}
cw::rc_t cw::flow::var_get( const variable_t* var, bool& valRef ) cw::rc_t cw::flow::var_get( const variable_t* var, bool& valRef )
{ return _val_get_driver(var,valRef); } { return _val_get_driver(var,valRef); }

View File

@ -24,7 +24,7 @@ namespace cw
enum { enum {
kFbufVectN = 3, kFbufVectN = 3, // count of signal vectors in fbuf (mag,phs,hz)
kAnyChIdx = kInvalidIdx, kAnyChIdx = kInvalidIdx,
kLocalValueN = 2 kLocalValueN = 2
}; };
@ -34,6 +34,7 @@ namespace cw
struct value_str* base; struct value_str* base;
srate_t srate; // signal sample rate srate_t srate; // signal sample rate
unsigned flags; // See kXXXFbufFl unsigned flags; // See kXXXFbufFl
unsigned maxBinN; // max value that any value in binN_V[] is allowed to take
unsigned chN; // count of channels unsigned chN; // count of channels
unsigned* binN_V; // binN_V[ chN ] count of sample frames per channel unsigned* binN_V; // binN_V[ chN ] count of sample frames per channel
unsigned* hopSmpN_V; // hopSmpN_V[ chN ] hop sample count unsigned* hopSmpN_V; // hopSmpN_V[ chN ] hop sample count
@ -233,7 +234,8 @@ namespace cw
rc_t abuf_set_channel( abuf_t* buf, unsigned chIdx, const sample_t* v, unsigned vN ); rc_t abuf_set_channel( abuf_t* buf, unsigned chIdx, const sample_t* v, unsigned vN );
const sample_t* abuf_get_channel( abuf_t* buf, unsigned chIdx ); const sample_t* abuf_get_channel( abuf_t* buf, unsigned chIdx );
fbuf_t* fbuf_create( srate_t srate, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV=nullptr, const sample_t** phsV=nullptr, const sample_t** hzV=nullptr ); fbuf_t* fbuf_create( srate_t srate, unsigned maxBinN, unsigned chN, const unsigned* binN_V, const unsigned* hopSmpN_V, const sample_t** magV=nullptr, const sample_t** phsV=nullptr, const sample_t** hzV=nullptr );
fbuf_t* fbuf_create( srate_t srate, unsigned maxBinN, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV=nullptr, const sample_t** phsV=nullptr, const sample_t** hzV=nullptr );
void fbuf_destroy( fbuf_t*& buf ); void fbuf_destroy( fbuf_t*& buf );
fbuf_t* fbuf_duplicate( const fbuf_t* src ); fbuf_t* fbuf_duplicate( const fbuf_t* src );
@ -368,7 +370,8 @@ namespace cw
rc_t var_register_and_set( instance_t* inst, const char* label, unsigned vid, unsigned chIdx, variable_t*& varRef ); rc_t var_register_and_set( instance_t* inst, const char* label, unsigned vid, unsigned chIdx, variable_t*& varRef );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN ); rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned frameN );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV=nullptr, const sample_t** phsV=nullptr, const sample_t** hzV=nullptr ); rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned maxBinN, unsigned chN, const unsigned* binN_V, const unsigned* hopSmpN_V, const sample_t** magV=nullptr, const sample_t** phsV=nullptr, const sample_t** hzV=nullptr );
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned maxBinN, unsigned chN, unsigned binN, unsigned hopSmpN, const sample_t** magV=nullptr, const sample_t** phsV=nullptr, const sample_t** hzV=nullptr );
inline rc_t _var_register_and_set(cw::flow::instance_t*, unsigned int ) { return kOkRC; } inline rc_t _var_register_and_set(cw::flow::instance_t*, unsigned int ) { return kOkRC; }

View File

@ -298,7 +298,7 @@ namespace cw
for(unsigned i=0; i<p->pvoc_ctx.srcChN; ++i) for(unsigned i=0; i<p->pvoc_ctx.srcChN; ++i)
{ {
if((rc = dsp::pv_anl::create( p->anlA[i], p->pvoc_ctx.procSmpN, ctx->srcSrate, p->pvoc_ctx.wndSmpN, p->pvoc_ctx.hopSmpN, dsp::pv_anl::kNoCalcHzPvaFl )) != kOkRC ) if((rc = dsp::pv_anl::create( p->anlA[i], p->pvoc_ctx.procSmpN, ctx->srcSrate, p->pvoc_ctx.wndSmpN, p->pvoc_ctx.wndSmpN, p->pvoc_ctx.hopSmpN, dsp::pv_anl::kNoCalcHzPvaFl )) != kOkRC )
{ {
rc = cwLogError(rc,"PVOC analysis component create failed."); rc = cwLogError(rc,"PVOC analysis component create failed.");
goto errLabel; goto errLabel;