From 858cb95b8539f5695c5348c340b9f982d8b66719 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Tue, 29 Oct 2013 14:45:49 +0000 Subject: making intensity segmenter --- rotord/src/nodes_audio_analysis.h | 95 ++++++++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 17 deletions(-) (limited to 'rotord/src/nodes_audio_analysis.h') diff --git a/rotord/src/nodes_audio_analysis.h b/rotord/src/nodes_audio_analysis.h index 44ea3eb..620f277 100644 --- a/rotord/src/nodes_audio_analysis.h +++ b/rotord/src/nodes_audio_analysis.h @@ -9,6 +9,18 @@ namespace Rotor { #define VAMPHOST_Timesteps 2 #define VAMPHOST_Valueline 3 #define VAMPHOST_Values 4 + class Audio_processor: public Signal_node { + public: + virtual Audio_processor(){}; + virtual ~Audio_processor(){}; + virtual int process_frame(uint8_t *data,int samples)=0; + virtual bool init(int _channels,int _bits,int _samples,int _rate)=0; + virtual void cleanup()=0; + virtual void print_summary(){}; + virtual string get_features(){}; + int channels,bits,samples,rate; + }; + //actual nodes------------------------------------------------- class Audio_thumbnailer: public Audio_processor { public: Audio_thumbnailer(){ @@ -43,9 +55,9 @@ namespace Rotor { void cleanup(); int process_frame(uint8_t *data,int samples_in_frame); const float output(const Time_spec &time) { - if (analyser.features.size()) { - auto i=analyser.features.upper_bound(time.time); //the first element in the container whose key is considered to go after k - if (i!=analyser.features.end()){ + if (features.size()) { + auto i=features.upper_bound(time.time); //the first element in the container whose key is considered to go after k + if (i!=features.end()){ float uk=i->first; float v1,v2; v1=v2=0.0f; @@ -72,15 +84,15 @@ namespace Rotor { } string get_features(); void print_summary(){ - cerr<<"vamp plugin "< params; + map features; + private: + vampHost::Analyser analyser; }; class Audio_analysis: public Vamp_node { //vamp node that allows the user to choose a plugin @@ -170,20 +182,20 @@ namespace Rotor { vector act_count; for (int i=0;i<(int)parameters["acts"]->value;i++) act_count.push_back(0); - if (analyser.features.size()<=(int)parameters["acts"]->value+1){ + if (features.size()<=(int)parameters["acts"]->value+1){ //iteratively split segments and refresh durations //this could work well on the original data //pick the longest and split it in two //refresh durations - this can be a function //keep going //finally copy out - while (analyser.features.size()<(int)parameters["acts"]->value+1){ + while (features.size()<(int)parameters["acts"]->value+1){ map durations; map times; int i=0; - for (map::iterator f=analyser.features.begin();f!=analyser.features.end();++f){ + for (map::iterator f=features.begin();f!=features.end();++f){ auto g=f; - if (++g!=analyser.features.end()){ + if (++g!=features.end()){ durations[i]=g->first-f->first; times[i]=f->first; } @@ -197,10 +209,10 @@ namespace Rotor { n=d.first; } } - analyser.features[times[n]+(durations[n]/2)]=analyser.features[times[n]]; + features[times[n]+(durations[n]/2)]=features[times[n]]; } int j=0; - for (auto f: analyser.features){ + for (auto f: features){ f.second.number=j; acts[f.first]=f.second; j++; @@ -216,7 +228,7 @@ namespace Rotor { //start with a set of the segments numbers //(the aim: to access the segment numbers by the time that they start) - map segments=analyser.features; + map segments=features; segments.erase(--segments.end()); //assign the acts from the beginning and end in towards the middle @@ -260,12 +272,61 @@ namespace Rotor { } } //add last item back on - acts[(*--analyser.features.end()).first]=analyser.features[(*--analyser.features.end()).first]; - analyser.features=acts; + acts[(*--features.end()).first]=features[(*--features.end()).first]; + features=acts; } private: }; + class Intensity_segmenter: public Vamp_node { + //vamp node that applies a ruleset to manage a set of acts via a cycler + public: + Intensity_segmenter(){ + title="Intensity segmenter"; + description="Combines the output of segmentation, tempo, and intensity analysis plugins"; + UID="6ce236b6-4080-11e3-90b7-74d02b29f6a6"; + analysers["segmenter"]=vampHost::Analyser(); + analysers["tempo"]=vampHost::Analyser(); + analysers["intensity"]=vampHost::Analyser(); + }; + Intensity_segmenter(map &settings):Intensity_segmenter() { + base_settings(settings); + }; + ~Intensity_segmenter(){}; + Intensity_segmenter* clone(map &_settings) { return new Intensity_segmenter(_settings);}; + bool init(int _channels,int _bits,int _samples,int _rate) { + return analysers["segmenter"].init("qm-vamp-plugins","qm-segmenter",_channels,_bits,_samples,_rate,0,params)\ + &&analysers["tempo"].init("qm-vamp-plugins","qm-tempotracker",_channels,_bits,_samples,_rate,2,params)\ + &&analysers["intensity"].init("bbc-vamp-plugins","bbc-intensity",_channels,_bits,_samples,_rate,0,params); + } + int process_frame(uint8_t *data,int samples_in_frame) { + //for (auto a:analysers) a.second.process_frame(data,samples_in_frame); //WHY NOT WORK + analysers["segmenter"].process_frame(data,samples_in_frame); + analysers["tempo"].process_frame(data,samples_in_frame); + analysers["intensity"].process_frame(data,samples_in_frame); + return 1; + } + void cleanup(){ + //for (auto a:analysers) a.second.cleanup(); //WHY NOT WORK - its as if the call is const + analysers["segmenter"].cleanup(); + analysers["tempo"].cleanup(); + analysers["intensity"].cleanup(); + cerr< analysers; + }; } #endif -- cgit v1.2.3 From b3abde4531510b7accbc58174ecd9ec27c52ee3a Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Wed, 30 Oct 2013 14:15:47 +0000 Subject: intensity segmenter --- rotord/src/nodes_audio_analysis.cpp | 80 +++++++++++++++++++++++++++++++++++++ rotord/src/nodes_audio_analysis.h | 20 +++------- 2 files changed, 85 insertions(+), 15 deletions(-) (limited to 'rotord/src/nodes_audio_analysis.h') diff --git a/rotord/src/nodes_audio_analysis.cpp b/rotord/src/nodes_audio_analysis.cpp index 1e65668..5318bb1 100644 --- a/rotord/src/nodes_audio_analysis.cpp +++ b/rotord/src/nodes_audio_analysis.cpp @@ -105,4 +105,84 @@ namespace Rotor{ } return data; } + bool sortsegments(std::pair i,std::pair j){ + return (i.second tempos; + vector intensities; + vector times; + for (auto f=analysers["segmenter"].features.begin();g!=analysers["segmenter"].features.end();f++,g++,i++){ + cerr<<"segment "<first<<" to "<first<first); + //integrate tempo and intensity algorithmically + float tempo=0; + if (analysers["tempo"].features.size()) { + float pt=f->first; + float pv=analysers["tempo"].get_value(f->first); + for (auto u=analysers["tempo"].features.upper_bound(f->first);u!=analysers["tempo"].features.upper_bound(g->first);u++){ + tempo +=(u->first-pt)*(u->second.values[0]+pv)*0.5f; //area of the slice + pt=u->first; + pv=u->second.values[0]; + } + tempo +=(g->first-pt)*(analysers["tempo"].get_value(g->first)+pv)*0.5f; //area of the last slice + tempo /=g->first-f->first; //average value; + } + if (tempo>max_tempo) max_tempo=tempo; + if (tempofirst; + float pv=analysers["intensity"].get_value(f->first); + for (auto u=analysers["intensity"].features.upper_bound(f->first);u!=analysers["intensity"].features.upper_bound(g->first);u++){ + intensity +=(u->first-pt)*(u->second.values[0]+pv)*0.5f; //area of the slice + pt=u->first; + pv=u->second.values[0]; + } + intensity +=(g->first-pt)*(analysers["intensity"].get_value(g->first)+pv)*0.5f; //area of the last slice + intensity /=g->first-f->first; //average value; + } + if (intensity>max_intensity) max_intensity=intensity; + if (intensity> totals; + for (i=0;ivalue)+(intensities[i]*parameters["intensity_weight"]->value))); + } + //sort and convert to features + std::sort(totals.begin(),totals.end(),sortsegments); + for (int i=0;i &settings):Intensity_segmenter() { base_settings(settings); @@ -306,21 +308,7 @@ namespace Rotor { analysers["intensity"].process_frame(data,samples_in_frame); return 1; } - void cleanup(){ - //for (auto a:analysers) a.second.cleanup(); //WHY NOT WORK - its as if the call is const - analysers["segmenter"].cleanup(); - analysers["tempo"].cleanup(); - analysers["intensity"].cleanup(); - cerr<