summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rotord/src/nodes_audio_analysis.cpp80
-rw-r--r--rotord/src/nodes_audio_analysis.h20
2 files changed, 85 insertions, 15 deletions
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<int,float> i,std::pair<int,float> j){
+ return (i.second<j.second);
+ }
+ void Intensity_segmenter::cleanup(){
+ //algorithm idea:
+ //get average tempo and intensity for each segment and store them
+ //scale by the range to get a value from 0.0 to 1.0
+ //add tempo and intensity according to a weighting
+ //score the results (ie 1st place, 2nd place) to end up with a set of integer numbers
+
+ //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["segmenter"].features.size()<<" segments"<<endl;
+ cerr<<analysers["tempo"].features.size()<<" tempo features"<<endl;
+ cerr<<analysers["intensity"].features.size()<<" intensity features"<<endl;
+ auto g=++analysers["segmenter"].features.begin();
+ int i=0;
+ float min_tempo=9999999.0f;
+ float min_intensity=9999999.0f;
+ float max_tempo=0.0f;
+ float max_intensity=0.0f;
+ vector<float> tempos;
+ vector<float> intensities;
+ vector<float> times;
+ for (auto f=analysers["segmenter"].features.begin();g!=analysers["segmenter"].features.end();f++,g++,i++){
+ cerr<<"segment "<<i<<": "<<f->first<<" to "<<g->first<<endl;
+ times.push_back(f->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 (tempo<min_tempo) min_tempo=tempo;
+ tempos.push_back(tempo);
+ cerr<<"segment "<<i<<" average tempo: "<<tempo<<endl;
+
+ float intensity=0;
+ if (analysers["intensity"].features.size()) {
+ float pt=f->first;
+ 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<min_intensity) min_intensity=intensity;
+ intensities.push_back(intensity);
+ cerr<<"segment "<<i<<" average intensity: "<<intensity<<endl;
+ }
+ //make relative scale 0.0-1.0 and save weighted totals
+ vector< pair<int,float>> totals;
+ for (i=0;i<tempos.size();i++){
+ tempos[i]=(tempos[i]-min_tempo)/(max_tempo-min_tempo);
+ intensities[i]=(intensities[i]-min_intensity)/(max_intensity-min_intensity);
+ totals.push_back(make_pair(i,(tempos[i]*parameters["tempo_weight"]->value)+(intensities[i]*parameters["intensity_weight"]->value)));
+ }
+ //sort and convert to features
+ std::sort(totals.begin(),totals.end(),sortsegments);
+ for (int i=0;i<totals.size();i++){
+ vampHost::feature f;
+ f.values.push_back((float)i);
+ features[times[totals[i].first]]=f;
+ }
+ return true;
+ }
} \ No newline at end of file
diff --git a/rotord/src/nodes_audio_analysis.h b/rotord/src/nodes_audio_analysis.h
index 620f277..a3fe5b8 100644
--- a/rotord/src/nodes_audio_analysis.h
+++ b/rotord/src/nodes_audio_analysis.h
@@ -288,6 +288,8 @@ namespace Rotor {
analysers["segmenter"]=vampHost::Analyser();
analysers["tempo"]=vampHost::Analyser();
analysers["intensity"]=vampHost::Analyser();
+ create_parameter("intensity_weight","number","intensity weight","Intensity weighting",1.0f);
+ create_parameter("tempo_weight","number","tempo weight","Tempo weighting",1.0f);
};
Intensity_segmenter(map<string,string> &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<<analysers["segmenter"].features.size()<<" segments"<<endl;
- cerr<<analysers["tempo"].features.size()<<" tempo features"<<endl;
- cerr<<analysers["intensity"].features.size()<<" intensity features"<<endl;
- //auto f=analysers["segmenter"].features.begin();
- //for (auto g=++analysers["segmenter"].features.begin();g!=analysers["segmenter"].features.end();f++,g++){
- // cerr<<"calculating segment from "<<f.first<<" to "<<g.first<<endl;
- // features[f.first]=f.second;
- //}
- return true;
- }
+ void cleanup(); //all the fun happens here
void print_summary(){
cerr<<"Intensity segmenter found "<<features.size()<<" features "<<endl;
};
@@ -329,4 +317,6 @@ namespace Rotor {
};
}
+
+
#endif