From fe435dc1a7be3783165f5dfb524a3db49fa55997 Mon Sep 17 00:00:00 2001 From: John Glover Date: Mon, 25 Jun 2012 22:18:55 +0100 Subject: [base] Add C++/Cython PeakDetection.frames and Frame.peaks --- simpl/base.pyx | 79 +++++++++++++++++++++++++++++++++++------------------- src/simpl/base.cpp | 14 ++++++++-- src/simpl/base.h | 6 +++-- tests/test_base.py | 2 +- 4 files changed, 69 insertions(+), 32 deletions(-) diff --git a/simpl/base.pyx b/simpl/base.pyx index cb43d2f..2fab453 100644 --- a/simpl/base.pyx +++ b/simpl/base.pyx @@ -15,7 +15,7 @@ cdef extern from "" namespace "std": char * c_str() -cdef extern from "../src/simpl/base.h" namespace "simpl": +cdef extern from "../src/simpl/base.h" namespace "simpl": cdef cppclass c_Peak "simpl::Peak": c_Peak() double amplitude @@ -31,18 +31,14 @@ cdef extern from "../src/simpl/base.h" namespace "simpl": int max_peaks() void max_peaks(int new_max_peaks) void add_peak(c_Peak* peak) - # void add_peaks(Peaks* peaks) c_Peak* peak(int peak_number) void clear_peaks() - # Peaks::iterator peaks_begin() - # Peaks::iterator peaks_end() # partials # int num_partials() # int max_partials() # void max_partials(int new_max_partials) # void add_partial(Partial partial) - # Partials::iterator partials() # audio buffers int size() @@ -76,24 +72,26 @@ cdef extern from "../src/simpl/base.h" namespace "simpl": void window_size(int new_window_size) double min_peak_separation() void min_peak_separation(double new_min_peak_separation) - # Frames* frames() - # virtual Peaks* find_peaks_in_frame(const Frame& frame) - # virtual Frames* find_peaks(number* audio) + int num_frames() + c_Frame* frame(int frame_number) + vector[c_Frame*] frames() + # Peaks* find_peaks_in_frame(const Frame& frame) + # Frames* find_peaks(number* audio) cdef class Peak: cdef c_Peak* thisptr - cdef int peak_created + cdef int created - def __cinit__(self, create_new=True): + def __cinit__(self, create_new=True): if create_new: self.thisptr = new c_Peak() - self.peak_created = True + self.created = True else: - self.peak_created = False + self.created = False - def __dealloc__(self): - if self.peak_created: + def __dealloc__(self): + if self.created: del self.thisptr cdef set_peak(self, c_Peak* p): @@ -114,14 +112,24 @@ cdef class Peak: cdef class Frame: cdef c_Frame* thisptr + cdef int created - def __cinit__(self, size=None): - if size: - self.thisptr = new c_Frame(size) + def __cinit__(self, size=None, create_new=True): + if create_new: + if size: + self.thisptr = new c_Frame(size) + else: + self.thisptr = new c_Frame() + self.created = True else: - self.thisptr = new c_Frame() + self.create = False - def __dealloc__(self): del self.thisptr + def __dealloc__(self): + if self.created: + del self.thisptr + + cdef set_frame(self, c_Frame* f): + self.thisptr = f # peaks property num_peaks: @@ -134,6 +142,10 @@ cdef class Frame: def add_peak(self, Peak p not None): self.thisptr.add_peak(p.thisptr) + def add_peaks(self, peaks not None): + for p in peaks: + self.add_peak(p) + def peak(self, int i): cdef c_Peak* c_p = self.thisptr.peak(i) p = Peak(False) @@ -143,6 +155,8 @@ cdef class Frame: property peaks: def __get__(self): return [self.peak(i) for i in range(self.thisptr.num_peaks())] + def __set__(self, peaks): + self.add_peaks(peaks) def clear_peaks(self): self.thisptr.clear_peaks() @@ -153,35 +167,35 @@ cdef class Frame: def __set__(self, int i): self.thisptr.size(i) property audio: - def __get__(self): + def __get__(self): cdef np.npy_intp shape[1] shape[0] = self.thisptr.size() return np.PyArray_SimpleNewFromData(1, shape, np.NPY_DOUBLE, self.thisptr.audio()) - def __set__(self, np.ndarray[dtype_t, ndim=1] a): + def __set__(self, np.ndarray[dtype_t, ndim=1] a): self.thisptr.audio( a.data) property synth: - def __get__(self): + def __get__(self): cdef np.npy_intp shape[1] shape[0] = self.thisptr.size() return np.PyArray_SimpleNewFromData(1, shape, np.NPY_DOUBLE, self.thisptr.synth()) - def __set__(self, np.ndarray[dtype_t, ndim=1] a): + def __set__(self, np.ndarray[dtype_t, ndim=1] a): self.thisptr.synth( a.data) property residual: - def __get__(self): + def __get__(self): cdef np.npy_intp shape[1] shape[0] = self.thisptr.size() return np.PyArray_SimpleNewFromData(1, shape, np.NPY_DOUBLE, self.thisptr.residual()) - def __set__(self, np.ndarray[dtype_t, ndim=1] a): + def __set__(self, np.ndarray[dtype_t, ndim=1] a): self.thisptr.residual( a.data) property synth_residual: - def __get__(self): + def __get__(self): cdef np.npy_intp shape[1] shape[0] = self.thisptr.size() return np.PyArray_SimpleNewFromData(1, shape, np.NPY_DOUBLE, self.thisptr.synth_residual()) - def __set__(self, np.ndarray[dtype_t, ndim=1] a): + def __set__(self, np.ndarray[dtype_t, ndim=1] a): self.thisptr.synth_residual( a.data) @@ -225,3 +239,14 @@ cdef class PeakDetection: property min_peak_separation: def __get__(self): return self.thisptr.min_peak_separation() def __set__(self, double d): self.thisptr.min_peak_separation(d) + + def frame(self, int i): + cdef c_Frame* c_f = self.thisptr.frame(i) + f = Frame(False) + f.set_frame(c_f) + + property frames: + def __get__(self): + return [self.frame(i) for i in range(self.thisptr.num_frames())] + def __set__(self, f): + raise Exception("NotImplemented") diff --git a/src/simpl/base.cpp b/src/simpl/base.cpp index e07f6fe..afffcbb 100644 --- a/src/simpl/base.cpp +++ b/src/simpl/base.cpp @@ -24,7 +24,7 @@ Peak::~Peak() } // Returns true iff this peak is unmatched in the given direction, and has positive amplitude -bool Peak::is_free(const string direction) +bool Peak::is_free(const string direction) { if(amplitude <= 0.0) { @@ -336,6 +336,16 @@ void PeakDetection::min_peak_separation(number new_min_peak_separation) _min_peak_separation = new_min_peak_separation; } +int PeakDetection::num_frames() +{ + return _frames.size(); +} + +Frame* PeakDetection::frame(int frame_number) +{ + return _frames[frame_number]; +} + Frames* PeakDetection::frames() { return &_frames; @@ -363,7 +373,7 @@ Frames* PeakDetection::find_peaks(number* audio) // { // _frame_size = next_frame_size(); // } - + // // get the next frame // Frame f = Frame(_frame_size); // f.audio(audio, pos); diff --git a/src/simpl/base.h b/src/simpl/base.h index f70c952..9f12482 100644 --- a/src/simpl/base.h +++ b/src/simpl/base.h @@ -46,7 +46,7 @@ typedef std::vector Peaks; // --------------------------------------------------------------------------- class Partial {}; -typedef std::vector Partials; +typedef std::vector Partials; // --------------------------------------------------------------------------- // Frame @@ -109,7 +109,7 @@ public: number* synth_residual(); }; -typedef std::vector Frames; +typedef std::vector Frames; // --------------------------------------------------------------------------- // PeakDetection @@ -151,6 +151,8 @@ public: void window_size(int new_window_size); number min_peak_separation(); void min_peak_separation(number new_min_peak_separation); + int num_frames(); + Frame* frame(int frame_number); Frames* frames(); // Find and return all spectral peaks in a given frame of audio diff --git a/tests/test_base.py b/tests/test_base.py index f9807ef..8b00d33 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -46,4 +46,4 @@ class TestFrame(object): class TestPeakDetection(object): def test_peak_detection(self): pd = base.PeakDetection() - print pd + print pd.frames -- cgit v1.2.3