diff options
| author | Comment <tim@gray.(none)> | 2013-12-10 01:43:12 +0000 |
|---|---|---|
| committer | Comment <tim@gray.(none)> | 2013-12-10 01:43:12 +0000 |
| commit | 979ace4891f439f6fef35db6c1b0a40e4d86b8de (patch) | |
| tree | 78300eab8c099f833faf15394a0efc51cfdb2308 /rotord/src/nodes_audio_analysis.cpp | |
| parent | 7f36d65df273193ea373428ce130f0fd1fa9e3ec (diff) | |
| parent | 0b63fd4e7b1bcda9830c2304284ea2daf4073db3 (diff) | |
Merge branch 'master' of eclectronics.org@eclectronics.org:rotor
Conflicts:
rotord/src/nodes_audio_analysis.cpp
Diffstat (limited to 'rotord/src/nodes_audio_analysis.cpp')
| -rw-r--r-- | rotord/src/nodes_audio_analysis.cpp | 126 |
1 files changed, 121 insertions, 5 deletions
diff --git a/rotord/src/nodes_audio_analysis.cpp b/rotord/src/nodes_audio_analysis.cpp index ea44048..f077d41 100644 --- a/rotord/src/nodes_audio_analysis.cpp +++ b/rotord/src/nodes_audio_analysis.cpp @@ -93,7 +93,7 @@ namespace Rotor{ if (i.second.values.size()) { data+=" ("; bool first=true; - for (auto j: i.second.values) { + for (auto j: i.second.values) { if (first){ first=false; } @@ -101,7 +101,7 @@ namespace Rotor{ data=data+toString(j); } data+=") "; - } + } data+="]"; } return data; @@ -109,6 +109,10 @@ namespace Rotor{ bool sortsegments(std::pair<int,double> i,std::pair<int,double> j){ return (i.second<j.second); } + + bool sortseggrps(std::pair<double,vector<pair<double,int> > > i,std::pair<double,vector<pair<double,int> > > j){ + return (i.first<j.first); + } void Intensity_segmenter::cleanup(){ //algorithm idea: //get average tempo and intensity for each segment and store them @@ -131,10 +135,34 @@ namespace Rotor{ analysers["segmenter"].cleanup(); analysers["tempo"].cleanup(); analysers["intensity"].cleanup(); + + //combine with similarity numbers + // 1. count similarity numbers + + map<int,vector<int> > similarities; + + //what do we want to know about these similarities? + // how many are there? map.size() + // how many members are in each one? map[item].size() + // which members are they? auto m: map[item] + + uint32_t i=0; + for (auto f:analysers["segmenter"].features) { + if (f.second.values.size()) { + int group=f.second.values[0]; + if (similarities.find(group)==similarities.end()){ + similarities[group]={}; + } + similarities[group].push_back(i); + } + i++; + } + for (auto s:similarities) cerr<<"group "<<s.first<<" count: "<<s.second.size()<<endl; + cerr<<analysers["segmenter"].features.size()<<" segments"<<endl; cerr<<analysers["tempo"].features.size()<<" tempo features"<<endl; cerr<<analysers["intensity"].features.size()<<" intensity features"<<endl; - uint32_t i=0; + i=0; double min_tempo=9999999.0; double min_intensity=9999999.0; double max_tempo=0.0; @@ -182,11 +210,15 @@ namespace Rotor{ } //make relative scale 0.0-1.0 and save weighted totals vector< pair<int,double>> totals; + vector<double> totalsmap; 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))); + totalsmap.push_back((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 (i=0;i<totals.size();i++) { @@ -214,10 +246,94 @@ namespace Rotor{ cerr<<endl; } } + for (i=0;i<totals.size();i++){ vampHost::feature f; f.values.push_back((double)i-bucketoffsets[i]); features[times[totals[i].first]]=f; - } + } + */ + + /* +sort intensity totals +find out how many segments will share levels apart from similarity levels +start with a structure: +map<inputnum,vector<pair<tempo,inputnum>> +start grouping by similarity +if there are more similarity groups than wantedgroups, start by grouping similarities +otherwise take biggest similarity groups and split them by intensity +if there are still too many groups, merge closest smallest groups +finally sort by intensity to map output + +nned to retrieve total intensity by segment + */ + // segment group_intensity seg_intense segment + vector<pair<double,vector<pair<double,int> > > > seggrps; + for (i=0;i<totalsmap.size();i++){ + vector<pair<double,int> > data; + data.push_back(make_pair(totalsmap[i],i)); + seggrps.push_back(make_pair(totalsmap[i],data)); + } + for (auto s:similarities){ + if (s.second.size()>1){ + for (int j=s.second.size()-1;j>0;j--){ + seggrps[s.second[0]].second.push_back(make_pair(totalsmap[s.second[j]],s.second[j])); + //keep running average// should be by area? + seggrps[s.second[0]].first+=(totalsmap[s.second[j]]*(1.0/max(1,(int)seggrps[s.second[0]].second.size()-1))); + double div=seggrps[s.second[0]].second.size()==1?1.0:((double)seggrps[s.second[0]].second.size()-1/(double)seggrps[s.second[0]].second.size()); + //neat! this gives 1,1/2,2/3,3/4.. + seggrps[s.second[0]].first*=div; + seggrps.erase(seggrps.begin()+s.second[j]); + } + } + } + cerr<<"similarities assigned, "<<(totalsmap.size()-seggrps.size())<<" segments merged"<<endl; + //sort the contents by intensity + std::sort(seggrps.begin(),seggrps.end(),sortseggrps); + //possible mergers will be with groups with adjacent intensity + while (seggrps.size()>(int)parameters["levels"]->value){ + //reduce similarity groups + //decide the best 2 to merge + vector<double> diffs; + for (int j=0;j<seggrps.size()-1;j++) diffs.push_back(seggrps[j+1].first-seggrps[j].first); + int smallest=0; + for (int j=1;j<diffs.size();j++) if (diffs[i]<diffs[smallest]) smallest=i; + for (int j=0;j<seggrps[smallest].second.size();j++) { + seggrps[smallest+1].second.push_back(seggrps[smallest].second[j]); + } + seggrps.erase(seggrps.begin()+smallest); + } + cerr<<"intensities merged, "<<seggrps.size()<<" levels remain"<<endl; + while (seggrps.size()<(int)parameters["levels"]->value) { + //split groups + } + + map<int,int> outputvalues; + for (int j=0;j<seggrps.size();j++){ + for (int k=0;k<seggrps[j].second.size();k++){ + outputvalues[seggrps[j].second[k].second]=j; + } + } + + + for (i=0;i<totals.size();i++){ + vampHost::feature f; + f.values.push_back(outputvalues[i]); + features[times[totals[i].first]]=f; + } } -}
\ No newline at end of file +} + +/* +A data structure to represent segments and their mapping to output levels +how do we merge the intensity groups with the similarities? + +we create a list + + + + +... we iterate through the list of segments and place the right output number + + +*/ |
