summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-05-23 16:00:24 +0100
committerTim Redfern <tim@eclectronics.org>2013-05-23 16:00:24 +0100
commitb643511ff513aadbd0485afc6b264702aac41021 (patch)
tree1aad48b38f8aa7c4eb0b7aacac69b23e794f4510
parent55513473ca37841b40662e1a0221d7dd260a59b7 (diff)
portability
-rw-r--r--rotord/08.xml5
-rw-r--r--rotord/graph.cpp7
-rw-r--r--rotord/rendercontext.cpp19
-rwxr-xr-xrotord/rotor.cpp4
-rwxr-xr-xrotord/rotor.h45
-rwxr-xr-xrotord/rotord.cpp15
-rwxr-xr-xrotord/rotord.h1
-rw-r--r--rotord/vampHost.cpp17
-rw-r--r--rotord/vampHost.h2
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> &params) {
+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> &params) {
+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> &params)=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> &params);
+ 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> &params);
+ 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> &params);
+ 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> &params);
void process_frame(uint8_t *data,int samples_in_frame);
void cleanup();