diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-09-06 15:04:38 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-09-06 15:04:38 +0100 |
| commit | 48ec56201e2240dcda68f2c384bacc3bdcb405ba (patch) | |
| tree | 45611563f1ef74c49b119050cc2cbbfea8ba752a /rotord/src | |
| parent | 3dbe8f18642b684db0c8abb60c3f4a7a7e7c5dc4 (diff) | |
act segmenter v1
Diffstat (limited to 'rotord/src')
| -rw-r--r-- | rotord/src/nodes_audio_analysis.h | 86 | ||||
| -rw-r--r-- | rotord/src/nodes_drawing.h | 9 | ||||
| -rwxr-xr-x | rotord/src/tinyxml.cpp | 2 | ||||
| -rw-r--r-- | rotord/src/vampHost.cpp | 2 | ||||
| -rw-r--r-- | rotord/src/vampHost.h | 2 |
5 files changed, 84 insertions, 17 deletions
diff --git a/rotord/src/nodes_audio_analysis.h b/rotord/src/nodes_audio_analysis.h index de90d13..7a0ed9e 100644 --- a/rotord/src/nodes_audio_analysis.h +++ b/rotord/src/nodes_audio_analysis.h @@ -12,6 +12,9 @@ namespace Rotor { class Vamp_node: public Audio_processor { //base class for vamp plugin hosts public: + Vamp_node(){ + create_attribute("mode","Data output mode","Mode","timeline",{"timeline","timesteps","valueline","values"}); + }; bool init(int _channels,int _bits,int _samples,int _rate); void cleanup(); int process_frame(uint8_t *data,int samples_in_frame); @@ -25,7 +28,7 @@ namespace Rotor { if (i->second.values.size()) v2=i->second.values[0]; i--; float lk=i->first; - int ln=i->second.number-1; //vamp numbers the first segment 0 + int ln=i->second.number; if (i->second.values.size()) v1=i->second.values[0]; int m=attributes["mode"]->intVal; // @@ -62,7 +65,6 @@ namespace Rotor { //create_attribute("soname","Plugin library to use","Plugin library","vamp-example-plugins",{"horiz","vert","horizR","vertR"}); //create_attribute("id","ID of Plugin to use","Plugin ID","percussiononsets",{"horiz","vert","horizR","vertR"}); create_attribute("analyser","Analyser Plugin to use","Analyser plugin","barbeattracker",{"barbeattracker","segmenter"}); - create_attribute("mode","Data output mode","Mode","timeline",{"timeline","timesteps","valueline","values"}); create_parameter("outputNo","number","Plugin output to use","Output number",0.0f); title="Audio analysis"; description="Analyse audio and output"; @@ -82,7 +84,7 @@ namespace Rotor { public: Act_segmenter(){ create_parameter("outputNo","number","Plugin output to use","Output number",0.0f); - create_parameter("acts","number","Number of acts defined","Acts",0.0f); + create_parameter("acts","number","Number of acts defined","Acts",1.0f); title="Act manager"; description="Applies a ruleset to manage acts based on segments"; }; @@ -96,29 +98,91 @@ namespace Rotor { Act_segmenter* clone(map<string,string> &_settings) { return new Act_segmenter(_settings);}; void cleanup(){ Vamp_node::cleanup(); - //create list of segment durations - vector<float> durations; - for (map<double,vampHost::feature>::iterator f=analyser.features.begin();f!=analyser.features.end();++f){ + map<float,vampHost::feature> acts; //temporary storage for new set of features + vector<int> act_count; + for (int i=0;i<(int)parameters["acts"]->value;i++) act_count.push_back(0); + + map<float,int> durations; //list of segment durations + int i=0; + for (map<float,vampHost::feature>::iterator f=analyser.features.begin();f!=analyser.features.end();++f){ auto g=f; if (++g!=analyser.features.end()){ - durations.push_back(g->first-f->first); + durations[g->first-f->first]=i; } + i++; } //distribute acts amongst segments; if (analyser.features.size()==(int)parameters["acts"]->value+1){ for (auto f: analyser.features){ - acts[f.first]=f.second.number; + acts[f.first]=f.second; } } else if (analyser.features.size()<(int)parameters["acts"]->value+1){ - //find longest segment + //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 + } - else { //extra segments to distribute + else { //there are extra segments to assign to acts + //assign act numbers to segments + + //work through the segments + //have a list of segments that are to be filled + //start at the ends and work inwards + //have a list of how many times each segment has been used + //start with a set of the segments numbers + //(the aim: to access the segment numbers by the time that they start) + map<float,vampHost::feature> segments=analyser.features; + segments.erase(--segments.end()); + + //assign the acts from the beginning and end in towards the middle + bool take_start=true; + while (segments.size()){ + int act=-1; + vampHost::feature f; + float t; + if (take_start){ + f=(*segments.begin()).second; + t=(*segments.begin()).first; + segments.erase(segments.begin()); + for (int i=0;i<(int)parameters["acts"]->value-1;i++) { + if (act_count[i]==0||(act_count[i+1]>act_count[i]&&act_count[i]<i)) { + act=i; + break; + } + } + } + else { + f=(*--segments.end()).second; + t=(*--segments.end()).first; + segments.erase(--segments.end()); + for (int i=(int)parameters["acts"]->value-1;i>0;i--) { + if (act_count[i]==0||(act_count[i-1]>act_count[i]&&act_count[i]<(int)parameters["acts"]->value-i)) { + act=i; + break; + } + } + + } + if (act==-1){ //all slots are filled equally + act=(int)parameters["acts"]->value/2; + } + act_count[act]++; + f.number=act; + acts[t]=f; + take_start=!take_start; + } } + //add last item back on + acts[(*--analyser.features.end()).first]=analyser.features[(*--analyser.features.end()).first]; + analyser.features=acts; } private: - map<double,int> acts; + }; } diff --git a/rotord/src/nodes_drawing.h b/rotord/src/nodes_drawing.h index db1d934..370c0fb 100644 --- a/rotord/src/nodes_drawing.h +++ b/rotord/src/nodes_drawing.h @@ -9,6 +9,7 @@ namespace Rotor { public: Draw_node(){ create_image_input("image input","Image input"); + create_attribute("colour","Colour to fill","Colour","FFFFFF"); //no title or description as it isn't intended for the user }; Draw_node(map<string,string> &settings):Draw_node() { @@ -39,7 +40,10 @@ namespace Rotor { cairo_surface_destroy(cs); return ℑ } + protected: + Colour colour; private: + }; class Text: public Draw_node { public: @@ -51,6 +55,7 @@ namespace Rotor { }; Text(map<string,string> &settings):Text() { base_settings(settings); + colour=Colour(attributes["colour"]->value); }; ~Text(){}; Text* clone(map<string,string> &_settings) { return new Text(_settings);}; @@ -61,7 +66,7 @@ namespace Rotor { } else text=attributes["text"]->value; cairo_text_extents_t te; - cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); + cairo_set_source_rgb(cr, colour.Rfloat(),colour.Gfloat(),colour.Bfloat()); cairo_select_font_face (cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 120); @@ -84,7 +89,6 @@ namespace Rotor { create_parameter("y","number","Y coordinate","Y",0.0f); create_parameter("scale","number","Scale","Scale",1.0f); create_parameter("rotation","number","Rotation","Rotation",0.0f); - create_attribute("colour","Colour to fill","Colour","FFFFFF"); create_attribute("shape","Shape to draw","Shape","square",{"circle","square","triangle"}); }; Shape(map<string,string> &settings):Shape() { @@ -119,7 +123,6 @@ namespace Rotor { cairo_fill(cr); } private: - Colour colour; }; class Audio_viz: public Draw_node { public: diff --git a/rotord/src/tinyxml.cpp b/rotord/src/tinyxml.cpp index ef91984..b5d0451 100755 --- a/rotord/src/tinyxml.cpp +++ b/rotord/src/tinyxml.cpp @@ -1790,7 +1790,7 @@ bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute && element.FirstChild()->ToText()->CDATA() == false ) { simpleTextPrint = true; - //DoLineBreak()! + //DoLineBreak(); } else { diff --git a/rotord/src/vampHost.cpp b/rotord/src/vampHost.cpp index b265c3d..3b16173 100644 --- a/rotord/src/vampHost.cpp +++ b/rotord/src/vampHost.cpp @@ -731,7 +731,7 @@ bool vampHost::Analyser::init(const string &soname,const string &id,const int &_ blocks_processed=0; currentStep=0; - featureNo=1; + featureNo=0; return true; } diff --git a/rotord/src/vampHost.h b/rotord/src/vampHost.h index 241ffce..1f53508 100644 --- a/rotord/src/vampHost.h +++ b/rotord/src/vampHost.h @@ -65,7 +65,7 @@ namespace vampHost { void cleanup(); //map<double,int> features; - map<double,feature> features; + map<float,feature> features; //map<time,featureNo> //this is the best way to store features: because map allows to search for the key below and above the present time |
