summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/simpl/base.cpp127
-rw-r--r--src/simpl/base.h61
2 files changed, 166 insertions, 22 deletions
diff --git a/src/simpl/base.cpp b/src/simpl/base.cpp
index 9b0c28d..9c70403 100644
--- a/src/simpl/base.cpp
+++ b/src/simpl/base.cpp
@@ -38,9 +38,7 @@ bool Peak::is_free(const string direction) {
}
}
else {
- // Throw(InvalidArgument, "Invalid direction");
- // TODO: fix this
- printf("ERROR: InvalidArgument\n");
+ return false;
}
return true;
@@ -48,6 +46,37 @@ bool Peak::is_free(const string direction) {
// ---------------------------------------------------------------------------
+// Partial
+// ---------------------------------------------------------------------------
+Partial::Partial() {
+ _starting_frame = 0;
+ _partial_number = -1;
+}
+
+Partial::~Partial() {
+ _peaks.clear();
+}
+
+void Partial::add_peak(Peak* peak) {
+}
+
+int Partial::length() {
+ return _peaks.size();
+}
+
+int Partial::first_frame_number() {
+ return _starting_frame;
+}
+
+int Partial::last_frame_number() {
+ return _starting_frame + length();
+}
+
+Peak* Partial::peak(int peak_number) {
+ return _peaks[peak_number];
+}
+
+// ---------------------------------------------------------------------------
// Frame
// ---------------------------------------------------------------------------
Frame::Frame() {
@@ -68,6 +97,7 @@ Frame::~Frame() {
void Frame::init() {
_max_peaks = 100;
_max_partials = 100;
+ _partials.resize(_max_partials);
_audio = NULL;
_synth = NULL;
_residual = NULL;
@@ -110,14 +140,7 @@ Peak* Frame::peak(int peak_number) {
void Frame::clear() {
_peaks.clear();
-}
-
-Peaks::iterator Frame::peaks_begin() {
- return _peaks.begin();
-}
-
-Peaks::iterator Frame::peaks_end() {
- return _peaks.end();
+ _partials.clear();
}
// Frame - partials
@@ -134,17 +157,18 @@ int Frame::max_partials() {
void Frame::max_partials(int new_max_partials) {
_max_partials = new_max_partials;
- // potentially losing data here but the user shouldn't really do this
+ // TODO: potentially losing data here, should prevent or complain
if((int)_partials.size() > _max_partials) {
_partials.resize(_max_partials);
}
}
-void Frame::add_partial(Partial partial) {
+Peak* Frame::partial(int partial_number) {
+ return _partials[partial_number];
}
-Partials::iterator Frame::partials() {
- return _partials.begin();
+void Frame::partial(int partial_number, Peak* peak) {
+ _partials[partial_number] = peak;
}
@@ -213,7 +237,9 @@ PeakDetection::~PeakDetection() {
void PeakDetection::clear() {
for(int i = 0; i < _frames.size(); i++) {
- delete _frames[i];
+ if(_frames[i]) {
+ delete _frames[i];
+ }
}
_frames.clear();
@@ -333,3 +359,72 @@ Frames PeakDetection::find_peaks(int audio_size, sample* audio) {
return _frames;
}
+
+
+// ---------------------------------------------------------------------------
+// PartialTracking
+// ---------------------------------------------------------------------------
+PartialTracking::PartialTracking() {
+ _sampling_rate = 44100;
+ _max_partials = 100;
+ _min_partial_length = 0;
+ _max_gap = 2;
+}
+
+PartialTracking::~PartialTracking() {
+ clear();
+}
+
+void PartialTracking::clear() {
+ _frames.clear();
+}
+
+int PartialTracking::sampling_rate() {
+ return _sampling_rate;
+}
+
+void PartialTracking::sampling_rate(int new_sampling_rate) {
+ _sampling_rate = new_sampling_rate;
+}
+
+int PartialTracking::max_partials() {
+ return _max_partials;
+}
+
+void PartialTracking::max_partials(int new_max_partials) {
+ _max_partials = new_max_partials;
+}
+
+int PartialTracking::min_partial_length() {
+ return _min_partial_length;
+}
+
+void PartialTracking::min_partial_length(int new_min_partial_length) {
+ _min_partial_length = new_min_partial_length;
+}
+
+int PartialTracking::max_gap() {
+ return _max_gap;
+}
+
+void PartialTracking::max_gap(int new_max_gap) {
+ _max_gap = new_max_gap;
+}
+
+// Streamable (real-time) partial-tracking.
+Peaks PartialTracking::update_partials(Frame* frame) {
+ Peaks peaks;
+ return peaks;
+}
+
+// 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++) {
+ Peaks peaks = update_partials(frames[i]);
+ for(int j = 0; j < peaks.size(); j++) {
+ frames[i]->partial(j, peaks[j]);
+ }
+ }
+ _frames = frames;
+ return _frames;
+}
diff --git a/src/simpl/base.h b/src/simpl/base.h
index b2d0da9..385e2a9 100644
--- a/src/simpl/base.h
+++ b/src/simpl/base.h
@@ -43,8 +43,25 @@ typedef std::vector<Peak*> Peaks;
// ---------------------------------------------------------------------------
// Partial
+//
+// Represents a sinuoidal partial or track, an ordered sequence of Peaks
// ---------------------------------------------------------------------------
-class Partial {};
+class Partial {
+ private:
+ int _starting_frame;
+ long _partial_number;
+ Peaks _peaks;
+
+ public:
+ Partial();
+ ~Partial();
+
+ void add_peak(Peak* peak);
+ int length();
+ int first_frame_number();
+ int last_frame_number();
+ Peak* peak(int peak_number);
+};
typedef std::vector<Partial*> Partials;
@@ -66,7 +83,7 @@ class Frame {
int _max_peaks;
int _max_partials;
Peaks _peaks;
- Partials _partials;
+ Peaks _partials;
sample* _audio;
sample* _synth;
sample* _residual;
@@ -86,15 +103,13 @@ class Frame {
void add_peaks(Peaks* peaks);
Peak* peak(int peak_number);
void clear();
- 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();
+ Peak* partial(int partial_number);
+ void partial(int partial_number, Peak* peak);
// audio buffers
int size();
@@ -165,6 +180,40 @@ class PeakDetection {
virtual Frames find_peaks(int audio_size, sample* audio);
};
+
+// ---------------------------------------------------------------------------
+// PartialTracking
+//
+// Link spectral peaks from consecutive frames to form partials
+// ---------------------------------------------------------------------------
+
+class PartialTracking {
+ private:
+ int _sampling_rate;
+ int _max_partials;
+ int _min_partial_length;
+ int _max_gap;
+ Frames _frames;
+
+ public:
+ PartialTracking();
+ ~PartialTracking();
+
+ void clear();
+
+ int sampling_rate();
+ void sampling_rate(int new_sampling_rate);
+ int max_partials();
+ void max_partials(int new_max_partials);
+ int min_partial_length();
+ void min_partial_length(int new_min_partial_length);
+ int max_gap();
+ void max_gap(int new_max_gap);
+
+ virtual Peaks update_partials(Frame* frame);
+ virtual Frames find_partials(Frames frames);
+};
+
} // end of namespace Simpl
#endif