diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-05-23 16:00:24 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-05-23 16:00:24 +0100 |
| commit | b643511ff513aadbd0485afc6b264702aac41021 (patch) | |
| tree | 1aad48b38f8aa7c4eb0b7aacac69b23e794f4510 | |
| parent | 55513473ca37841b40662e1a0221d7dd260a59b7 (diff) | |
portability
| -rw-r--r-- | rotord/08.xml | 5 | ||||
| -rw-r--r-- | rotord/graph.cpp | 7 | ||||
| -rw-r--r-- | rotord/rendercontext.cpp | 19 | ||||
| -rwxr-xr-x | rotord/rotor.cpp | 4 | ||||
| -rwxr-xr-x | rotord/rotor.h | 45 | ||||
| -rwxr-xr-x | rotord/rotord.cpp | 15 | ||||
| -rwxr-xr-x | rotord/rotord.h | 1 | ||||
| -rw-r--r-- | rotord/vampHost.cpp | 17 | ||||
| -rw-r--r-- | rotord/vampHost.h | 2 |
9 files changed, 77 insertions, 38 deletions
diff --git a/rotord/08.xml b/rotord/08.xml index bbc8479..2643b6b 100644 --- a/rotord/08.xml +++ b/rotord/08.xml @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="ISO-8859-1"?> <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 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 + <parameter name="Feature Type" value="2"/> </node> <node ID="03" type="signal_colour" palette="2FCE03FDF23EFF3D84FA80A7FFBF35" output="image">colour segmentation <signal_input from="02">signal to visualise</signal_input> @@ -14,7 +15,7 @@ <parameter_input parameter="value" from="04">value control</parameter_input> <image_input from="03">image to operate on</image_input> </node> - <node ID="06" type="video_output">video output + <node ID="07" type="video_output">video output <image_input from="05">image to output</image_input> </node> </patchbay> diff --git a/rotord/graph.cpp b/rotord/graph.cpp index eedcd88..655badb 100644 --- a/rotord/graph.cpp +++ b/rotord/graph.cpp @@ -98,6 +98,13 @@ bool Graph::load(string &filename){ else cerr << "Rotor: linking parameter input " << i4 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl; } nodes[nodeID]->link_params(); + //extra key/value pairs that can be specific to sub-settings + int n5=xml.getNumTags("parameter"); + for (int i5=0;i5<n5;i5++){ + nodes[nodeID]->set_parameter(xml.getAttribute("parameter","name","",i5),xml.getAttribute("parameter","value","",i5)); + } + if (n5>0) cerr << "Rotor: found " << n5 << " extra parameters for node '" << nodeID << "'" << endl; + xml.popTag(); } } diff --git a/rotord/rendercontext.cpp b/rotord/rendercontext.cpp index dec9f34..4d49b72 100644 --- a/rotord/rendercontext.cpp +++ b/rotord/rendercontext.cpp @@ -61,11 +61,10 @@ Command_response Render_context::session_command(const std::vector<std::string>& if (command[0]=="PUT") { //get audio file location and initiate analysis if (command.size()>2) { if (state==IDLE) { - //check file exists - Poco::File f=Poco::File(command[3]); + audio_filename=media_dir+command[3]; //for now, store session variables in memory //check file exists + Poco::File f=Poco::File(audio_filename); if (f.exists()) { //pass to worker thread ??if engine is ready?? ??what if engine has finished but results aren't read?? - audio_filename=command[3]; //for now, store session variables in memory add_queue(ANALYSE_AUDIO); response.status=HTTPResponse::HTTP_OK; response.description="<status context='"+command[1]+"'>Starting audio analysis: "+command[3]+"</status>\n"; @@ -127,9 +126,9 @@ Command_response Render_context::session_command(const std::vector<std::string>& //should interrupt whatever is happening? //before begining to load from xml if (state==IDLE) { //eventually not like this - Poco::File f=Poco::File(command[3]); + string graph_filename=graph_dir+command[3]; + Poco::File f=Poco::File(graph_filename); if (f.exists()) { - string graph_filename=command[3]; if (graph.load(graph_filename)) { response.status=HTTPResponse::HTTP_OK; //response.description="<status context='"+command[1]+"'>Rotor: loaded graph "+command[3]+"</status>\n"; @@ -196,10 +195,11 @@ Command_response Render_context::session_command(const std::vector<std::string>& if (command[0]=="PUT") { //get vide file location and initiate analysis if (command.size()>4) { //there should be a filename + a destination node if (state==IDLE) { + string video_filename=media_dir+command[4]; //check file exists - Poco::File f=Poco::File(command[4]); + Poco::File f=Poco::File(video_filename); if (f.exists()) { - if (load_video(command[3],command[4])) { + if (load_video(command[3],video_filename)) { //pass to worker thread ??if engine is ready?? ??what if engine has finished but results aren't read?? //DUMMY RESPONSE response.description="<status context='"+command[1]+"'>Rotor: succesfully loaded "+command[4]+" into video node "+command[3]+"</status>\n"; @@ -241,7 +241,7 @@ Command_response Render_context::session_command(const std::vector<std::string>& if (command[0]=="PUT") { if (command.size()>2) { if (state==IDLE) { - output_filename=command[3]; + output_filename=output_dir+command[3]; if (command.size()>3) { // output_framerate=ofToFloat(command[4]); } @@ -365,9 +365,8 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process //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,params) ){ + if(!p->init(codecContext->channels,16,samples,codecContext->sample_rate) ){ cerr<<"Plugin failed to initialse"<<endl; return false; } diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp index 3450607..5e4c6bb 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,const map<string,float> ¶ms) { +bool Audio_thumbnailer::init(int _channels,int _bits,int _samples,int _rate) { //base_audio_processor::init(_channels,_bits,_samples); channels=_channels; bits=_bits; @@ -145,7 +145,7 @@ string Audio_thumbnailer::print(){ delete enc; return output.str(); } -bool Audio_analysis::init(int _channels,int _bits,int _samples, int _rate, const map<string,float> ¶ms) { +bool Audio_analysis::init(int _channels,int _bits,int _samples, int _rate) { //need these to make sense of data channels=_channels; bits=_bits; diff --git a/rotord/rotor.h b/rotord/rotor.h index 6ca5da2..3b328bf 100755 --- a/rotord/rotor.h +++ b/rotord/rotor.h @@ -243,8 +243,7 @@ namespace Rotor { return *this; } Image * operator*(const float &amount) { - Image *other=new Image(); - other->setup(w,h); + Image *other=new Image(w,h); uint8_t *LUT=new uint8_t[0xFF]; for (int i=0;i<0xFF;i++) { LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i*amount))); @@ -252,42 +251,43 @@ namespace Rotor { for (int i=0;i<w*h*3;i++){ other->RGBdata[i]=LUT[RGBdata[i]]; } + delete LUT; return other; } Image * operator+(const float &amount) { - Image *other=new Image(); - other->setup(w,h); + Image *other=new Image(w,h); uint8_t *LUT=new uint8_t[0xFF]; for (int i=0;i<0xFF;i++) { - LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i+amount))); //should normalise to 0-255? + LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i+(amount*255.0f)))); } for (int i=0;i<w*h*3;i++){ other->RGBdata[i]=LUT[RGBdata[i]]; } + delete LUT; return other; } Image * operator-(const float &amount) { - Image *other=new Image(); - other->setup(w,h); + Image *other=new Image(w,h); uint8_t *LUT=new uint8_t[0xFF]; for (int i=0;i<0xFF;i++) { - LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i-amount))); //should normalise to 0-255? + LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i-(amount*255.0f)))); } for (int i=0;i<w*h*3;i++){ other->RGBdata[i]=LUT[RGBdata[i]]; } + delete LUT; return other; } Image * operator/(const float &amount) { - Image *other=new Image(); - other->setup(w,h); + Image *other=new Image(w,h); uint8_t *LUT=new uint8_t[0xFF]; for (int i=0;i<0xFF;i++) { - LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i/amount))); //should normalise to 0-255? + LUT[i]=(uint8_t)min(0xFF,max(0,(int)(i/amount))); } for (int i=0;i<w*h*3;i++){ other->RGBdata[i]=LUT[RGBdata[i]]; } + delete LUT; return other; } uint8_t *RGBdata; @@ -358,6 +358,7 @@ namespace Rotor { output_type=find_setting(settings,"output"); ID=find_setting(settings,"ID"); } + virtual void set_parameter(const std::string &key,const std::string &value){}; virtual void link_params(){}; //TODO make param classes that link automatically void update_params(const Time_spec& time); }; @@ -380,7 +381,7 @@ 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,const map<string,float> ¶ms)=0; + virtual bool init(int _channels,int _bits,int _samples,int _rate)=0; virtual void cleanup()=0; virtual void print_summary(){}; int channels,bits,samples,rate; @@ -396,8 +397,9 @@ namespace Rotor { 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,const map<string,float> ¶ms); + bool init(int _channels,int _bits,int _samples,int _rate); void cleanup(); + void set_parameter(const std::string &key,const std::string &value){params[key]=ofToFloat(value);}; int process_frame(uint8_t *data,int samples_in_frame); const float output(const Time_spec &time) { if (analyser.features.size()) { @@ -420,6 +422,7 @@ namespace Rotor { string soname,id; int outputNo; vampHost::Analyser analyser; + map <string,float> params; }; class Track_time: public Signal_node { public: @@ -795,8 +798,7 @@ namespace Rotor { if (inputs.size()) { if (inputs[0]->connection){ float sig= ((((Signal_node*)inputs[0]->connection)->get_output(frame))); - float seg=fmod(sig,(int)sig); - uint8_t col=255-((uint8_t)(seg*255.0f)); + uint8_t col=255-((uint8_t)(sig*255.0f)); if (col!=prevcol||image.w!=frame.w||image.h!=frame.h){ image.setup(frame.w,frame.h); for (int i=0;i<image.w*image.h*3;i++){ @@ -1123,7 +1125,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,const map<string,float> ¶ms); + bool init(int _channels,int _bits,int _samples,int _rate); void cleanup(){}; int process_frame(uint8_t *data,int samples_in_frame); string print(); @@ -1143,6 +1145,14 @@ namespace Rotor { state=IDLE; output_framerate=25.0f; audio_loaded=false; + + xmlIO xml; + if(xml.loadFile("settings.xml") ){ + graph_dir=xml.getAttribute("Rotor","graph_dir","",0); + media_dir=xml.getAttribute("Rotor","media_dir","",0); + output_dir=xml.getAttribute("Rotor","output_dir","",0); + } + else cerr<<"Rotor: settings.xml not found, using defaults"<<endl; }; ~Render_context(){delete audio_thumb;}; void runTask(); @@ -1162,6 +1172,9 @@ namespace Rotor { Poco::Mutex mutex; //lock for access from parent thread std::string audio_filename; std::string output_filename; + std::string graph_dir; + std::string media_dir; + std::string output_dir; Audio_thumbnailer *audio_thumb; vampHost::QMAnalyser audio_analyser; diff --git a/rotord/rotord.cpp b/rotord/rotord.cpp index bf1be02..27a09d7 100755 --- a/rotord/rotord.cpp +++ b/rotord/rotord.cpp @@ -283,8 +283,21 @@ void RotorServer::handleHelp(const std::string& name, const std::string& value){ int RotorServer::main(const std::vector<std::string>& args){ if (!_helpRequested) { - unsigned short port = (unsigned short) config().getInt("port", 9980); + + unsigned short port; + + xmlIO xml; + if(xml.loadFile("settings.xml") ){ + port=xml.getAttribute("Rotor","port",9980,0); + } + else cerr<<"Rotord: settings.xml not found, using defaults"<<endl; + + port = (unsigned short) config().getInt("port", port); //override from command line + std::string format(config().getString("format", DateTimeFormat::SORTABLE_FORMAT)); + + + ServerSocket svs(port); HTTPServer srv(new RotorRequestHandlerFactory(),svs, new HTTPServerParams); srv.start(); diff --git a/rotord/rotord.h b/rotord/rotord.h index b53a795..e9eb2a1 100755 --- a/rotord/rotord.h +++ b/rotord/rotord.h @@ -102,7 +102,6 @@ class RotorServer: public Poco::Util::ServerApplication int main(const std::vector<std::string>& args); private: bool _helpRequested; - }; int main(int argc, char** argv) diff --git a/rotord/vampHost.cpp b/rotord/vampHost.cpp index 14a9b35..70a0c63 100644 --- a/rotord/vampHost.cpp +++ b/rotord/vampHost.cpp @@ -694,6 +694,12 @@ bool vampHost::Analyser::init(const string &soname,const string &id,const int &_ od = outputs[outputNo]; cerr << "Output number "<<outputNo<<": \"" << od.identifier << "\"" << endl; + + for (auto i:params){ + plugin->setParameter(i.first,i.second); + cerr << "Set plugin parameter: "<<i.first<<" : "<<i.second<<endl; + } + if (!plugin->initialise(channels, stepSize, blockSize)) { cerr << "ERROR: Plugin initialise (channels = " << channels << ", stepSize = " << stepSize << ", blockSize = " @@ -722,16 +728,17 @@ bool vampHost::Analyser::init(const string &soname,const string &id,const int &_ void vampHost::Analyser::process_frame(uint8_t *data,int samples_in_frame){ int sample=0; + uint16_t *_data=(uint16_t*)data; //process the whole frame which may be f>1<f blocks //when the frame is finished leave the partial block for the next frame while(sample<samples_in_frame) { while(sample<samples_in_frame&&in_block<blockSize) { for (int i=0;i<channels;i++) { - unsigned int this_val=0; - for (int j=0;j<bytes;j++) { - this_val+=data[(sample*stride)+(i*bytes)+j]<<(j*8); - } - plugbuf[i][in_block]=((float)((int16_t)this_val))*scale; + //unsigned int this_val=0; + // this_val+=data[(sample*stride)+(i*bytes)+j]<<((1-j)*8); + //} + //plugbuf[i][in_block]=((float)((int16_t)this_val))*scale; + plugbuf[i][in_block]=((float)_data[sample])*scale; } in_block++; sample++; diff --git a/rotord/vampHost.h b/rotord/vampHost.h index 0ba26fd..fbf5228 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,const map<string,float> ¶ms); + bool 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> ¶ms); void process_frame(uint8_t *data,int samples_in_frame); void cleanup(); |
