summaryrefslogtreecommitdiff
path: root/NT/src
diff options
context:
space:
mode:
Diffstat (limited to 'NT/src')
-rw-r--r--NT/src/nodes.h4
-rw-r--r--NT/src/nodes_audio_analysis.cpp4
-rw-r--r--NT/src/nodes_audio_analysis.h127
-rw-r--r--NT/src/rotor.cpp2
-rw-r--r--NT/src/rotor.h25
5 files changed, 78 insertions, 84 deletions
diff --git a/NT/src/nodes.h b/NT/src/nodes.h
index cf1fd3e..6bfb6f5 100644
--- a/NT/src/nodes.h
+++ b/NT/src/nodes.h
@@ -24,7 +24,7 @@ namespace Rotor{
init(settings);
};
const double &get_output(const Frame_parameters &frame){
- value=frame.get_time();
+ value=frame.time;
return value;
}
Time* clone(Json::Value &_settings) { return new Time(_settings);};
@@ -34,7 +34,7 @@ namespace Rotor{
class Multiply: public Double_node {
public:
Multiply(){
- factors=create_array<double>("factors");
+ factors=create_array<double>("factors","Factors to multiply","Factors");
type="multiply";
description="multiplies numbers";
title="Multiply";
diff --git a/NT/src/nodes_audio_analysis.cpp b/NT/src/nodes_audio_analysis.cpp
index 1890b8c..34ad325 100644
--- a/NT/src/nodes_audio_analysis.cpp
+++ b/NT/src/nodes_audio_analysis.cpp
@@ -1,7 +1,7 @@
#include "nodes_audio_analysis.h"
namespace Rotor{
- bool Audio_thumbnailer::init(int _channels,int _bits,int _samples,int _rate) {
+ bool Audio_thumbnailer::init_vamp(int _channels,int _bits,int _samples,int _rate) {
//base_audio_processor::init(_channels,_bits,_samples);
channels=_channels;
bits=_bits;
@@ -64,7 +64,7 @@ namespace Rotor{
}
XML.addValue("data",vdata);
}
- bool Vamp_node::init(int _channels,int _bits,int _samples, int _rate) {
+ bool Vamp_node::init_vamp(int _channels,int _bits,int _samples, int _rate) {
//need these to make sense of data
channels=_channels;
bits=_bits;
diff --git a/NT/src/nodes_audio_analysis.h b/NT/src/nodes_audio_analysis.h
index e239e87..00f4303 100644
--- a/NT/src/nodes_audio_analysis.h
+++ b/NT/src/nodes_audio_analysis.h
@@ -14,7 +14,7 @@ namespace Rotor {
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 bool init_vamp(int _channels,int _bits,int _samples,int _rate)=0;
virtual void cleanup()=0;
virtual void print_summary(){};
virtual string get_features(){return "";};
@@ -34,8 +34,11 @@ namespace Rotor {
accum=0.0;
};
~Audio_thumbnailer(){};
- Audio_thumbnailer* clone(Json::Value& _settings) { return new Audio_thumbnailer();};
- bool init(int _channels,int _bits,int _samples,int _rate);
+ Audio_thumbnailer(Json::Value &settings):Audio_thumbnailer() {
+ init(settings);
+ };
+ Audio_thumbnailer* clone(Json::Value& _settings) { return new Audio_thumbnailer(_settings);};
+ bool init_vamp(int _channels,int _bits,int _samples,int _rate);
void cleanup(){};
int process_frame(uint8_t *data,int samples_in_frame);
void print_vector(xmlIO XML);
@@ -51,7 +54,7 @@ namespace Rotor {
Vamp_node(){
mode=create_attribute("mode","Data output mode","Mode",Enum({"timeline","timesteps","valueline","values"},0));
};
- bool init(int _channels,int _bits,int _samples,int _rate);
+ bool init_vamp(int _channels,int _bits,int _samples,int _rate);
void cleanup();
int process_frame(uint8_t *data,int samples_in_frame);
const double& output(const Frame_parameters &frame) {
@@ -71,7 +74,7 @@ namespace Rotor {
double lk=i->first;
int ln=i->second.number;
if (i->second.values.size()) v1=i->second.values[0];
- switch (mode->get().get_value()){
+ switch (mode->get()){
case VAMPHOST_Timeline:
value= (((frame.time-lk-lk)/(uk-lk))+ln);
case VAMPHOST_Timesteps:
@@ -100,38 +103,16 @@ namespace Rotor {
Variable_type<Enum> *mode;
};
class Audio_analysis: public Vamp_node {
- //vamp node that allows the user to choose a plugin
- public:
- Audio_analysis(){
- //create_attribute("soname","Plugin library to use","Plugin library","vamp-example-plugins");
- //create_attribute("id","ID of Plugin to use","Plugin ID","percussiononsets");
- //create_attribute("analyser","Analyser Plugin to use","Analyser plugin","barbeattracker",{"barbeattracker","segmenter"});
- create_inlet("outputNo","Plugin output to use","Output number",0.0);
- //title="Audio analysis";
- //description="Analyse audio and output";
- NODEID="b769f54e-2d0b-11e3-87dd-f73fc7b1c636";
- };
- Audio_analysis(map<string,string> &settings):Audio_analysis() {
- base_settings(settings);
- soname=find_setting(settings,"soname");
- id=find_setting(settings,"id");
- outputNo=find_setting(settings,"outputNo",0);
- };
- ~Audio_analysis(){};
- Audio_analysis* clone(map<string,string> &_settings) { return new Audio_analysis(_settings);};
- private:
- };
- class Audio_analysis2: public Vamp_node {
//reworked the plugin loader
public:
- Audio_analysis2(){
+ Audio_analysis(){
//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",{"adaptivespectrum","barbeattracker","chromagram","dwt","mfcc","onsetdetector","segmenter","similarity","tempotracker","transcription"});
- create_parameter("outputNo","number","Plugin output to use","Output number",0.0);
+ analyser=create_attribute("analyser","Analyser Plugin to use","Analyser plugin",Enum({"adaptivespectrum","barbeattracker","chromagram","dwt","mfcc","onsetdetector","segmenter","similarity","tempotracker","transcription"},1));
+ output_no=create_inlet("outputNo","Plugin output to use","Output number",0);
title="Audio analysis";
description="Analyse audio and output";
- NODEID="b769f54e-2d0b-11e3-87dd-f73fc7b1c636";
+ type_id="b769f54e-2d0b-11e3-87dd-f73fc7b1c636";
plugins.push_back(make_pair("qm-adaptivespectrogram","qm-vamp-plugins"));
plugins.push_back(make_pair("qm-barbeattracker","qm-vamp-plugins"));
plugins.push_back(make_pair("qm-chromagram","qm-vamp-plugins"));
@@ -143,58 +124,57 @@ namespace Rotor {
plugins.push_back(make_pair("qm-tempotracker","qm-vamp-plugins"));
plugins.push_back(make_pair("qm-transcription","qm-vamp-plugins"));
};
- Audio_analysis2(map<string,string> &settings):Audio_analysis2() {
- base_settings(settings);
- soname=plugins[attributes["analyser"]->intVal-1].second;
- id=plugins[attributes["analyser"]->intVal-1].first;
- outputNo=find_setting(settings,"outputNo",0);
- };
- ~Audio_analysis2(){};
- void init_attribute(const string &attr){
- if (attr=="analyser") {
- soname=plugins[attributes["analyser"]->intVal-1].second;
- id=plugins[attributes["analyser"]->intVal-1].first;
- }
- if (attr=="outputNo") {
- outputNo=parameters["outputNo"]->value;
- }
+ Audio_analysis(Json::Value &settings):Audio_analysis() {
+ init(settings);
};
- Audio_analysis2* clone(map<string,string> &_settings) { return new Audio_analysis2(_settings);};
+ void init(Json::Value s){
+ Vamp_node::init(s);
+ soname=plugins[analyser->get()-1].second;
+ id=plugins[analyser->get()-1].first;
+ outputNo=output_no->get(); //TODO: replace this
+ }
+ ~Audio_analysis(){};
+ Audio_analysis* clone(Json::Value& _settings) { return new Audio_analysis(_settings);};
private:
vector< pair<string,string>> plugins;
+ Variable_type<Enum> *analyser;
+ Variable_type<int> *output_no;
};
class Act_segmenter: public Vamp_node {
//vamp node that applies a ruleset to manage a set of acts via a cycler
public:
Act_segmenter(){
- create_parameter("outputNo","number","Plugin output to use","Output number",0.0);
- create_parameter("acts","number","Number of acts defined","Acts",1.0);
+ output_no=create_inlet("outputNo","Plugin output to use","Output number",0);
+ num_acts=create_inlet("acts","Number of acts defined","Acts",1);
title="Act manager";
description="Applies a ruleset to manage acts based on segments";
- NODEID="c55359a2-2d0b-11e3-8a3d-53fa9c2b8859";
+ type_id="c55359a2-2d0b-11e3-8a3d-53fa9c2b8859";
};
- Act_segmenter(map<string,string> &settings):Act_segmenter() {
- base_settings(settings);
- soname="qm-vamp-plugins";
- id="qm-segmenter";
- outputNo=find_setting(settings,"outputNo",0);
+ Act_segmenter(Json::Value &settings):Act_segmenter() {
+ init(settings);
};
+ void init(Json::Value s){
+ Vamp_node::init(s);
+ soname="qm-vamp-plugins";
+ id="qm-segmenter";
+ outputNo=output_no->get(); //TODO: replace this
+ }
~Act_segmenter(){};
- Act_segmenter* clone(map<string,string> &_settings) { return new Act_segmenter(_settings);};
+ Act_segmenter* clone(Json::Value &settings) { return new Act_segmenter(settings);};
void cleanup(){
Vamp_node::cleanup();
map<double,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);
+ for (int i=0;i<num_acts->get();i++) act_count.push_back(0);
- if (features.size()<=(uint32_t)parameters["acts"]->value+1){
+ if (features.size()<=(uint32_t)num_acts->get()+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 (features.size()<(uint32_t)parameters["acts"]->value+1){
+ while (features.size()<(uint32_t)num_acts->get()+1){
map<int,double> durations;
map<int,double> times;
int i=0;
@@ -248,7 +228,7 @@ namespace Rotor {
f=(*segments.begin()).second;
t=(*segments.begin()).first;
segments.erase(segments.begin());
- for (int i=0;i<(int)parameters["acts"]->value-1;i++) {
+ for (int i=0;i<num_acts->get()-1;i++) {
if (act_count[i]==0||(act_count[i+1]>act_count[i]&&act_count[i]<i)) {
act=i;
break;
@@ -259,8 +239,8 @@ namespace Rotor {
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)) {
+ for (int i=num_acts->get()-1;i>0;i--) {
+ if (act_count[i]==0||(act_count[i-1]>act_count[i]&&act_count[i]<num_acts->get()-i)) {
act=i;
break;
}
@@ -268,7 +248,7 @@ namespace Rotor {
}
if (act==-1){ //all slots are filled equally
- act=(int)parameters["acts"]->value/2;
+ act=num_acts->get()/2;
}
act_count[act]++;
f.number=act;
@@ -281,6 +261,8 @@ namespace Rotor {
features=acts;
}
private:
+ Variable_type<int> *output_no;
+ Variable_type<int> *num_acts;
};
class Intensity_segmenter: public Vamp_node {
@@ -289,20 +271,20 @@ namespace Rotor {
Intensity_segmenter(){
title="Intensity segmenter";
description="Combines the output of segmentation, tempo, and intensity analysis plugins";
- NODEID="6ce236b6-4080-11e3-90b7-74d02b29f6a6";
+ type_id="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.0);
- create_parameter("tempo_weight","number","tempo weight","Tempo weighting",1.0);
- create_parameter("levels","number","levels","Number of intensity levels",0.0);
+ intensity_weight=create_attribute("intensity_weight","intensity weight","Intensity weighting",1.0);
+ tempo_weight=create_attribute("tempo_weight","tempo weight","Tempo weighting",1.0);
+ levels=create_attribute("levels","levels","Number of intensity levels",1);
};
- Intensity_segmenter(map<string,string> &settings):Intensity_segmenter() {
- base_settings(settings);
+ Intensity_segmenter(Json::Value &settings):Intensity_segmenter() {
+ init(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) {
+ Intensity_segmenter* clone(Json::Value &settings) { return new Intensity_segmenter(settings);};
+ bool init_vamp(int _channels,int _bits,int _samples,int _rate) {
features.clear();
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)\
@@ -321,6 +303,9 @@ namespace Rotor {
};
private:
map<string,vampHost::Analyser> analysers;
+ Variable_type<double> *tempo_weight;
+ Variable_type<double> *intensity_weight;
+ Variable_type<int> *levels;
};
}
diff --git a/NT/src/rotor.cpp b/NT/src/rotor.cpp
index 12218e5..1c46cad 100644
--- a/NT/src/rotor.cpp
+++ b/NT/src/rotor.cpp
@@ -41,8 +41,10 @@ Json::Value Variable_array_type<T>::to_json(){
}
//explicit template instantiation to avoid linker errors
+template class Variable_type<int>;
template class Variable_type<double>;
template class Variable_type<string>;
+
template class Variable_array_type<double>;
diff --git a/NT/src/rotor.h b/NT/src/rotor.h
index 8fbba7d..f2e19b5 100644
--- a/NT/src/rotor.h
+++ b/NT/src/rotor.h
@@ -90,11 +90,14 @@ namespace Rotor {
public:
Enum(std::initializer_list<std::string> init={},int def=0) : labels(init), value(def){};
int get_value(){return value;};
+ operator int () const {
+ return value;
+ }
private:
std::vector<std::string> labels;
int value;
};
-
+
class Audio_frame{
public:
Audio_frame(uint16_t *_samples,int _channels,int _numsamples){
@@ -127,7 +130,7 @@ namespace Rotor {
};
class Variable { //pure virtual base type for variable pointers
public:
- Variable():name(""),description(""),title(""),connection(nullptr){};
+ Variable(std::string _name="",std::string _description="",std::string _title=""):name(_name),description(_description),title(_title),connection(nullptr){};
virtual ~Variable(){};
virtual Json::Value to_json()=0;
virtual void init(Json::Value s)=0;
@@ -148,8 +151,7 @@ namespace Rotor {
};
template <class T> class Variable_type : public Variable {
public:
- Variable_type(std::string _name="",std::string _description="",std::string _title="",bool _connectable=true){
- Variable(_name,_description,_title);
+ Variable_type(std::string _name="",std::string _description="",std::string _title="",bool _connectable=true): Variable(_name,_description,_title){
connectable=_connectable;
};
void init(Json::Value s){
@@ -158,6 +160,9 @@ namespace Rotor {
name=s["name"].asString();
input=s["input"].asString();
}
+ void set(const T& val){
+ value=val;
+ }
bool create_connection(std::unordered_map<std::string,Node*> &nodes){
for (auto node:nodes){
if (node.first==input){
@@ -195,13 +200,15 @@ namespace Rotor {
};
class Variable_array: public Variable {
public:
- Variable_array(){};
+ Variable_array(std::string _name="",std::string _description="",std::string _title="",bool _connectable=true): Variable(_name,_description,_title){
+ connectable=_connectable;
+ };
protected:
std::vector<Variable> values;
};
template <class T> class Variable_array_type: public Variable_array {
public:
- Variable_array_type(std::string n){name=n;connectable=true;};
+ Variable_array_type(std::string _name="",std::string _description="",std::string _title="",bool _connectable=true): Variable_array(_name,_description,_title,connectable){};
void init(Json::Value s){
name=s["name"].asString();
if (!s["input"].empty()){
@@ -321,20 +328,20 @@ namespace Rotor {
std::string get_output_type(){return TypeName<NT>::Get();};
template <class IT> Variable_type<IT>* create_inlet(std::string name="",std::string description="",std::string title="",IT _default=IT()){
vars[name]=new Variable_type<IT>(name,description,title,true);
+ dynamic_cast<Variable_type<IT>*>(vars[name])->set(_default);
return (dynamic_cast<Variable_type<IT>*>(vars[name]));
}
template <class IT> Variable_type<IT>* create_attribute(std::string name="",std::string description="",std::string title="",IT _default=IT()){
vars[name]=new Variable_type<IT>(name,description,title,false);
+ dynamic_cast<Variable_type<IT>*>(vars[name])->set(_default);
return (dynamic_cast<Variable_type<IT>*>(vars[name]));
}
template <class IT> Variable_array_type<IT>* create_array(std::string name="",std::string description="",std::string title="",IT _default=IT()){
vars[name]=new Variable_array_type<IT>(name,description,title);
return (dynamic_cast<Variable_array_type<IT>*>(vars[name]));
}
- //enum will require specialisation
- //1st, define the enum data type
protected:
- NT value; //every node has a value so it can return a reference
+ NT value; //every node has an internal value so it can return a reference
};
}