From 2675f0ef49584ceb03283430716e053fe0498a3a Mon Sep 17 00:00:00 2001 From: John Glover Date: Mon, 2 Jul 2012 20:42:47 +0100 Subject: [partial_tracking] Add C++ implemention of SMS partial tracking. Update libsms test data. --- src/simpl/partial_tracking.cpp | 109 ++++++++++++++++++++++++++++++++++++++++- src/simpl/partial_tracking.h | 38 +++++++++++--- 2 files changed, 140 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/simpl/partial_tracking.cpp b/src/simpl/partial_tracking.cpp index 219be72..22832c4 100644 --- a/src/simpl/partial_tracking.cpp +++ b/src/simpl/partial_tracking.cpp @@ -63,11 +63,118 @@ Peaks PartialTracking::update_partials(Frame* frame) { // Find partials from the sinusoidal peaks in a list of Frames. Frames PartialTracking::find_partials(Frames frames) { for(int i = 0; i < frames.size(); i++) { + if(frames[i]->max_partials() != _max_partials) { + frames[i]->max_partials(_max_partials); + } + Peaks peaks = update_partials(frames[i]); for(int j = 0; j < peaks.size(); j++) { - frames[i]->partial(j, peaks[j]); + frames[i]->add_partial(peaks[j]); } } _frames = frames; return _frames; } + + +// --------------------------------------------------------------------------- +// SMSPartialTracking +// --------------------------------------------------------------------------- + +SMSPartialTracking::SMSPartialTracking() { + sms_init(); + + sms_initAnalParams(&_analysis_params); + _analysis_params.iSamplingRate = _sampling_rate; + _analysis_params.fHighestFreq = 20000; + _analysis_params.iMaxDelayFrames = 4; + _analysis_params.analDelay = 0; + _analysis_params.minGoodFrames = 1; + _analysis_params.iCleanTracks = 0; + _analysis_params.iFormat = SMS_FORMAT_HP; + _analysis_params.nTracks = _max_partials; + _analysis_params.nGuides = _max_partials; + _analysis_params.preEmphasis = 0; + sms_initAnalysis(&_analysis_params); + + sms_fillHeader(&_header, &_analysis_params); + sms_allocFrameH(&_header, &_data); + + _num_peaks = 100; + init_peaks(); +} + +SMSPartialTracking::~SMSPartialTracking() { + sms_freeAnalysis(&_analysis_params); + sms_freeFrame(&_data); + sms_free(); + + delete [] _peak_amplitude; + delete [] _peak_frequency; + delete [] _peak_phase; +} + +void SMSPartialTracking::init_peaks() { + if(_peak_amplitude) { + delete [] _peak_amplitude; + } + if(_peak_frequency) { + delete [] _peak_frequency; + } + if(_peak_phase) { + delete [] _peak_phase; + } + + _peak_amplitude = new sample[_num_peaks]; + _peak_frequency = new sample[_num_peaks]; + _peak_phase = new sample[_num_peaks]; +} + +void SMSPartialTracking::max_partials(int new_max_partials) { + _max_partials = new_max_partials; + + sms_freeAnalysis(&_analysis_params); + sms_freeFrame(&_data); + + // sms_initAnalParams(&_analysis_params); + _analysis_params.maxPeaks = _max_partials; + _analysis_params.nTracks = _max_partials; + _analysis_params.nGuides = _max_partials; + + sms_initAnalysis(&_analysis_params); + sms_fillHeader(&_header, &_analysis_params); + sms_allocFrameH(&_header, &_data); +} + +Peaks SMSPartialTracking::update_partials(Frame* frame) { + if(_num_peaks != frame->num_peaks()) { + _num_peaks = frame->num_peaks(); + init_peaks(); + } + + // set peaks in SMSAnalysisParams object + for(int i = 0; i < _num_peaks; i++) { + _peak_amplitude[i] = frame->peak(i)->amplitude; + _peak_frequency[i] = frame->peak(i)->frequency; + _peak_phase[i] = frame->peak(i)->phase; + } + sms_setPeaks(&_analysis_params, _num_peaks, _peak_amplitude, + _num_peaks, _peak_frequency, + _num_peaks, _peak_phase); + + // SMS partial tracking + sms_findPartials(&_data, &_analysis_params); + + // get partials from SMSData object + Peaks peaks; + + for(int i = 0; i < _data.nTracks; i++) { + Peak* p = new Peak(); + p->amplitude = _data.pFSinAmp[i]; + p->frequency = _data.pFSinFreq[i]; + p->phase = _data.pFSinPha[i]; + peaks.push_back(p); + } + + return peaks; +} diff --git a/src/simpl/partial_tracking.h b/src/simpl/partial_tracking.h index ade5584..e6f08d2 100644 --- a/src/simpl/partial_tracking.h +++ b/src/simpl/partial_tracking.h @@ -1,8 +1,12 @@ #ifndef PARTIAL_TRACKING_H -#define PARTIAL_TRACING_H +#define PARTIAL_TRACKING_H #include "base.h" +extern "C" { + #include "sms.h" +} + using namespace std; namespace simpl @@ -16,7 +20,7 @@ namespace simpl // --------------------------------------------------------------------------- class PartialTracking { - private: + protected: int _sampling_rate; int _max_partials; int _min_partial_length; @@ -30,19 +34,41 @@ class PartialTracking { void clear(); int sampling_rate(); - void sampling_rate(int new_sampling_rate); + virtual void sampling_rate(int new_sampling_rate); int max_partials(); - void max_partials(int new_max_partials); + virtual void max_partials(int new_max_partials); int min_partial_length(); - void min_partial_length(int new_min_partial_length); + virtual void min_partial_length(int new_min_partial_length); int max_gap(); - void max_gap(int new_max_gap); + virtual void max_gap(int new_max_gap); virtual Peaks update_partials(Frame* frame); virtual Frames find_partials(Frames frames); }; +// --------------------------------------------------------------------------- +// SMSPartialTracking +// --------------------------------------------------------------------------- +class SMSPartialTracking : public PartialTracking { + private: + SMSAnalysisParams _analysis_params; + SMSHeader _header; + SMSData _data; + int _num_peaks; + sample* _peak_amplitude; + sample* _peak_frequency; + sample* _peak_phase; + void init_peaks(); + + public: + SMSPartialTracking(); + ~SMSPartialTracking(); + void max_partials(int new_max_partials); + Peaks update_partials(Frame* frame); +}; + + } // end of namespace Simpl #endif -- cgit v1.2.3