summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt9
-rw-r--r--setup.py2
-rw-r--r--simpl/__init__.py2
-rw-r--r--simpl/peak_detection.pxd6
-rw-r--r--simpl/peak_detection.pyx12
-rw-r--r--src/simpl/peak_detection.cpp75
-rw-r--r--src/simpl/peak_detection.h28
-rw-r--r--tests/test_peak_detection.py23
8 files changed, 148 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ad0e151..4b070df 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,7 +21,7 @@ set(source_files src/simpl/base.cpp
src/sms/peakContinuation.c
src/sms/peakDetection.c
src/sms/residual.c
- src//sms/sineSynth.c
+ src/sms/sineSynth.c
src/sms/sms.c
src/sms/sms.h
src/sms/soundIO.c
@@ -34,6 +34,10 @@ set(source_files src/simpl/base.cpp
src/sms/windows.c
)
+FILE(GLOB sndobj_src src/sndobj/*.cpp)
+FILE(GLOB rfftw_src src/sndobj/rfftw/*.c)
+LIST(APPEND source_files ${source_files} ${sndobj_src} ${rfftw_src})
+
set(include_files src/simpl/simpl.h
src/simpl/base.h
src/simpl/peak_detection.h
@@ -41,9 +45,10 @@ set(include_files src/simpl/simpl.h
src/simpl/synthesis.h
src/simpl/residual.h
src/sms/sms.h
+ src/sndobj/SndObj.h
)
-include_directories(src/simpl src/sms)
+include_directories(src/simpl src/sms src/sndobj src/sndobj/rfftw)
add_library(simpl SHARED ${source_files})
target_link_libraries(simpl m fftw3 gsl gslcblas)
diff --git a/setup.py b/setup.py
index 556bcb6..9983d79 100644
--- a/setup.py
+++ b/setup.py
@@ -74,7 +74,7 @@ fftw_sources = """
sndobj_sources = map(lambda x: 'src/sndobj/' + x, sndobj_sources)
sndobj_sources.extend(map(lambda x: 'src/sndobj/rfftw/' + x, fftw_sources))
-# sources.extend(sndobj_sources)
+sources.extend(sndobj_sources)
sndobj_sources.append("simpl/sndobj.i")
diff --git a/simpl/__init__.py b/simpl/__init__.py
index 101c96d..3b70fb5 100644
--- a/simpl/__init__.py
+++ b/simpl/__init__.py
@@ -8,6 +8,7 @@ Peak = base.Peak
import peak_detection
PeakDetection = peak_detection.PeakDetection
SMSPeakDetection = peak_detection.SMSPeakDetection
+SndObjPeakDetection = peak_detection.SndObjPeakDetection
import partial_tracking
PartialTracking = partial_tracking.PartialTracking
@@ -28,7 +29,6 @@ compare_peak_amps = pybase.compare_peak_amps
compare_peak_freqs = pybase.compare_peak_freqs
import pysndobj
-SndObjPeakDetection = pysndobj.SndObjPeakDetection
SndObjPartialTracking = pysndobj.SndObjPartialTracking
SndObjSynthesis = pysndobj.SndObjSynthesis
diff --git a/simpl/peak_detection.pxd b/simpl/peak_detection.pxd
index c7dfc2e..5fdb395 100644
--- a/simpl/peak_detection.pxd
+++ b/simpl/peak_detection.pxd
@@ -43,3 +43,9 @@ cdef extern from "../src/simpl/peak_detection.h" namespace "simpl":
void max_peaks(int new_max_peaks)
vector[c_Peak*] find_peaks_in_frame(c_Frame* frame)
vector[c_Frame*] find_peaks(int audio_size, double* audio)
+
+ cdef cppclass c_SndObjPeakDetection "simpl::SndObjPeakDetection"(c_PeakDetection):
+ c_SndObjPeakDetection()
+ void hop_size(int new_hop_size)
+ void max_peaks(int new_max_peaks)
+ vector[c_Peak*] find_peaks_in_frame(c_Frame* frame)
diff --git a/simpl/peak_detection.pyx b/simpl/peak_detection.pyx
index 8987564..6afc80a 100644
--- a/simpl/peak_detection.pyx
+++ b/simpl/peak_detection.pyx
@@ -99,3 +99,15 @@ cdef class SMSPeakDetection(PeakDetection):
if self.thisptr:
del self.thisptr
self.thisptr = <c_PeakDetection*>0
+
+
+cdef class SndObjPeakDetection(PeakDetection):
+ def __cinit__(self):
+ if self.thisptr:
+ del self.thisptr
+ self.thisptr = new c_SndObjPeakDetection()
+
+ def __dealloc__(self):
+ if self.thisptr:
+ del self.thisptr
+ self.thisptr = <c_PeakDetection*>0
diff --git a/src/simpl/peak_detection.cpp b/src/simpl/peak_detection.cpp
index 0f118b3..18fca8e 100644
--- a/src/simpl/peak_detection.cpp
+++ b/src/simpl/peak_detection.cpp
@@ -290,3 +290,78 @@ Frames SMSPeakDetection::find_peaks(int audio_size, sample* audio) {
return _frames;
}
+
+
+// ---------------------------------------------------------------------------
+// SndObjPeakDetection
+// ---------------------------------------------------------------------------
+SndObjPeakDetection::SndObjPeakDetection() {
+ _input = new SndObj();
+ _input->SetVectorSize(_frame_size);
+ _window = new HammingTable(_frame_size, 0.5);
+ _ifgram = new IFGram(_window, _input, 1, _frame_size, _hop_size);
+ _analysis = new SinAnal(_ifgram, _threshold, _max_peaks);
+ _threshold = 0.003;
+}
+
+SndObjPeakDetection::~SndObjPeakDetection() {
+ delete _input;
+ delete _window;
+ delete _ifgram;
+ delete _analysis;
+}
+
+void SndObjPeakDetection::frame_size(int new_frame_size) {
+ _frame_size = new_frame_size;
+ _input->SetVectorSize(_frame_size);
+
+ if(_window) {
+ delete _window;
+ }
+ _window = new HammingTable(_frame_size, 0.5);
+
+ _ifgram->Connect("window", _window);
+ _ifgram->Set("fft size", _frame_size);
+}
+
+void SndObjPeakDetection::hop_size(int new_hop_size) {
+ _hop_size = new_hop_size;
+ _ifgram->Set("hop size", _hop_size);
+}
+
+void SndObjPeakDetection::max_peaks(int new_max_peaks) {
+ _max_peaks = new_max_peaks;
+ _analysis->Set("max tracks", _max_peaks);
+}
+
+Peaks SndObjPeakDetection::find_peaks_in_frame(Frame* frame) {
+ Peaks peaks;
+
+ _input->PushIn(frame->audio(), frame->size());
+ _ifgram->DoProcess();
+ int num_peaks = _analysis->FindPeaks();
+
+ for(int i = 0; i < num_peaks; i++) {
+ Peak* p = new Peak();
+ p->amplitude = _analysis->Output(i * 3);
+ p->frequency = _analysis->Output((i * 3) + 1);
+ p->phase = _analysis->Output((i * 3) + 2);
+ peaks.push_back(p);
+
+ frame->add_peak(p);
+
+ // TODO: check that peaks are _min_peak_separation apart
+ //
+ // if not peaks:
+ // peaks.append(p)
+ // else:
+ // if np.abs(p.frequency - peaks[-1].frequency) > self._min_peak_separation:
+ // peaks.append(p)
+ // else:
+ // if p.amplitude > peaks[-1].amplitude:
+ // peaks.remove(peaks[-1])
+ // peaks.append(p)
+ }
+
+ return peaks;
+}
diff --git a/src/simpl/peak_detection.h b/src/simpl/peak_detection.h
index e10c2c3..bcc918b 100644
--- a/src/simpl/peak_detection.h
+++ b/src/simpl/peak_detection.h
@@ -7,6 +7,11 @@ extern "C" {
#include "sms.h"
}
+#include "SndObj.h"
+#include "HammingTable.h"
+#include "IFGram.h"
+#include "SinAnal.h"
+
using namespace std;
@@ -90,6 +95,27 @@ class SMSPeakDetection : public PeakDetection {
};
-} // end of namespace Simpl
+// ---------------------------------------------------------------------------
+// SndObjPeakDetection
+// ---------------------------------------------------------------------------
+class SndObjPeakDetection : public PeakDetection {
+ private:
+ SndObj* _input;
+ HammingTable* _window;
+ IFGram* _ifgram;
+ SinAnal* _analysis;
+ sample _threshold;
+
+ public:
+ SndObjPeakDetection();
+ ~SndObjPeakDetection();
+ void frame_size(int new_frame_size);
+ void hop_size(int new_hop_size);
+ void max_peaks(int new_max_peaks);
+ Peaks find_peaks_in_frame(Frame* frame);
+};
+
+
+} // end of namespace simpl
#endif
diff --git a/tests/test_peak_detection.py b/tests/test_peak_detection.py
index f339818..cd124f0 100644
--- a/tests/test_peak_detection.py
+++ b/tests/test_peak_detection.py
@@ -5,6 +5,7 @@ import simpl.peak_detection as peak_detection
PeakDetection = peak_detection.PeakDetection
SMSPeakDetection = peak_detection.SMSPeakDetection
+SndObjPeakDetection = peak_detection.SMSPeakDetection
float_precision = 5
frame_size = 512
@@ -59,14 +60,11 @@ class TestSMSPeakDetection(object):
assert len(pd.frames[0].peaks)
def test_size_next_read(self):
- """
- Make sure SMSPeakDetection is calculating the correct value for the
- size of the next frame.
- """
audio, sampling_rate = simpl.read_wav(audio_path)
pd = SMSPeakDetection()
pd.hop_size = hop_size
+ pd.static_frame_size = False
pd.max_peaks = max_peaks
current_frame = 0
sample_offset = 0
@@ -102,3 +100,20 @@ class TestSMSPeakDetection(object):
assert frame.num_peaks <= max_peaks, frame.num_peaks
max_amp = max([p.amplitude for p in frame.peaks])
assert max_amp
+
+
+class TestSndObjPeakDetection(object):
+ def test_peak_detection(self):
+ audio, sampling_rate = simpl.read_wav(audio_path)
+
+ pd = SndObjPeakDetection()
+ pd.max_peaks = max_peaks
+ pd.hop_size = hop_size
+ frames = pd.find_peaks(audio[0:num_samples])
+
+ assert len(frames) == num_samples / hop_size
+
+ for frame in frames:
+ assert frame.num_peaks <= max_peaks, frame.num_peaks
+ max_amp = max([p.amplitude for p in frame.peaks])
+ assert max_amp