Allow frequency domain transforms to have a variable window sample count.
Audio file in processor now has a 'seekSecs' and 'onOffFl' parameter. Audio mixer now works as a stereo mixer. PV Analysis proc now can have variable window length.
This commit is contained in:
parent
a2f459c5fb
commit
cbaff98964
@ -385,14 +385,14 @@ cw::rc_t cw::afop::file_processor( const char* srcFn, const char* dstFn, proc_fu
|
|||||||
for(unsigned i = 0; i<proc_ctx.srcChN; ++i)
|
for(unsigned i = 0; i<proc_ctx.srcChN; ++i)
|
||||||
{
|
{
|
||||||
srcChFileBuf[i] = srcFileBuf + (i*proc_ctx.srcHopSmpN );
|
srcChFileBuf[i] = srcFileBuf + (i*proc_ctx.srcHopSmpN );
|
||||||
dsp::shift_buf::create( srcShiftBufA[i], proc_ctx.srcHopSmpN, proc_ctx.srcWndSmpN, proc_ctx.srcHopSmpN );
|
dsp::shift_buf::create( srcShiftBufA[i], proc_ctx.srcHopSmpN, proc_ctx.srcWndSmpN, proc_ctx.srcWndSmpN, proc_ctx.srcHopSmpN );
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each dest. channel - setup the dest file buffer and create the dst shift buffer
|
// For each dest. channel - setup the dest file buffer and create the dst shift buffer
|
||||||
for(unsigned i = 0; i<proc_ctx.dstChN; ++i)
|
for(unsigned i = 0; i<proc_ctx.dstChN; ++i)
|
||||||
{
|
{
|
||||||
oChBuf[i] = procFileBuf + (i*proc_ctx.dstHopSmpN );
|
oChBuf[i] = procFileBuf + (i*proc_ctx.dstHopSmpN );
|
||||||
dsp::shift_buf::create( dstShiftBufA[i], proc_ctx.dstHopSmpN, proc_ctx.dstWndSmpN, proc_ctx.dstHopSmpN );
|
dsp::shift_buf::create( dstShiftBufA[i], proc_ctx.dstHopSmpN, proc_ctx.dstWndSmpN, proc_ctx.dstWndSmpN, proc_ctx.dstHopSmpN );
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the data recorder
|
// create the data recorder
|
||||||
|
@ -39,14 +39,14 @@ namespace cw
|
|||||||
unsigned wndLabelToId( const char* label )
|
unsigned wndLabelToId( const char* label )
|
||||||
{ return cw::labelToId( wndLabelArray, label, kInvalidWndId ); }
|
{ return cw::labelToId( wndLabelArray, label, kInvalidWndId ); }
|
||||||
|
|
||||||
rc_t _test( const char* windowLabel, const double* wndV, unsigned wndN )
|
rc_t _test( const char* windowLabel, const double* wndV, unsigned maxWndN, unsigned wndN )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
wnd_func::fobj_t* p = nullptr;
|
wnd_func::fobj_t* p = nullptr;
|
||||||
|
|
||||||
unsigned wndId = wndLabelToId( windowLabel );
|
unsigned wndId = wndLabelToId( windowLabel );
|
||||||
|
|
||||||
if((rc = create(p,wndId,wndN,3)) == kOkRC )
|
if((rc = create(p,wndId,maxWndN,wndN,3)) == kOkRC )
|
||||||
{
|
{
|
||||||
vop::print(p->wndV, p->wndN, "%f ", windowLabel);
|
vop::print(p->wndV, p->wndN, "%f ", windowLabel);
|
||||||
|
|
||||||
@ -70,13 +70,13 @@ namespace cw
|
|||||||
|
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
_test( "hann", hann_15, 15);
|
_test( "hann", hann_15, 15, 15);
|
||||||
_test( "hann", hann_16, 16);
|
_test( "hann", hann_16, 16, 16);
|
||||||
_test( "hamming", hamm_15, 15);
|
_test( "hamming", hamm_15, 15, 15);
|
||||||
_test( "hamming", hamm_16, 16);
|
_test( "hamming", hamm_16, 16, 16);
|
||||||
_test( "triangle", tri_15, 15);
|
_test( "triangle", tri_15, 15, 15);
|
||||||
_test( "triangle", tri_16, 16);
|
_test( "triangle", tri_16, 16, 16);
|
||||||
_test( "unity", ones_5, 5);
|
_test( "unity", ones_5, 5, 5);
|
||||||
|
|
||||||
if( rc != kOkRC )
|
if( rc != kOkRC )
|
||||||
cwLogError(rc,"Window test failed.");
|
cwLogError(rc,"Window test failed.");
|
||||||
@ -168,6 +168,7 @@ namespace cw
|
|||||||
|
|
||||||
unsigned procSmpCnt = 5; // count of samples to be fed to the shift buffer on each cycle
|
unsigned procSmpCnt = 5; // count of samples to be fed to the shift buffer on each cycle
|
||||||
unsigned hopSmpCnt = 6; // count of samples between shift buffer outputs
|
unsigned hopSmpCnt = 6; // count of samples between shift buffer outputs
|
||||||
|
unsigned maxWndSmpCnt= 7;
|
||||||
unsigned wndSmpCnt = 7; // count of samples in each shift buffer output
|
unsigned wndSmpCnt = 7; // count of samples in each shift buffer output
|
||||||
|
|
||||||
unsigned iSmpCnt = 49; // count of samples in the input test signal
|
unsigned iSmpCnt = 49; // count of samples in the input test signal
|
||||||
@ -177,7 +178,7 @@ namespace cw
|
|||||||
|
|
||||||
shift_buf::fobj_t* p = nullptr;
|
shift_buf::fobj_t* p = nullptr;
|
||||||
|
|
||||||
if((rc = shift_buf::create(p,procSmpCnt,wndSmpCnt,hopSmpCnt)) == kOkRC )
|
if((rc = shift_buf::create(p,procSmpCnt,maxWndSmpCnt,wndSmpCnt,hopSmpCnt)) == kOkRC )
|
||||||
{
|
{
|
||||||
sample_t* x = mem::allocZ<sample_t>(iSmpCnt);
|
sample_t* x = mem::allocZ<sample_t>(iSmpCnt);
|
||||||
sample_t* y = mem::allocZ<sample_t>(oSmpCnt);
|
sample_t* y = mem::allocZ<sample_t>(oSmpCnt);
|
||||||
|
@ -36,6 +36,7 @@ namespace cw
|
|||||||
{
|
{
|
||||||
unsigned wndTypeId; //
|
unsigned wndTypeId; //
|
||||||
unsigned flags; //
|
unsigned flags; //
|
||||||
|
unsigned maxWndN; //
|
||||||
sample_t* wndV; // wndV[ wndN ]
|
sample_t* wndV; // wndV[ wndN ]
|
||||||
unsigned wndN; // length of wndV[] and outV[]
|
unsigned wndN; // length of wndV[] and outV[]
|
||||||
sample_t* outV; // outV[ wndN ]
|
sample_t* outV; // outV[ wndN ]
|
||||||
@ -49,19 +50,10 @@ namespace cw
|
|||||||
unsigned wndLabelToId( const char* label ); // window type label to id
|
unsigned wndLabelToId( const char* label ); // window type label to id
|
||||||
|
|
||||||
template< typename sample_t >
|
template< typename sample_t >
|
||||||
rc_t create( struct obj_str<sample_t>*& p, unsigned wndId, unsigned wndSmpCnt, double kaiserSideLobeRejectDb )
|
rc_t _apply_window( struct obj_str<sample_t>*& p )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
p = mem::allocZ< struct obj_str< sample_t > >();
|
|
||||||
|
|
||||||
p->wndV = mem::allocZ<sample_t>(wndSmpCnt);
|
|
||||||
p->outV = mem::allocZ<sample_t>(wndSmpCnt);
|
|
||||||
p->wndN = wndSmpCnt;
|
|
||||||
p->wndTypeId = wndId & kWndIdMask;
|
|
||||||
p->flags = wndId & ~kWndIdMask;
|
|
||||||
|
|
||||||
|
|
||||||
switch( p->wndTypeId )
|
switch( p->wndTypeId )
|
||||||
{
|
{
|
||||||
case kHannWndId:
|
case kHannWndId:
|
||||||
@ -78,7 +70,7 @@ namespace cw
|
|||||||
|
|
||||||
case kKaiserWndId:
|
case kKaiserWndId:
|
||||||
{
|
{
|
||||||
sample_t beta = (p->flags & kSlRejIsBetaWndFl) ? kaiserSideLobeRejectDb : kaiser_beta_from_sidelobe_reject<sample_t>(kaiserSideLobeRejectDb);
|
sample_t beta = (p->flags & kSlRejIsBetaWndFl) ? p->kaiserSLRejectDb : kaiser_beta_from_sidelobe_reject<sample_t>(p->kaiserSLRejectDb);
|
||||||
kaiser<sample_t>(p->wndV,p->wndN, beta);
|
kaiser<sample_t>(p->wndV,p->wndN, beta);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -92,20 +84,19 @@ namespace cw
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rc = cwLogError(kInvalidArgRC,"The window id '%i' (0x%x) is not valid.", wndId, wndId );
|
rc = cwLogError(kInvalidArgRC,"The window id '%i' (0x%x) is not valid.", p->wndTypeId, p->wndTypeId );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sample_t den = 0;
|
sample_t den = 0;
|
||||||
sample_t num = 1;
|
sample_t num = 1;
|
||||||
if( cwIsFlag(p->flags,kNormBySumWndFl) )
|
if( cwIsFlag(p->flags,kNormBySumWndFl) )
|
||||||
{
|
{
|
||||||
den = vop::sum(p->wndV, p->wndN);
|
den = vop::sum(p->wndV, p->wndN);
|
||||||
num = wndSmpCnt;
|
num = p->wndN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cwIsFlag(p->flags,kNormByLengthWndFl) )
|
if( cwIsFlag(p->flags,kNormByLengthWndFl) )
|
||||||
den += wndSmpCnt;
|
den += p->wndN;
|
||||||
|
|
||||||
if( den > 0 )
|
if( den > 0 )
|
||||||
{
|
{
|
||||||
@ -113,11 +104,30 @@ namespace cw
|
|||||||
vop::div(p->wndV,den,p->wndN);
|
vop::div(p->wndV,den,p->wndN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename sample_t >
|
||||||
|
rc_t create( struct obj_str<sample_t>*& p, unsigned wndId, unsigned maxWndSmpCnt, unsigned wndSmpCnt, double kaiserSideLobeRejectDb )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
|
p = mem::allocZ< struct obj_str< sample_t > >();
|
||||||
|
|
||||||
|
p->wndV = mem::allocZ<sample_t>(maxWndSmpCnt);
|
||||||
|
p->outV = mem::allocZ<sample_t>(maxWndSmpCnt);
|
||||||
|
p->wndN = wndSmpCnt;
|
||||||
|
p->maxWndN = maxWndSmpCnt;
|
||||||
|
p->wndTypeId = wndId & kWndIdMask;
|
||||||
|
p->flags = wndId & ~kWndIdMask;
|
||||||
|
p->kaiserSLRejectDb = kaiserSideLobeRejectDb;
|
||||||
|
|
||||||
|
rc = _apply_window(p);
|
||||||
|
|
||||||
if( rc != kOkRC )
|
if( rc != kOkRC )
|
||||||
destroy(p);
|
destroy(p);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename sample_t >
|
template< typename sample_t >
|
||||||
@ -151,6 +161,28 @@ namespace cw
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename sample_t >
|
||||||
|
rc_t set_window_sample_count( struct obj_str<sample_t>* p, unsigned wndSmpCnt )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
|
if( wndSmpCnt > p->maxWndN )
|
||||||
|
return cwLogError( kInvalidArgRC, "The window function sample count (%i) cannot be larger than the max window function sample count (%i).", wndSmpCnt, p->maxWndN );
|
||||||
|
|
||||||
|
if( wndSmpCnt != p->wndN )
|
||||||
|
{
|
||||||
|
p->wndN = wndSmpCnt;
|
||||||
|
|
||||||
|
if((rc = _apply_window(p)) == kOkRC )
|
||||||
|
{
|
||||||
|
// zero the end of the window buffer
|
||||||
|
vop::zero(p->wndV + p->wndN, p->maxWndN - p->wndN );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rc_t test( const cw::object_t* args );
|
rc_t test( const cw::object_t* args );
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -191,7 +223,7 @@ namespace cw
|
|||||||
|
|
||||||
p = mem::allocZ< struct obj_str<sample_t> >();
|
p = mem::allocZ< struct obj_str<sample_t> >();
|
||||||
|
|
||||||
if((rc = wnd_func::create( p->wf, wndTypeId, wndSmpCnt, 0)) != kOkRC )
|
if((rc = wnd_func::create( p->wf, wndTypeId, wndSmpCnt, wndSmpCnt, 0)) != kOkRC )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
p->bufV = mem::allocZ<sample_t>( wndSmpCnt );
|
p->bufV = mem::allocZ<sample_t>( wndSmpCnt );
|
||||||
@ -285,7 +317,6 @@ namespace cw
|
|||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rc_t test( const cw::object_t* args );
|
rc_t test( const cw::object_t* args );
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -303,6 +334,7 @@ namespace cw
|
|||||||
sample_t* outV; // output window outV[ outN ]
|
sample_t* outV; // output window outV[ outN ]
|
||||||
unsigned outN; // outN == wndSmpCnt
|
unsigned outN; // outN == wndSmpCnt
|
||||||
unsigned procSmpCnt; // input sample count
|
unsigned procSmpCnt; // input sample count
|
||||||
|
unsigned maxWndSmpCnt; // maximum value for wndSmpCnt
|
||||||
unsigned wndSmpCnt; // output sample count
|
unsigned wndSmpCnt; // output sample count
|
||||||
unsigned hopSmpCnt; // count of samples to shift the buffer by on each call to cmShiftExec()
|
unsigned hopSmpCnt; // count of samples to shift the buffer by on each call to cmShiftExec()
|
||||||
sample_t* inPtr; // ptr to location in outV[] to recv next sample
|
sample_t* inPtr; // ptr to location in outV[] to recv next sample
|
||||||
@ -313,21 +345,26 @@ namespace cw
|
|||||||
typedef obj_str<double> dobj_t;
|
typedef obj_str<double> dobj_t;
|
||||||
|
|
||||||
template< typename sample_t >
|
template< typename sample_t >
|
||||||
rc_t create( struct obj_str<sample_t>*& p, unsigned procSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt )
|
rc_t create( struct obj_str<sample_t>*& p, unsigned procSmpCnt, unsigned maxWndSmpCnt, unsigned wndSmpCnt, unsigned hopSmpCnt )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
p = mem::allocZ< struct obj_str<sample_t> >();
|
p = mem::allocZ< struct obj_str<sample_t> >();
|
||||||
|
|
||||||
|
p->maxWndSmpCnt = maxWndSmpCnt;
|
||||||
|
if((rc = set_window_sample_count(p,wndSmpCnt )) != kOkRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
if( hopSmpCnt > wndSmpCnt )
|
if( hopSmpCnt > wndSmpCnt )
|
||||||
return cwLogError( kInvalidArgRC, "The window sample count (%i) must be greater than or equal to the hop sample count (%i).", wndSmpCnt, hopSmpCnt );
|
return cwLogError( kInvalidArgRC, "The shift buffer window sample count (%i) must be greater than or equal to the hop sample count (%i).", wndSmpCnt, hopSmpCnt );
|
||||||
|
|
||||||
// The worst case storage requirement is where there are wndSmpCnt-1 samples in outV[] and procSmpCnt new samples arrive.
|
// The worst case storage requirement is where there are wndSmpCnt-1 samples in outV[] and procSmpCnt new samples arrive.
|
||||||
p->bufSmpCnt = wndSmpCnt + procSmpCnt;
|
p->bufSmpCnt = maxWndSmpCnt + procSmpCnt;
|
||||||
p->bufV = mem::allocZ<sample_t>( p->bufSmpCnt );
|
p->bufV = mem::allocZ<sample_t>( p->bufSmpCnt );
|
||||||
p->outV = p->bufV;
|
p->outV = p->bufV;
|
||||||
p->outN = wndSmpCnt;
|
//p->outN = wndSmpCnt;
|
||||||
p->wndSmpCnt = wndSmpCnt;
|
//p->maxWndSmpCnt = maxWndSmpCnt;
|
||||||
|
//p->wndSmpCnt = wndSmpCnt;
|
||||||
p->procSmpCnt = procSmpCnt;
|
p->procSmpCnt = procSmpCnt;
|
||||||
p->hopSmpCnt = hopSmpCnt;
|
p->hopSmpCnt = hopSmpCnt;
|
||||||
p->inPtr = p->outV;
|
p->inPtr = p->outV;
|
||||||
@ -389,6 +426,18 @@ namespace cw
|
|||||||
return p->fl;
|
return p->fl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename sample_t >
|
||||||
|
rc_t set_window_sample_count( struct obj_str<sample_t>* p, unsigned wndSmpCnt )
|
||||||
|
{
|
||||||
|
if( wndSmpCnt > p->maxWndSmpCnt )
|
||||||
|
return cwLogError( kInvalidArgRC, "The shift buffer window sample count (%i) cannot be larger than the max window sample count (%i).", p->wndSmpCnt, p->maxWndSmpCnt );
|
||||||
|
|
||||||
|
p->wndSmpCnt = wndSmpCnt;
|
||||||
|
p->outN = wndSmpCnt;
|
||||||
|
|
||||||
|
return kOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
rc_t test( const cw::object_t* args );
|
rc_t test( const cw::object_t* args );
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -524,9 +573,9 @@ namespace cw
|
|||||||
|
|
||||||
p = mem::allocZ< struct obj_str<T> >();
|
p = mem::allocZ< struct obj_str<T> >();
|
||||||
|
|
||||||
shift_buf::create( p->sb, procSmpCnt, wndSmpCnt, hopSmpCnt );
|
shift_buf::create( p->sb, procSmpCnt, maxWndSmpCnt, wndSmpCnt, hopSmpCnt );
|
||||||
wnd_func::create( p->wf, wnd_func::kHannWndId | wnd_func::kNormByLengthWndFl, wndSmpCnt, 0 );
|
wnd_func::create( p->wf, wnd_func::kHannWndId | wnd_func::kNormByLengthWndFl, maxWndSmpCnt, wndSmpCnt, 0 );
|
||||||
fft::create( p->ft, wndSmpCnt, fft::kToPolarFl);
|
fft::create( p->ft, maxWndSmpCnt, fft::kToPolarFl);
|
||||||
phs_to_frq::create(p->pf, srate, p->ft->binN, hopSmpCnt );
|
phs_to_frq::create(p->pf, srate, p->ft->binN, hopSmpCnt );
|
||||||
|
|
||||||
p->flags = flags;
|
p->flags = flags;
|
||||||
@ -577,6 +626,17 @@ namespace cw
|
|||||||
return fl;
|
return fl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
rc_t set_window_length( struct obj_str<T>* p, unsigned wndSmpCnt )
|
||||||
|
{
|
||||||
|
rc_t rc;
|
||||||
|
|
||||||
|
if((rc = shift_buf::set_window_sample_count( p->sb, wndSmpCnt )) == kOkRC )
|
||||||
|
rc = wnd_func::set_window_sample_count( p->wf, wndSmpCnt );
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -638,7 +698,7 @@ namespace cw
|
|||||||
p->magV = mem::allocZ<T>( p->binCnt );
|
p->magV = mem::allocZ<T>( p->binCnt );
|
||||||
|
|
||||||
|
|
||||||
wnd_func::create( p->wf, wndTypeId, wndSmpCnt, 0);
|
wnd_func::create( p->wf, wndTypeId, wndSmpCnt, wndSmpCnt, 0);
|
||||||
ifft::create( p->ft, p->binCnt );
|
ifft::create( p->ft, p->binCnt );
|
||||||
ola::create( p->ola, wndSmpCnt, hopSmpCnt, procSmpCnt, wndTypeId );
|
ola::create( p->ola, wndSmpCnt, hopSmpCnt, procSmpCnt, wndTypeId );
|
||||||
|
|
||||||
@ -911,29 +971,35 @@ namespace cw
|
|||||||
// convert db back to magnitude
|
// convert db back to magnitude
|
||||||
vop::db_to_ampl(X1m, X1m, binN );
|
vop::db_to_ampl(X1m, X1m, binN );
|
||||||
|
|
||||||
|
|
||||||
// convert the mean input magnitude to db
|
// convert the mean input magnitude to db
|
||||||
double idb = 20*log10(u0);
|
double idb = 20*log10(u0);
|
||||||
|
|
||||||
// get the mean output magnitude spectra
|
// get the mean output magnitude spectra
|
||||||
double u1 = vop::mean(X1m,binN);
|
double u1 = vop::mean(X1m,binN);
|
||||||
|
|
||||||
if( idb > -150.0 )
|
if( p->mix > 0 )
|
||||||
{
|
{
|
||||||
// set the output gain such that the mean output magnitude
|
if( idb > -150.0 )
|
||||||
// will match the mean input magnitude
|
{
|
||||||
p->ogain = u0/u1;
|
// set the output gain such that the mean output magnitude
|
||||||
|
// will match the mean input magnitude
|
||||||
|
p->ogain = u0/u1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
T0 a0 = 0.9;
|
||||||
|
p->ogain *= a0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
T0 a0 = 0.9;
|
|
||||||
p->ogain *= a0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply the output gain
|
// apply the output gain
|
||||||
if( p->bypassFl )
|
if( p->bypassFl )
|
||||||
vop::copy( p->outMagV, magV, binN );
|
vop::copy( p->outMagV, magV, binN );
|
||||||
else
|
else
|
||||||
vop::mul( p->outMagV, X1m, std::min((T1)4.0,p->ogain), binN);
|
vop::mul( p->outMagV, X1m, std::min((T1)4.0,p->ogain), binN);
|
||||||
|
//vop::mul( p->outMagV, X1m, p->ogain, binN);
|
||||||
|
|
||||||
vop::copy( p->outPhsV, phsV, binN);
|
vop::copy( p->outPhsV, phsV, binN);
|
||||||
|
|
||||||
|
155
cwFlowProc.cpp
155
cwFlowProc.cpp
@ -366,6 +366,8 @@ namespace cw
|
|||||||
{
|
{
|
||||||
kFnamePId,
|
kFnamePId,
|
||||||
kEofFlPId,
|
kEofFlPId,
|
||||||
|
kOnOffFlPId,
|
||||||
|
kSeekSecsPId,
|
||||||
kOutPId
|
kOutPId
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -380,13 +382,19 @@ namespace cw
|
|||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
audiofile::info_t info;
|
audiofile::info_t info;
|
||||||
|
real_t seekSecs;
|
||||||
inst_t* inst = mem::allocZ<inst_t>();
|
inst_t* inst = mem::allocZ<inst_t>();
|
||||||
ctx->userPtr = inst;
|
ctx->userPtr = inst;
|
||||||
|
|
||||||
|
if((rc = var_register( ctx, kAnyChIdx, kOnOffFlPId, "on_off" )) != kOkRC )
|
||||||
|
{
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
// Register variable and get their current value
|
// Register variable and get their current value
|
||||||
if((rc = var_register_and_get( ctx, kAnyChIdx,
|
if((rc = var_register_and_get( ctx, kAnyChIdx,
|
||||||
kFnamePId, "fname", inst->filename,
|
kFnamePId, "fname", inst->filename,
|
||||||
|
kSeekSecsPId, "seekSecs", seekSecs,
|
||||||
kEofFlPId, "eofFl", inst->eofFl )) != kOkRC )
|
kEofFlPId, "eofFl", inst->eofFl )) != kOkRC )
|
||||||
{
|
{
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
@ -399,6 +407,13 @@ namespace cw
|
|||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((rc = seek( inst->afH, (unsigned)lround(seekSecs*info.srate) )) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(kInvalidArgRC,"The audio file '%s' could not seek to offset %f seconds.",seekSecs);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cwLogInfo("Audio '%s' srate:%f chs:%i frames:%i %f seconds.",inst->filename,info.srate,info.chCnt,info.frameCnt, info.frameCnt/info.srate );
|
cwLogInfo("Audio '%s' srate:%f chs:%i frames:%i %f seconds.",inst->filename,info.srate,info.chCnt,info.frameCnt, info.frameCnt/info.srate );
|
||||||
|
|
||||||
// create one output audio buffer - with the same configuration as the source audio file
|
// create one output audio buffer - with the same configuration as the source audio file
|
||||||
@ -427,7 +442,21 @@ namespace cw
|
|||||||
rc_t value( instance_t* ctx, variable_t* var )
|
rc_t value( instance_t* ctx, variable_t* var )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
return rc;
|
real_t seekSecs = 0;
|
||||||
|
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||||
|
|
||||||
|
if((rc = var_get(ctx,kSeekSecsPId,kAnyChIdx,seekSecs)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
if((rc = seek( inst->afH, (unsigned)lround(seekSecs * audiofile::sampleRate(inst->afH) ) )) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(kInvalidArgRC,"The audio file '%s' could not seek to offset %f seconds.",seekSecs);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
return kOkRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t exec( instance_t* ctx )
|
rc_t exec( instance_t* ctx )
|
||||||
@ -436,7 +465,11 @@ namespace cw
|
|||||||
unsigned actualFrameN = 0;
|
unsigned actualFrameN = 0;
|
||||||
inst_t* inst = (inst_t*)ctx->userPtr;
|
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||||
abuf_t* abuf = nullptr;
|
abuf_t* abuf = nullptr;
|
||||||
|
bool onOffFl = false;
|
||||||
|
|
||||||
|
// get the 'on-off; flag
|
||||||
|
if((rc = var_get(ctx,kOnOffFlPId,kAnyChIdx,onOffFl)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
// verify that a source buffer exists
|
// verify that a source buffer exists
|
||||||
if((rc = var_get(ctx,kOutPId,kAnyChIdx,abuf)) != kOkRC )
|
if((rc = var_get(ctx,kOutPId,kAnyChIdx,abuf)) != kOkRC )
|
||||||
@ -448,14 +481,23 @@ namespace cw
|
|||||||
sample_t* chBuf[ abuf->chN ];
|
sample_t* chBuf[ abuf->chN ];
|
||||||
|
|
||||||
for(unsigned i=0; i<abuf->chN; ++i)
|
for(unsigned i=0; i<abuf->chN; ++i)
|
||||||
|
{
|
||||||
chBuf[i] = abuf->buf + (i*abuf->frameN);
|
chBuf[i] = abuf->buf + (i*abuf->frameN);
|
||||||
|
|
||||||
rc = readFloat(inst->afH, abuf->frameN, 0, abuf->chN, chBuf, &actualFrameN );
|
// if the on/off flag is not set - then fill the output buffer with zeros
|
||||||
|
if( !onOffFl )
|
||||||
|
vop::zero(chBuf[i],abuf->frameN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the on/off flag is set then read from audio file
|
||||||
|
if( onOffFl )
|
||||||
|
rc = readFloat(inst->afH, abuf->frameN, 0, abuf->chN, chBuf, &actualFrameN );
|
||||||
|
|
||||||
if( inst->eofFl && actualFrameN == 0)
|
if( inst->eofFl && actualFrameN == 0)
|
||||||
rc = kEofRC;
|
rc = kEofRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,7 +545,7 @@ namespace cw
|
|||||||
if((rc = var_register_and_get( ctx, kAnyChIdx,
|
if((rc = var_register_and_get( ctx, kAnyChIdx,
|
||||||
kFnamePId, "fname", inst->filename,
|
kFnamePId, "fname", inst->filename,
|
||||||
kBitsPId, "bits", audioFileBits,
|
kBitsPId, "bits", audioFileBits,
|
||||||
kInPId, "in", src_abuf)) != kOkRC )
|
kInPId, "in", src_abuf )) != kOkRC )
|
||||||
{
|
{
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
@ -548,7 +590,7 @@ namespace cw
|
|||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
inst_t* inst = (inst_t*)ctx->userPtr;
|
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||||
const abuf_t* src_abuf = nullptr;
|
const abuf_t* src_abuf = nullptr;
|
||||||
|
|
||||||
if((rc = var_get(ctx,kInPId,kAnyChIdx,src_abuf)) != kOkRC )
|
if((rc = var_get(ctx,kInPId,kAnyChIdx,src_abuf)) != kOkRC )
|
||||||
rc = cwLogError(kInvalidStateRC,"The audio file instance '%s' does not have a valid input connection.",ctx->label);
|
rc = cwLogError(kInvalidStateRC,"The audio file instance '%s' does not have a valid input connection.",ctx->label);
|
||||||
else
|
else
|
||||||
@ -1175,7 +1217,8 @@ namespace cw
|
|||||||
const abuf_t* abuf0 = nullptr; //
|
const abuf_t* abuf0 = nullptr; //
|
||||||
const abuf_t* abuf1 = nullptr;
|
const abuf_t* abuf1 = nullptr;
|
||||||
unsigned outChN = 0;
|
unsigned outChN = 0;
|
||||||
|
double dum;
|
||||||
|
|
||||||
// get the source audio buffer
|
// get the source audio buffer
|
||||||
if((rc = var_register_and_get(ctx, kAnyChIdx,
|
if((rc = var_register_and_get(ctx, kAnyChIdx,
|
||||||
kIn0PId,"in0",abuf0,
|
kIn0PId,"in0",abuf0,
|
||||||
@ -1189,8 +1232,8 @@ namespace cw
|
|||||||
outChN = std::max(abuf0->chN, abuf1->chN);
|
outChN = std::max(abuf0->chN, abuf1->chN);
|
||||||
|
|
||||||
// register the gain
|
// register the gain
|
||||||
var_register( ctx, kAnyChIdx, kGain0PId, "gain0" );
|
var_register_and_get( ctx, kAnyChIdx, kGain0PId, "gain0", dum );
|
||||||
var_register( ctx, kAnyChIdx, kGain1PId, "gain1" );
|
var_register_and_get( ctx, kAnyChIdx, kGain1PId, "gain1", dum );
|
||||||
|
|
||||||
// create the output audio buffer
|
// create the output audio buffer
|
||||||
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf0->srate, outChN, abuf0->frameN );
|
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf0->srate, outChN, abuf0->frameN );
|
||||||
@ -1224,7 +1267,7 @@ namespace cw
|
|||||||
sample_t* osig = obuf->buf + i*obuf->frameN;
|
sample_t* osig = obuf->buf + i*obuf->frameN;
|
||||||
real_t gain = 1;
|
real_t gain = 1;
|
||||||
|
|
||||||
if((rc = var_get(ctx, gainPId, i, gain)) != kOkRC )
|
if((rc = var_get(ctx, gainPId, kAnyChIdx, gain)) != kOkRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
for(unsigned j=0; j<obuf->frameN; ++j)
|
for(unsigned j=0; j<obuf->frameN; ++j)
|
||||||
@ -1241,18 +1284,20 @@ namespace cw
|
|||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
abuf_t* obuf = nullptr;
|
abuf_t* obuf = nullptr;
|
||||||
const abuf_t* ibuf0 = nullptr;
|
//const abuf_t* ibuf0 = nullptr;
|
||||||
const abuf_t* ibuf1 = nullptr;
|
//const abuf_t* ibuf1 = nullptr;
|
||||||
|
|
||||||
if((rc = var_get(ctx,kOutPId, kAnyChIdx, obuf)) != kOkRC )
|
if((rc = var_get(ctx,kOutPId, kAnyChIdx, obuf)) != kOkRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
if((rc = var_get(ctx,kIn0PId, kAnyChIdx, ibuf0 )) != kOkRC )
|
//if((rc = var_get(ctx,kIn0PId, kAnyChIdx, ibuf0 )) != kOkRC )
|
||||||
goto errLabel;
|
// goto errLabel;
|
||||||
|
|
||||||
if((rc = var_get(ctx,kIn1PId, kAnyChIdx, ibuf1 )) != kOkRC )
|
//if((rc = var_get(ctx,kIn1PId, kAnyChIdx, ibuf1 )) != kOkRC )
|
||||||
goto errLabel;
|
// goto errLabel;
|
||||||
|
|
||||||
|
vop::zero(obuf->buf, obuf->frameN*obuf->chN );
|
||||||
|
|
||||||
_mix( ctx, kIn0PId, kGain0PId, obuf );
|
_mix( ctx, kIn0PId, kGain0PId, obuf );
|
||||||
_mix( ctx, kIn1PId, kGain1PId, obuf );
|
_mix( ctx, kIn1PId, kGain1PId, obuf );
|
||||||
|
|
||||||
@ -1422,14 +1467,9 @@ namespace cw
|
|||||||
inst_t* inst = mem::allocZ<inst_t>();
|
inst_t* inst = mem::allocZ<inst_t>();
|
||||||
ctx->userPtr = inst;
|
ctx->userPtr = inst;
|
||||||
|
|
||||||
if((rc = var_register_and_get( ctx, kAnyChIdx,
|
if((rc = var_register_and_get( ctx, kAnyChIdx,kInPId, "in", srcBuf )) != kOkRC )
|
||||||
kInPId, "in", srcBuf,
|
|
||||||
kMaxWndSmpNPId, "maxWndSmpN", inst->maxWndSmpN,
|
|
||||||
kWndSmpNPId, "wndSmpN", inst->wndSmpN,
|
|
||||||
kHopSmpNPId, "hopSmpN", inst->hopSmpN,
|
|
||||||
kHzFlPId, "hzFl", inst->hzFl )) != kOkRC )
|
|
||||||
{
|
{
|
||||||
goto errLabel;
|
cwLogError(kInvalidArgRC,"Unable to access the 'src' buffer.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1440,27 +1480,50 @@ namespace cw
|
|||||||
const sample_t* magV[ srcBuf->chN ];
|
const sample_t* magV[ srcBuf->chN ];
|
||||||
const sample_t* phsV[ srcBuf->chN ];
|
const sample_t* phsV[ srcBuf->chN ];
|
||||||
const sample_t* hzV[ srcBuf->chN ];
|
const sample_t* hzV[ srcBuf->chN ];
|
||||||
|
unsigned maxBinNV[ srcBuf->chN ];
|
||||||
|
unsigned binNV[ srcBuf->chN ];
|
||||||
|
unsigned hopNV[ srcBuf->chN ];
|
||||||
|
|
||||||
// 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->maxWndSmpN, inst->wndSmpN, inst->hopSmpN, flags )) != kOkRC )
|
|
||||||
|
unsigned maxWndSmpN = 0;
|
||||||
|
unsigned wndSmpN = 0;
|
||||||
|
unsigned hopSmpN = 0;
|
||||||
|
bool hzFl = false;
|
||||||
|
|
||||||
|
if((rc = var_register_and_get( ctx, i,
|
||||||
|
kMaxWndSmpNPId, "maxWndSmpN", maxWndSmpN,
|
||||||
|
kWndSmpNPId, "wndSmpN", wndSmpN,
|
||||||
|
kHopSmpNPId, "hopSmpN", hopSmpN,
|
||||||
|
kHzFlPId, "hzFl", hzFl )) != kOkRC )
|
||||||
|
{
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((rc = create( inst->pvA[i], ctx->ctx->framesPerCycle, srcBuf->srate, maxWndSmpN, wndSmpN, 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
magV[i] = inst->pvA[i]->magV;
|
maxBinNV[i] = inst->pvA[i]->maxBinCnt;
|
||||||
phsV[i] = inst->pvA[i]->phsV;
|
binNV[i] = inst->pvA[i]->binCnt;
|
||||||
hzV[i] = inst->pvA[i]->hzV;
|
hopNV[i] = hopSmpN;
|
||||||
|
|
||||||
|
magV[i] = inst->pvA[i]->magV;
|
||||||
|
phsV[i] = inst->pvA[i]->phsV;
|
||||||
|
hzV[i] = inst->pvA[i]->hzV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((rc = var_register( ctx, kAnyChIdx, kInPId, "in" )) != kOkRC )
|
|
||||||
goto errLabel;
|
|
||||||
|
|
||||||
// create the fbuf 'out'
|
|
||||||
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 );
|
|
||||||
|
|
||||||
|
// create the fbuf 'out'
|
||||||
|
if((rc = var_register_and_set(ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, maxBinNV, binNV, hopNV, magV, phsV, hzV )) != kOkRC )
|
||||||
|
{
|
||||||
|
cwLogError(kOpFailRC,"The output freq. buffer could not be created.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
@ -1485,6 +1548,24 @@ namespace cw
|
|||||||
rc_t value( instance_t* ctx, variable_t* var )
|
rc_t value( instance_t* ctx, variable_t* var )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||||
|
|
||||||
|
if( var->chIdx != kAnyChIdx && var->chIdx < inst->pvN )
|
||||||
|
{
|
||||||
|
unsigned val = 0;
|
||||||
|
pv_t* pva = inst->pvA[ var->chIdx ];
|
||||||
|
|
||||||
|
switch( var->vid )
|
||||||
|
{
|
||||||
|
case kWndSmpNPId:
|
||||||
|
rc = var_get( var, val );
|
||||||
|
dsp::pv_anl::set_window_length(pva,val);
|
||||||
|
//printf("WL:%i %i\n",val,var->chIdx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1751,7 +1832,7 @@ namespace cw
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the output buffer
|
// create the output buffer
|
||||||
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 )
|
if((rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, srcBuf->srate, srcBuf->chN, srcBuf->maxBinN_V, srcBuf->binN_V, srcBuf->hopSmpN_V, magV, phsV, hzV )) != kOkRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1796,8 +1877,8 @@ namespace cw
|
|||||||
cwLogWarning("Unhandled variable id '%i' on instance: %s.", var->vid, ctx->label );
|
cwLogWarning("Unhandled variable id '%i' on instance: %s.", var->vid, ctx->label );
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("sd: ceil:%f expo:%f thresh:%f upr:%f lwr:%f mix:%f : rc:%i val:%f\n",
|
//printf("%i sd: ceil:%f expo:%f thresh:%f upr:%f lwr:%f mix:%f : rc:%i val:%f\n",
|
||||||
// sd->ceiling, sd->expo, sd->thresh, sd->uprSlope, sd->lwrSlope, sd->mix, rc, val );
|
// var->chIdx,sd->ceiling, sd->expo, sd->thresh, sd->uprSlope, sd->lwrSlope, sd->mix, rc, val );
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -217,7 +217,7 @@ namespace cw
|
|||||||
case kFloatTFl: valRef = val->u.f!=0; break;
|
case kFloatTFl: valRef = val->u.f!=0; break;
|
||||||
case kDoubleTFl: valRef = val->u.d!=0; break;
|
case kDoubleTFl: valRef = val->u.d!=0; break;
|
||||||
default:
|
default:
|
||||||
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a bool.");
|
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a bool.",val->flags);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ namespace cw
|
|||||||
case kFloatTFl: valRef = (uint_t)val->u.f; break;
|
case kFloatTFl: valRef = (uint_t)val->u.f; break;
|
||||||
case kDoubleTFl: valRef = (uint_t)val->u.d; break;
|
case kDoubleTFl: valRef = (uint_t)val->u.d; break;
|
||||||
default:
|
default:
|
||||||
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a uint_t.");
|
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a uint_t.",val->flags);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ namespace cw
|
|||||||
case kFloatTFl: valRef = (int_t)val->u.f; break;
|
case kFloatTFl: valRef = (int_t)val->u.f; break;
|
||||||
case kDoubleTFl: valRef = (int_t)val->u.d; break;
|
case kDoubleTFl: valRef = (int_t)val->u.d; break;
|
||||||
default:
|
default:
|
||||||
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a int_t.");
|
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a int_t.",val->flags);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -265,7 +265,7 @@ namespace cw
|
|||||||
case kFloatTFl: valRef = (float)val->u.f; break;
|
case kFloatTFl: valRef = (float)val->u.f; break;
|
||||||
case kDoubleTFl: valRef = (float)val->u.d; break;
|
case kDoubleTFl: valRef = (float)val->u.d; break;
|
||||||
default:
|
default:
|
||||||
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a float.");
|
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a float.", val->flags);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -281,7 +281,7 @@ namespace cw
|
|||||||
case kFloatTFl: valRef = (double)val->u.f; break;
|
case kFloatTFl: valRef = (double)val->u.f; break;
|
||||||
case kDoubleTFl: valRef = val->u.d; break;
|
case kDoubleTFl: valRef = val->u.d; break;
|
||||||
default:
|
default:
|
||||||
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a double.");
|
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a double.",val->flags);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ namespace cw
|
|||||||
valRef = val->u.s;
|
valRef = val->u.s;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a string.");
|
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to a string.",val->flags);
|
||||||
valRef = nullptr;
|
valRef = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +307,7 @@ namespace cw
|
|||||||
valRef = val->u.abuf;
|
valRef = val->u.abuf;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to an abuf_t.");
|
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to an abuf_t.",val->flags);
|
||||||
valRef = nullptr;
|
valRef = nullptr;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
@ -330,7 +330,7 @@ namespace cw
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
valRef = nullptr;
|
valRef = nullptr;
|
||||||
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to an fbuf_t.");
|
rc = cwLogError(kTypeMismatchRC,"The type 0x%x could not be converted to an fbuf_t.",val->flags);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -903,33 +903,30 @@ 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, const unsigned* maxBinN_V, const unsigned* binN_V, const unsigned* hopSmpN_V, const sample_t** magV, const sample_t** phsV, const sample_t** hzV )
|
||||||
{
|
{
|
||||||
unsigned curMaxBinN = vop::max(binN_V,chN);
|
for(unsigned i=0; i<chN; ++i)
|
||||||
|
if( binN_V[i] > maxBinN_V[i] )
|
||||||
if( curMaxBinN > maxBinN )
|
{
|
||||||
{
|
cwLogError(kInvalidArgRC,"A channel bin count (%i) execeeds the max bin count (%i).",binN_V[i],maxBinN_V[i]);
|
||||||
cwLogWarning("A channel bin count (%i) execeeds the max bin count (%i). Max. bin count increased to:%i.",curMaxBinN,maxBinN,curMaxBinN);
|
return nullptr;;
|
||||||
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->maxBinN_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->binN_V, binN_V, chN );
|
||||||
vop::copy( f->hopSmpN_V, hopSmpN_V, chN );
|
vop::copy( f->maxBinN_V, maxBinN_V, chN );
|
||||||
|
vop::copy( f->hopSmpN_V, hopSmpN_V, chN );
|
||||||
|
|
||||||
|
|
||||||
if( magV != nullptr || phsV != nullptr || hzV != nullptr )
|
if( magV != nullptr || phsV != nullptr || hzV != nullptr )
|
||||||
{
|
{
|
||||||
@ -942,15 +939,17 @@ cw::flow::fbuf_t* cw::flow::fbuf_create( srate_t srate, unsigned maxBinN, unsign
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sample_t* buf = mem::allocZ<sample_t>( kFbufVectN * maxBinN );
|
unsigned maxTotalBinsN = vop::sum( maxBinN_V, chN );
|
||||||
|
|
||||||
|
sample_t* buf = mem::allocZ<sample_t>( kFbufVectN * maxTotalBinsN );
|
||||||
sample_t* m = buf;
|
sample_t* m = buf;
|
||||||
for(unsigned chIdx=0; chIdx<chN; ++chIdx)
|
for(unsigned chIdx=0; chIdx<chN; ++chIdx)
|
||||||
{
|
{
|
||||||
f->magV[chIdx] = m + 0 * f->binN_V[chIdx];
|
f->magV[chIdx] = m + 0 * f->binN_V[chIdx];
|
||||||
f->phsV[chIdx] = m + 1 * f->binN_V[chIdx];
|
f->phsV[chIdx] = m + 1 * f->binN_V[chIdx];
|
||||||
f->hzV[ chIdx] = m + 2 * f->binN_V[chIdx];
|
f->hzV[ chIdx] = m + 2 * f->binN_V[chIdx];
|
||||||
m += f->binN_V[chIdx];
|
m += f->maxBinN_V[chIdx];
|
||||||
assert( m <= buf + kFbufVectN * maxBinN );
|
assert( m <= buf + kFbufVectN * maxTotalBinsN );
|
||||||
}
|
}
|
||||||
|
|
||||||
f->buf = buf;
|
f->buf = buf;
|
||||||
@ -961,14 +960,16 @@ cw::flow::fbuf_t* cw::flow::fbuf_create( srate_t srate, unsigned maxBinN, unsign
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 )
|
cw::flow::fbuf_t* cw::flow::fbuf_create( srate_t srate, unsigned chN, unsigned maxBinN, unsigned binN, unsigned hopSmpN, const sample_t** magV, const sample_t** phsV, const sample_t** hzV )
|
||||||
{
|
{
|
||||||
|
unsigned maxBinN_V[ chN ];
|
||||||
unsigned binN_V[ chN ];
|
unsigned binN_V[ chN ];
|
||||||
unsigned hopSmpN_V[ chN ];
|
unsigned hopSmpN_V[ chN ];
|
||||||
|
|
||||||
|
vop::fill( maxBinN_V, chN, maxBinN );
|
||||||
vop::fill( binN_V, chN, binN );
|
vop::fill( binN_V, chN, binN );
|
||||||
vop::fill( hopSmpN_V, chN, binN );
|
vop::fill( hopSmpN_V, chN, binN );
|
||||||
return fbuf_create( srate, maxBinN, chN, binN_V, hopSmpN_V, magV, phsV, hzV );
|
return fbuf_create( srate, chN, maxBinN_V, binN_V, hopSmpN_V, magV, phsV, hzV );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,6 +980,7 @@ void cw::flow::fbuf_destroy( fbuf_t*& fbuf )
|
|||||||
if( fbuf == nullptr )
|
if( fbuf == nullptr )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mem::release( fbuf->maxBinN_V );
|
||||||
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);
|
||||||
@ -991,10 +993,11 @@ 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->maxBinN, src->chN, src->binN_V, src->hopSmpN_V );
|
fbuf_t* fbuf = fbuf_create( src->srate, src->chN, src->maxBinN_V, src->binN_V, src->hopSmpN_V );
|
||||||
|
|
||||||
for(unsigned i=0; i<fbuf->chN; ++i)
|
for(unsigned i=0; i<fbuf->chN; ++i)
|
||||||
{
|
{
|
||||||
|
fbuf->maxBinN_V[i] = src->maxBinN_V[i];
|
||||||
fbuf->binN_V[i] = src->binN_V[i];
|
fbuf->binN_V[i] = src->binN_V[i];
|
||||||
fbuf->hopSmpN_V[i] = src->hopSmpN_V[i];
|
fbuf->hopSmpN_V[i] = src->hopSmpN_V[i];
|
||||||
|
|
||||||
@ -1364,11 +1367,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 maxBinN, unsigned chN, const unsigned* binN_V, const unsigned* hopSmpN_V, 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 chN, const unsigned* maxBinN_V, 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, maxBinN, chN, binN_V, hopSmpN_V, magV, phsV, hzV )) == nullptr )
|
if((fbuf = fbuf_create( srate, chN, maxBinN_V, 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 )
|
||||||
@ -1377,13 +1380,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 )
|
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 maxBinN, unsigned binN, unsigned hopSmpN, const sample_t** magV, const sample_t** phsV, const sample_t** hzV )
|
||||||
{
|
{
|
||||||
|
unsigned maxBinN_V[ chN ];
|
||||||
unsigned binN_V[ chN ];
|
unsigned binN_V[ chN ];
|
||||||
unsigned hopSmpN_V[ chN ];
|
unsigned hopSmpN_V[ chN ];
|
||||||
|
vop::fill(maxBinN_V,chN,maxBinN);
|
||||||
vop::fill(binN_V,chN,binN);
|
vop::fill(binN_V,chN,binN);
|
||||||
vop::fill(hopSmpN_V,chN, hopSmpN );
|
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);
|
return var_register_and_set(inst,var_label,vid,chIdx,srate, chN, maxBinN_V, binN_V, hopSmpN_V, magV, phsV, hzV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ 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* maxBinN_V; // max value that binN_V[i] is allowed to take
|
||||||
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
|
||||||
sample_t** magV; // magV[ chN ][ binN ]
|
sample_t** magV; // magV[ chN ][ binN ]
|
||||||
@ -234,8 +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 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 chN, const unsigned* maxBinN_V, 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 );
|
fbuf_t* fbuf_create( srate_t srate, unsigned chN, unsigned maxBinN, 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 );
|
||||||
|
|
||||||
@ -370,8 +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 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 chN, const unsigned* maxBinN_V, 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 );
|
rc_t var_register_and_set( instance_t* inst, const char* var_label, unsigned vid, unsigned chIdx, srate_t srate, unsigned chN, unsigned maxBinN, 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; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user