summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rotord/05.xml2
-rw-r--r--rotord/09.xml16
-rw-r--r--rotord/graph.cpp1
-rw-r--r--rotord/libavexporter.h6
-rw-r--r--rotord/rendercontext.cpp15
-rwxr-xr-xrotord/rotor.cpp11
-rwxr-xr-xrotord/rotor.h43
-rw-r--r--rotord/vampHost.cpp12
-rw-r--r--rotord/vampHost.h2
9 files changed, 73 insertions, 35 deletions
diff --git a/rotord/05.xml b/rotord/05.xml
index 93191dd..4566be3 100644
--- a/rotord/05.xml
+++ b/rotord/05.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<patchbay ID="0f7aa258-7c2f-11e2-abbd-133252267708">Sample template ©Rotor 2013
- <node ID="01" type="audio_analysis" soname="qm-vamp-plugins" id="qm-tempotracker" output="signal">beats
+ <node ID="01" type="audio_analysis" soname="qm-vamp-plugins" id="qm-barbeattracker" output="signal">beats
</node>
<node ID="02" type="audio_analysis" soname="qm-vamp-plugins" id="qm-segmenter" output="signal">segmentation
</node>
diff --git a/rotord/09.xml b/rotord/09.xml
index 72ba45c..91bbaf9 100644
--- a/rotord/09.xml
+++ b/rotord/09.xml
@@ -2,13 +2,19 @@
<patchbay ID="0f7aa258-7c2f-11e2-abbd-133252267708">Testing parameter controls ©Rotor 2013
<node ID="01" type="audio_analysis" soname="qm-vamp-plugins" id="qm-tempotracker" output="signal">beats
</node>
- <node ID="02" type="arithmetic" operator="%" value="2.0" output="signal">signal arithmetic
+ <node ID="02" type="audio_analysis" soname="qm-vamp-plugins" id="qm-segmenter" output="signal">beats
+ <parameter name="Feature Type" value="2"/>
+ </node>
+ <node ID="02" type="arithmetic" operator="%" value="1.0" output="signal">signal arithmetic
<signal_input from="01">signal to operate on</signal_input>
</node>
- <node ID="03" type="signal_greyscale" output="image">bar greyscale fading
- <signal_input from="02">signal to visualise</signal_input>
+ <node ID="03" type="testcard" output="image">testcard
+ </node>
+ <node ID="04" type="image_arithmetic" operator="*" value="1.0" output="image">colour segmentation
+ <parameter_input parameter="value" from="02">value control</parameter_input>
+ <image_input from="03">image to operate on</image_input>
</node>
- <node ID="04" type="video_output">video output
- <image_input from="03">image to output</image_input>
+ <node ID="06" type="video_output">video output
+ <image_input from="04">image to output</image_input>
</node>
</patchbay>
diff --git a/rotord/graph.cpp b/rotord/graph.cpp
index 57cae92..eedcd88 100644
--- a/rotord/graph.cpp
+++ b/rotord/graph.cpp
@@ -97,6 +97,7 @@ bool Graph::load(string &filename){
}
else cerr << "Rotor: linking parameter input " << i4 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl;
}
+ nodes[nodeID]->link_params();
xml.popTag();
}
}
diff --git a/rotord/libavexporter.h b/rotord/libavexporter.h
index c5e66e3..03b7580 100644
--- a/rotord/libavexporter.h
+++ b/rotord/libavexporter.h
@@ -459,6 +459,12 @@ namespace libav {
ret = 0;
}
}
+
+ //
+ // added 22 may in memory leak run
+ //
+ sws_freeContext(sws_ctx); //should be done once per render instead of per frame??
+
if (ret != 0) {
//fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
exit(1);
diff --git a/rotord/rendercontext.cpp b/rotord/rendercontext.cpp
index 624b7c1..dec9f34 100644
--- a/rotord/rendercontext.cpp
+++ b/rotord/rendercontext.cpp
@@ -18,7 +18,7 @@ void Render_context::runTask() {
for (auto a: analysers) {
processors.push_back(dynamic_cast<Base_audio_processor*>(a));
}
- if (_load_audio(audio_filename,processors)) {
+ if (load_audio(audio_filename,processors)) {
audio_loaded=true;
state=IDLE;
}
@@ -268,6 +268,7 @@ Command_response Render_context::session_command(const std::vector<std::string>&
}
return response;
}
+/*
//http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/
//great to use c++11 features
@@ -289,7 +290,8 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process
return true;
}
-bool Render_context::_load_audio(const string &filename,vector<Base_audio_processor*> processors){
+*/
+bool Render_context::load_audio(const string &filename,vector<Base_audio_processor*> processors){
av_register_all();
@@ -358,10 +360,14 @@ bool Render_context::_load_audio(const string &filename,vector<Base_audio_proces
graph.duration=((float)formatContext->duration)/AV_TIME_BASE;
std::cout << "This stream has " << codecContext->channels << " channels, a sample rate of " << codecContext->sample_rate << "Hz and "<<samples <<" samples" << std::endl;
- std::cout << "The data is in format " <<codecContext->sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ") "<<std::endl;
+ std::cout << "The data is in format " <<codecContext->sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ")"<<std::endl;
+ //std::cout << "Decoding to format " <<frame->format<< " at "<<frame->sample_rate<<" Hz"<<std::endl;
+
+ //frame->sample_rate=codecContext->sample_rate;
+ map <std::string,float> params;
for (auto p: processors) {
- if(!p->init(codecContext->channels,16,samples,codecContext->sample_rate) ){
+ if(!p->init(codecContext->channels,16,samples,codecContext->sample_rate,params) ){
cerr<<"Plugin failed to initialse"<<endl;
return false;
}
@@ -438,6 +444,7 @@ bool Render_context::_load_audio(const string &filename,vector<Base_audio_proces
// Clean up!
for (auto p: processors) {
p->cleanup();
+ p->print_summary();
}
diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp
index 18988ed..3450607 100755
--- a/rotord/rotor.cpp
+++ b/rotord/rotor.cpp
@@ -65,7 +65,7 @@ bool Signal_output::render(const float duration, const float framerate,string &x
return true;
}
-bool Audio_thumbnailer::init(int _channels,int _bits,int _samples,int _rate) {
+bool Audio_thumbnailer::init(int _channels,int _bits,int _samples,int _rate,const map<string,float> &params) {
//base_audio_processor::init(_channels,_bits,_samples);
channels=_channels;
bits=_bits;
@@ -145,13 +145,13 @@ string Audio_thumbnailer::print(){
delete enc;
return output.str();
}
-bool Audio_analysis::init(int _channels,int _bits,int _samples, int _rate) {
+bool Audio_analysis::init(int _channels,int _bits,int _samples, int _rate, const map<string,float> &params) {
//need these to make sense of data
channels=_channels;
bits=_bits;
samples=_samples;
- return analyser.init(soname,id,_channels,_bits,_samples,_rate);
+ return analyser.init(soname,id,_channels,_bits,_samples,_rate,outputNo,params);
//attempt to load vamp plugin and prepare to receive frames of data
//should the audio analysis contain a vamphost or should it inherit?
@@ -164,12 +164,13 @@ int Audio_analysis::process_frame(uint8_t *data,int samples_in_frame) {
}
void Audio_analysis::cleanup() {
analyser.cleanup();
- //print_features();
+ print_features();
}
void Audio_analysis::print_features(){
for (auto i: analyser.features) {
- cerr<<i.second<<" "<<i.first<<endl;
+ cerr<<" ["<<i.second<<":"<<i.first<<"]";
}
+ cerr<<endl;
}
bool Video_output::render(const float duration, const float framerate,const string &output_filename,const string &audio_filename,float& progress){
diff --git a/rotord/rotor.h b/rotord/rotor.h
index 137f8ee..6ca5da2 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -338,6 +338,7 @@ namespace Rotor {
class Node{
public:
virtual Node* clone(map<string,string> &_settings)=0;
+ virtual ~Node(){};
UUID uid; //every usable node has a UUID
int id;
vector<Signal_input*> inputs; //simple node can have signal inputs, output depends on node type
@@ -357,6 +358,7 @@ namespace Rotor {
output_type=find_setting(settings,"output");
ID=find_setting(settings,"ID");
}
+ virtual void link_params(){}; //TODO make param classes that link automatically
void update_params(const Time_spec& time);
};
class Signal_node: public Node{
@@ -378,8 +380,9 @@ namespace Rotor {
class Base_audio_processor: public Signal_node {
public:
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(int _channels,int _bits,int _samples,int _rate,const map<string,float> &params)=0;
virtual void cleanup()=0;
+ virtual void print_summary(){};
int channels,bits,samples,rate;
};
//actual nodes-------------------------------------------------
@@ -390,28 +393,29 @@ namespace Rotor {
base_settings(settings);
soname=find_setting(settings,"soname");
id=find_setting(settings,"id");
- outputNo=ofToInt(find_setting(settings,"output","0"));
+ outputNo=find_setting(settings,"outputNo",0);
};
Audio_analysis* clone(map<string,string> &_settings) { return new Audio_analysis(_settings);};
- bool init(int _channels,int _bits,int _samples,int _rate);
+ bool init(int _channels,int _bits,int _samples,int _rate,const map<string,float> &params);
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.lower_bound(time.time);
+ 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()){
+ float uk=i->first;
+ i--;
float lk=i->first;
int ln=i->second;
- if (i++!=analyser.features.end()){
- float uk=i->first;
- return (((time.time-lk)/(uk-lk))+ln);
- }
- else return (float)ln;
+ return (((time.time-lk)/(uk-lk))+ln);
}
}
return 0.0f;
}
void print_features();
+ void print_summary(){
+ cerr<<"vamp plugin "<<id<<" of library "<<soname<<" found "<<analyser.features.size()<<" features "<<endl;
+ };
private:
string soname,id;
int outputNo;
@@ -447,6 +451,8 @@ namespace Rotor {
if (_op=="<") op=COMPARISON_Less;
if (_op==">=") op=COMPARISON_Greater_or_equal;
if (_op=="<=") op=COMPARISON_Less_or_equal;
+ }
+ void link_params() {
for (auto p:parameter_inputs){
if (p->parameter=="value") p->receiver=&value;
}
@@ -500,7 +506,10 @@ namespace Rotor {
if (_op=="*") op=ARITHMETIC_multiply;
if (_op=="/") op=ARITHMETIC_divide;
if (_op=="%") op=ARITHMETIC_modulo;
+ }
+ void link_params() {
for (auto p:parameter_inputs){
+ p->receiver=nullptr;
if (p->parameter=="value") p->receiver=&value;
}
};
@@ -818,10 +827,15 @@ namespace Rotor {
if (_op=="*") op=ARITHMETIC_multiply;
if (_op=="/") op=ARITHMETIC_divide;
//if (_op=="%") op=ARITHMETIC_modulo; ??what would this even mean?
+ image=nullptr;
+ }
+ void link_params() {
for (auto p:parameter_inputs){
- if (p->parameter=="value") p->receiver=&value;
+ if (p->parameter=="value") {
+ p->receiver=&value;
+ }
}
- image=nullptr;
+
};
~Image_arithmetic(){if (image) delete image;};
Image *output(const Frame_spec &frame){
@@ -863,6 +877,8 @@ namespace Rotor {
base_settings(settings);
levels_settings(settings);
image=new Image();
+ }
+ void link_params() {
for (auto p:parameter_inputs){
if (p->parameter=="black_in") p->receiver=&black_in;
if (p->parameter=="white_in") p->receiver=&white_in;
@@ -954,6 +970,8 @@ namespace Rotor {
image=new Image();
lastframe=-1;
mode=find_setting(settings,"mode",0.0f);
+ }
+ void link_params() {
for (auto p:parameter_inputs){
if (p->parameter=="black_in") p->receiver=&black_in;
if (p->parameter=="white_in") p->receiver=&white_in;
@@ -1105,7 +1123,7 @@ namespace Rotor {
delete[] data;
};
Audio_thumbnailer* clone(map<string,string> &_settings) { return new Audio_thumbnailer();};
- bool init(int _channels,int _bits,int _samples,int _rate);
+ bool init(int _channels,int _bits,int _samples,int _rate,const map<string,float> &params);
void cleanup(){};
int process_frame(uint8_t *data,int samples_in_frame);
string print();
@@ -1134,7 +1152,6 @@ namespace Rotor {
void cancel(); //interrupt locking process
int make_preview(int nodeID, float time); //starts a frame preview - returns status code - how to retrieve?
bool load_audio(const string &filename,vector<Base_audio_processor*> processors);
- bool _load_audio(const string &filename,vector<Base_audio_processor*> processors);
Render_requirements get_requirements();
bool load_video(const string &nodeID,const string &filename);//can be performance or clip
private:
diff --git a/rotord/vampHost.cpp b/rotord/vampHost.cpp
index 56d57db..14a9b35 100644
--- a/rotord/vampHost.cpp
+++ b/rotord/vampHost.cpp
@@ -588,7 +588,7 @@ float vampHost::QMAnalyser::get_progress(){
mutex.unlock();
return p;
}
-bool vampHost::Analyser::init(const string &soname,const string &id,const int &_channels,const int &_bits,const int &_samples,const int &_rate,const int &_outputNo,const string &_output){
+bool vampHost::Analyser::init(const string &soname,const string &id,const int &_channels,const int &_bits,const int &_samples,const int &_rate,int _outputNo,const map<string,float> &params){
//stuff that only happens once
channels =_channels;
@@ -596,7 +596,7 @@ bool vampHost::Analyser::init(const string &soname,const string &id,const int &_
rate=_rate;
bits=_bits;
outputNo=_outputNo;
- output=_output;
+ //output=_output;
//http://www.mega-nerd.com/libsndfile/api.html#note1
//libsndfile returns -1..1 for fp data
@@ -692,7 +692,7 @@ bool vampHost::Analyser::init(const string &soname,const string &id,const int &_
}
}
od = outputs[outputNo];
- cerr << "Output is: \"" << od.identifier << "\"" << endl;
+ cerr << "Output number "<<outputNo<<": \"" << od.identifier << "\"" << endl;
if (!plugin->initialise(channels, stepSize, blockSize)) {
cerr << "ERROR: Plugin initialise (channels = " << channels
@@ -741,7 +741,7 @@ void vampHost::Analyser::process_frame(uint8_t *data,int samples_in_frame){
//cerr<<plugin->getIdentifier()<<" processed block "<<blocks_processed<<endl;
//I /think/ that the vamp plugin keeps processing through the plugbuf until it encounters 0s
- rt = RealTime::frame2RealTime(currentStep * stepSize, rate);
+ rt = RealTime::frame2RealTime(currentStep * stepSize, rate); //48000); //setting different rate doesn't affect it
Plugin::FeatureSet feat=plugin->process(plugbuf, rt);
@@ -772,7 +772,7 @@ void vampHost::Analyser::cleanup(){
in_block++;
}
- rt = RealTime::frame2RealTime(currentStep * stepSize, rate);
+ rt = RealTime::frame2RealTime(currentStep * stepSize, rate); // //setting different
Plugin::FeatureSet feat=plugin->process(plugbuf, rt);
@@ -788,7 +788,7 @@ void vampHost::Analyser::cleanup(){
featureNo++;
}
- cerr<<plugin->getIdentifier()<<" found "<<(features.size()-1)<<" features"<<endl;
+ //cerr<<plugin->getIdentifier()<<" found "<<(features.size()-1)<<" features"<<endl;
//deal with left over data?
for (int c = 0; c < channels; ++c) {
delete[] plugbuf[c];
diff --git a/rotord/vampHost.h b/rotord/vampHost.h
index 3758055..0ba26fd 100644
--- a/rotord/vampHost.h
+++ b/rotord/vampHost.h
@@ -56,7 +56,7 @@ namespace vampHost {
class Analyser{
//can load any vamp analysis plugin and present its data with a unified interface
public:
- bool init(const string &soname,const string &id,const int &_channels,const int &_bits,const int &_samples,const int &_rate,const int &_outputNo=0,const string &_output="");
+ bool init(const string &soname,const string &id,const int &_channels,const int &_bits,const int &_samples,const int &_rate,const int outputNo,const map<string,float> &params);
void process_frame(uint8_t *data,int samples_in_frame);
void cleanup();