From 55513473ca37841b40662e1a0221d7dd260a59b7 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Wed, 22 May 2013 19:39:11 +0100 Subject: baffled by audio analysis --- rotord/05.xml | 2 +- rotord/09.xml | 16 +++++++++++----- rotord/graph.cpp | 1 + rotord/libavexporter.h | 6 ++++++ rotord/rendercontext.cpp | 15 +++++++++++---- rotord/rotor.cpp | 11 ++++++----- rotord/rotor.h | 43 ++++++++++++++++++++++++++++++------------- rotord/vampHost.cpp | 12 ++++++------ rotord/vampHost.h | 2 +- 9 files changed, 73 insertions(+), 35 deletions(-) (limited to 'rotord') 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 @@ Sample template ©Rotor 2013 - beats + beats segmentation 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 @@ Testing parameter controls ©Rotor 2013 beats - signal arithmetic + beats + + + signal arithmetic signal to operate on - bar greyscale fading - signal to visualise + testcard + + colour segmentation + value control + image to operate on - video output - image to output + video output + image to output 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(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& } 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 processors){ +*/ +bool Render_context::load_audio(const string &filename,vector processors){ av_register_all(); @@ -358,10 +360,14 @@ bool Render_context::_load_audio(const string &filename,vectorduration)/AV_TIME_BASE; std::cout << "This stream has " << codecContext->channels << " channels, a sample rate of " << codecContext->sample_rate << "Hz and "<sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ") "<sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ")"<format<< " at "<sample_rate<<" Hz"<sample_rate=codecContext->sample_rate; + map 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"<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 ¶ms) { //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 ¶ms) { //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< &_settings)=0; + virtual ~Node(){}; UUID uid; //every usable node has a UUID int id; vector 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 ¶ms)=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 &_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 ¶ms); 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 "<=") 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 &_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 ¶ms); 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 processors); - bool _load_audio(const string &filename,vector 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 ¶ms){ //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 "<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<getIdentifier()<<" processed block "<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<getIdentifier()<<" found "<<(features.size()-1)<<" features"<getIdentifier()<<" found "<<(features.size()-1)<<" features"< ¶ms); void process_frame(uint8_t *data,int samples_in_frame); void cleanup(); -- cgit v1.2.3