summaryrefslogtreecommitdiff
path: root/rotord/src/nodes_audio_analysis.h
diff options
context:
space:
mode:
Diffstat (limited to 'rotord/src/nodes_audio_analysis.h')
-rw-r--r--rotord/src/nodes_audio_analysis.h83
1 files changed, 47 insertions, 36 deletions
diff --git a/rotord/src/nodes_audio_analysis.h b/rotord/src/nodes_audio_analysis.h
index db33b1f..a3fe5b8 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 "<<id<<" of library "<<soname<<" found "<<analyser.features.size()<<" features "<<endl;
+ cerr<<"vamp plugin "<<id<<" of library "<<soname<<" found "<<features.size()<<" features "<<endl;
};
protected:
string soname,id;
- int outputNo;
- vampHost::Analyser analyser;
+ int outputNo;
map <string,float> params;
- private:
- //??
+ map<float,vampHost::feature> 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<int> 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<int,float> durations;
map<int,float> times;
int i=0;
- for (map<float,vampHost::feature>::iterator f=analyser.features.begin();f!=analyser.features.end();++f){
+ for (map<float,vampHost::feature>::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<float,vampHost::feature> segments=analyser.features;
+ map<float,vampHost::feature> segments=features;
segments.erase(--segments.end());
//assign the acts from the beginning and end in towards the middle
@@ -260,8 +272,8 @@ 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:
@@ -271,41 +283,40 @@ namespace Rotor {
public:
Intensity_segmenter(){
title="Intensity segmenter";
- description="Combines segmentation, tempo and intensity";
- UID="74e05d10-3ffa-11e3-b5f9-7335309da36a";
+ 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();
+ 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);
};
~Intensity_segmenter(){};
Intensity_segmenter* clone(map<string,string> &_settings) { return new Intensity_segmenter(_settings);};
- bool init(int _channels,int _bits,int _samples, int _rate) {
- //params needed?
- 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["tempo"].init("bbc-vamp-plugins","bbc-intensity",_channels,_bits,_samples,_rate,0,params);
- return true;
+ 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);
+ //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();
-
- for (auto f:analysers["segmenter"].features){
-
- }
- //add last item back on
- //acts[(*--analyser.features.end()).first]=analyser.features[(*--analyser.features.end()).first];
- //analyser.features=acts;
- }
+ void cleanup(); //all the fun happens here
+ void print_summary(){
+ cerr<<"Intensity segmenter found "<<features.size()<<" features "<<endl;
+ };
private:
map<string,vampHost::Analyser> analysers;
};
}
+
+
#endif