summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Glover <j@johnglover.net>2012-09-24 11:18:09 +0200
committerJohn Glover <j@johnglover.net>2012-09-24 11:18:09 +0200
commit9f6de8863954715f930f937568ed274ee66d33db (patch)
treebc28f38b8cea6aa9eb71c3d7701364734eab0ef0
parent97ab533101618c84ae12806736e633261f241807 (diff)
downloadsimpl-9f6de8863954715f930f937568ed274ee66d33db.tar.gz
simpl-9f6de8863954715f930f937568ed274ee66d33db.tar.bz2
simpl-9f6de8863954715f930f937568ed274ee66d33db.zip
[partial_tracking] Default to inharmonic partial
tracking mode in SMSPartialTracking. Add methods to SMSPartialTracking to allow realtime mode and harmonic mode to be switched on/off.
-rw-r--r--src/simpl/partial_tracking.cpp40
-rw-r--r--src/simpl/partial_tracking.h5
-rw-r--r--tests/test_partial_tracking.cpp97
3 files changed, 139 insertions, 3 deletions
diff --git a/src/simpl/partial_tracking.cpp b/src/simpl/partial_tracking.cpp
index 99a8f34..5bb08b3 100644
--- a/src/simpl/partial_tracking.cpp
+++ b/src/simpl/partial_tracking.cpp
@@ -92,11 +92,12 @@ SMSPartialTracking::SMSPartialTracking() {
_analysis_params.analDelay = 0;
_analysis_params.minGoodFrames = 1;
_analysis_params.iCleanTracks = 0;
- _analysis_params.iFormat = SMS_FORMAT_HP;
+ _analysis_params.iFormat = SMS_FORMAT_IHP;
_analysis_params.nTracks = _max_partials;
_analysis_params.maxPeaks = _max_partials;
_analysis_params.nGuides = _max_partials;
_analysis_params.preEmphasis = 0;
+ _analysis_params.realtime = 0;
sms_initAnalysis(&_analysis_params);
sms_fillHeader(&_header, &_analysis_params);
@@ -159,11 +160,48 @@ void SMSPartialTracking::max_partials(int new_max_partials) {
init_peaks();
}
+bool SMSPartialTracking::realtime() {
+ return _analysis_params.realtime == 1;
+}
+
+void SMSPartialTracking::realtime(bool is_realtime) {
+ if(is_realtime) {
+ _analysis_params.realtime = 1;
+ }
+ else {
+ _analysis_params.realtime = 0;
+ }
+}
+
+bool SMSPartialTracking::harmonic() {
+ return _analysis_params.iFormat == SMS_FORMAT_HP;
+}
+
+void SMSPartialTracking::harmonic(bool is_harmonic) {
+ sms_freeAnalysis(&_analysis_params);
+ sms_freeFrame(&_data);
+
+ if(is_harmonic) {
+ _analysis_params.iFormat = SMS_FORMAT_HP;
+ }
+ else {
+ _analysis_params.iFormat = SMS_FORMAT_IHP;
+ }
+
+ sms_initAnalysis(&_analysis_params);
+ sms_fillHeader(&_header, &_analysis_params);
+ sms_allocFrameH(&_header, &_data);
+}
+
+void SMSPartialTracking::reset() {
+}
+
Peaks SMSPartialTracking::update_partials(Frame* frame) {
int num_peaks = _max_partials;
if(num_peaks > frame->num_peaks()) {
num_peaks = frame->num_peaks();
}
+ frame->clear_partials();
// set peaks in SMSAnalysisParams object
for(int i = 0; i < num_peaks; i++) {
diff --git a/src/simpl/partial_tracking.h b/src/simpl/partial_tracking.h
index 4f8d60e..324c348 100644
--- a/src/simpl/partial_tracking.h
+++ b/src/simpl/partial_tracking.h
@@ -78,6 +78,11 @@ class SMSPartialTracking : public PartialTracking {
SMSPartialTracking();
~SMSPartialTracking();
void max_partials(int new_max_partials);
+ bool realtime();
+ void realtime(bool is_realtime);
+ bool harmonic();
+ void harmonic(bool is_harmonic);
+ void reset();
Peaks update_partials(Frame* frame);
};
diff --git a/tests/test_partial_tracking.cpp b/tests/test_partial_tracking.cpp
index 71c5452..f5c1fff 100644
--- a/tests/test_partial_tracking.cpp
+++ b/tests/test_partial_tracking.cpp
@@ -15,12 +15,104 @@ namespace simpl
{
// ---------------------------------------------------------------------------
+// TestSMSPartialTracking
+// ---------------------------------------------------------------------------
+class TestSMSPartialTracking : public CPPUNIT_NS::TestCase {
+ CPPUNIT_TEST_SUITE(TestSMSPartialTracking);
+ CPPUNIT_TEST(test_basic);
+ CPPUNIT_TEST(test_peaks);
+ CPPUNIT_TEST_SUITE_END();
+
+protected:
+ static const double PRECISION = 0.001;
+ SMSPeakDetection* pd;
+ SMSPartialTracking* pt;
+ SndfileHandle sf;
+ int num_samples;
+
+ void test_basic() {
+ pt->reset();
+ pd->hop_size(256);
+ pd->frame_size(2048);
+
+ sample* audio = new sample[(int)sf.frames()];
+ sf.read(audio, (int)sf.frames());
+
+ Frames frames = pd->find_peaks(num_samples, &(audio[(int)sf.frames() / 2]));
+ frames = pt->find_partials(frames);
+
+ for(int i = 0; i < frames.size(); i++) {
+ CPPUNIT_ASSERT(frames[i]->num_peaks() > 0);
+ CPPUNIT_ASSERT(frames[i]->num_partials() > 0);
+ }
+ }
+
+ void test_peaks() {
+ pt->reset();
+
+ Frames frames;
+ Peaks peaks;
+ int num_frames = 8;
+
+ for(int i = 0; i < num_frames; i++) {
+ Peak* p = new Peak();
+ p->amplitude = 0.2;
+ p->frequency = 220;
+
+ Peak* p2 = new Peak();
+ p2->amplitude = 0.2;
+ p2->frequency = 440;
+
+ Frame* f = new Frame();
+ f->add_peak(p);
+ f->add_peak(p2);
+
+ frames.push_back(f);
+ peaks.push_back(p);
+ peaks.push_back(p2);
+ }
+
+ pt->find_partials(frames);
+ for(int i = 0; i < num_frames; i++) {
+ CPPUNIT_ASSERT(frames[i]->num_peaks() > 0);
+ CPPUNIT_ASSERT(frames[i]->num_partials() > 0);
+ CPPUNIT_ASSERT(frames[i]->partial(0)->amplitude == 0.2);
+ CPPUNIT_ASSERT(frames[i]->partial(0)->frequency == 220);
+ CPPUNIT_ASSERT(frames[i]->partial(1)->amplitude == 0.2);
+ CPPUNIT_ASSERT(frames[i]->partial(1)->frequency == 440);
+ }
+
+ for(int i = 0; i < num_frames * 2; i++) {
+ delete peaks[i];
+ }
+
+ for(int i = 0; i < num_frames; i++) {
+ delete frames[i];
+ }
+ }
+
+public:
+ void setUp() {
+ pd = new SMSPeakDetection();
+ pt = new SMSPartialTracking();
+ pt->realtime(1);
+ sf = SndfileHandle("../tests/audio/flute.wav");
+ num_samples = 4096;
+ }
+
+ void tearDown() {
+ delete pd;
+ delete pt;
+ }
+};
+
+// ---------------------------------------------------------------------------
// TestLorisPartialTracking
// ---------------------------------------------------------------------------
class TestLorisPartialTracking : public CPPUNIT_NS::TestCase {
CPPUNIT_TEST_SUITE(TestLorisPartialTracking);
CPPUNIT_TEST(test_basic);
- // CPPUNIT_TEST(test_simple_peaks);
+ CPPUNIT_TEST(test_peaks);
CPPUNIT_TEST_SUITE_END();
protected:
@@ -47,7 +139,7 @@ protected:
}
}
- void test_simple_peaks() {
+ void test_peaks() {
pt->reset();
Frames frames;
@@ -107,6 +199,7 @@ public:
} // end of namespace simpl
+CPPUNIT_TEST_SUITE_REGISTRATION(simpl::TestSMSPartialTracking);
CPPUNIT_TEST_SUITE_REGISTRATION(simpl::TestLorisPartialTracking);
int main(int arg, char **argv) {