libcw/cwDsp.cpp

189 lines
4.3 KiB
C++
Raw Permalink Normal View History

//| Copyright: (C) 2020-2024 Kevin Larke <contact AT larke DOT org>
//| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
2020-10-04 14:48:27 +00:00
#include "cwCommon.h"
#include "cwLog.h"
#include "cwCommonImpl.h"
#include "cwTest.h"
2020-10-04 14:48:27 +00:00
#include "cwMem.h"
#include "cwUtility.h"
#include "cwMath.h"
2020-10-04 14:48:27 +00:00
#include "cwVectOps.h"
#include "cwDsp.h"
#include "cwText.h"
2020-10-04 14:48:27 +00:00
//----------------------------------------------------------------------------------------------------------------------
// 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; }
2020-10-04 14:48:27 +00:00
cw::rc_t cw::dsp::fft::test()
{
typedef float real_t;
rc_t rc = kOkRC;
unsigned flags = kToPolarFl;
unsigned xN = 16;
real_t srate = xN;
real_t hz = 1;
real_t xV[xN];
struct obj_str<real_t>* p = nullptr;
create<real_t>(p,xN,flags);
2020-10-04 14:48:27 +00:00
if(p == nullptr )
2020-10-04 14:48:27 +00:00
{
rc = cwLogError(kOpFailRC,"FFT procedure allocation failed.");
goto errLabel;
}
vop::zero(xV,xN);
vop::sine(xV,xN,srate,hz);
exec(p,xV,xN);
vop::print( xV, xN, "%f ", "sin " );
vop::print( magn(p), bin_count(p), "%f ", "mag " );
vop::print( phase(p), bin_count(p), "%f ", "phs " );
errLabel:
destroy(p);
return rc;
}
//----------------------------------------------------------------------------------------------------------------------
// ifft
//
cw::rc_t cw::dsp::ifft::test()
{
typedef double real_t;
struct fft::obj_str<real_t>* ft = nullptr;
struct obj_str<real_t>* ift = nullptr;
2020-10-04 14:48:27 +00:00
rc_t rc = kOkRC;
unsigned xN = 16;
real_t xV[xN];
if( (rc = fft::create<real_t>(ft,xN,fft::kToPolarFl)) != kOkRC )
2020-10-04 14:48:27 +00:00
{
rc = cwLogError(rc,"FFT procedure allocation failed.");
2020-10-04 14:48:27 +00:00
goto errLabel;
}
if((rc = create<real_t>(ift, fft::bin_count(ft))) != kOkRC )
2020-10-04 14:48:27 +00:00
{
rc = cwLogError(rc,"IFFT procedure allocation failed.");
2020-10-04 14:48:27 +00:00
goto errLabel;
}
vop::zero(xV,xN);
vop::sine(xV,xN,(double)xN,1.0);
fft::exec(ft,xV,xN);
exec_polar(ift, fft::magn(ft), fft::phase(ft) );
2020-10-04 14:48:27 +00:00
vop::print( xV, xN, "%f ", "sin " );
vop::print( magn(ft), fft::bin_count(ft), "%f ", "mag " );
vop::print( phase(ft), fft::bin_count(ft), "%f ", "phs " );
vop::print( out(ift), out_count(ift), "%f ", "sig " );
errLabel:
destroy(ft);
destroy(ift);
return rc;
}
//----------------------------------------------------------------------------------------------------------------------
// convolve
//
cw::rc_t cw::dsp::convolve::test()
{
typedef float real_t;
real_t hV[] = { 1, .5, .25, .1, .05 };
unsigned hN = sizeof(hV) / sizeof(hV[0]);
real_t xV[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 };
unsigned xN = 4; //sizeof(xV) / sizeof(xV[0]);
real_t yV[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
unsigned yN = sizeof(yV) / sizeof(yV[0]);
// correct output from apply: real_t zV[] = { 1., 0.5, 0.25,0.1, 1.05,0.5, 0.25,0.1, 1.05,0.5, 0.25,0.1, 0.05,0.0, 0.0 };
obj_str<real_t>* p = nullptr;
create(p,hV,hN,xN);
2020-10-04 14:48:27 +00:00
exec(p,xV,xN);
vop::print( p->outV, p->outN , "%f ", "out ");
vop::print( p->olaV, p->olaN, "%f ", "ola " );
exec(p,xV+4,xN);
vop::print( p->outV, p->outN , "%f ", "out ");
vop::print( p->olaV, p->olaN, "%f ", "ola " );
exec(p,xV+8,xN);
vop::print( p->outV, p->outN , "%f ", "out ");
vop::print( p->olaV, p->olaN, "%f ", "ola " );
xN = sizeof(xV) / sizeof(xV[0]);
apply(xV,xN,hV,hN,yV,yN);
vop::print( yV, yN , "%4.2f ", "yV ");
destroy(p);
return kOkRC;
}
// 1. 0.5 0.25 0.1 1.05 0.5 0.25 0.1 1.05 0.5 0.25 0.1 0.05 0.0. 0. ]
// 1.0 0.5 0.25 0.1 1.05 0.5 0.25 0.1 1.05 0.5 0.25 0.1 1.05 1.0 0.75 0.
cw::rc_t cw::dsp::test_dsp( const test::test_args_t& args )
{
rc_t rc = kOkRC;
if( textIsEqual(args.test_label,"fft") )
{
rc = fft::test();
goto errLabel;
}
if( textIsEqual(args.test_label,"ifft") )
{
rc = ifft::test();
goto errLabel;
}
if( textIsEqual(args.test_label,"convolve") )
{
rc = convolve::test();
goto errLabel;
}
rc = cwLogError(kInvalidArgRC,"Unknown dsp test case module:%s test:%s.",args.module_label,args.test_label);
errLabel:
return rc;
}