diff options
Diffstat (limited to 'rotord/src/nodes_audio_analysis.cpp')
| -rw-r--r-- | rotord/src/nodes_audio_analysis.cpp | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/rotord/src/nodes_audio_analysis.cpp b/rotord/src/nodes_audio_analysis.cpp index 220f14b..a2a9c63 100644 --- a/rotord/src/nodes_audio_analysis.cpp +++ b/rotord/src/nodes_audio_analysis.cpp @@ -83,11 +83,11 @@ namespace Rotor{ } void Vamp_node::cleanup() { analyser.cleanup(); - //print_features(); + features=analyser.features; } string Vamp_node::get_features(){ string data; - for (auto i: analyser.features) { + for (auto i: features) { data=data+" ["+toString(i.second.number)+":"+toString(i.first); if (i.second.values.size()) { data+=" ("; @@ -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; + 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; + auto g=++analysers["segmenter"].features.begin(); + 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 |
