summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Glover <j@johnglover.net>2012-07-02 20:42:47 +0100
committerJohn Glover <j@johnglover.net>2012-07-02 20:42:47 +0100
commit2675f0ef49584ceb03283430716e053fe0498a3a (patch)
tree05d4088fe3e7550a9bc8041f4f7839ad21ccd92a /src
parent9312f0a18a208c4dde6c400b1e08b678648be588 (diff)
downloadsimpl-2675f0ef49584ceb03283430716e053fe0498a3a.tar.gz
simpl-2675f0ef49584ceb03283430716e053fe0498a3a.tar.bz2
simpl-2675f0ef49584ceb03283430716e053fe0498a3a.zip
[partial_tracking] Add C++ implemention of SMS partial tracking.
Update libsms test data.
Diffstat (limited to 'src')
-rw-r--r--src/simpl/partial_tracking.cpp109
-rw-r--r--src/simpl/partial_tracking.h38
2 files changed, 140 insertions, 7 deletions
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