diff options
| author | Comment <tim@gray.(none)> | 2013-12-05 01:36:58 +0000 |
|---|---|---|
| committer | Comment <tim@gray.(none)> | 2013-12-05 01:36:58 +0000 |
| commit | 674173fb17ca25b1b35d6482de6f603cc3d8209c (patch) | |
| tree | fb651966aa14b4acc92d1355938575c10e2090f0 /rotord/src | |
| parent | 8cfc0a3581cad5da07da69b70c71e67256739166 (diff) | |
signal output
Diffstat (limited to 'rotord/src')
| -rw-r--r-- | rotord/src/graph.cpp | 45 | ||||
| -rw-r--r-- | rotord/src/graph.h | 2 | ||||
| -rw-r--r-- | rotord/src/rendercontext.cpp | 13 | ||||
| -rw-r--r-- | rotord/src/rotor.h | 73 |
4 files changed, 92 insertions, 41 deletions
diff --git a/rotord/src/graph.cpp b/rotord/src/graph.cpp index 7afb92e..f26db6a 100644 --- a/rotord/src/graph.cpp +++ b/rotord/src/graph.cpp @@ -24,23 +24,30 @@ Node* Graph::find_node(const string &type){ } return nullptr; //can be tested against }; -bool Graph::signal_render(xmlIO &XML,const float framerate) { - if (find_node("signal_output")) { - Signal_output *signal_output=dynamic_cast<Signal_output*>(find_node("signal_output")); - //return signal_output->render(duration,framerate,signal_xml); - float sig=0.0f; - string val=""; - for (float i=0;i<duration;i+=1.0f/framerate){ - float s=(signal_output->get_output(Time_spec(i,framerate,duration))+1.0f)/10.0f; - if (!fequal(sig,s)){ - val+=toString(i)+":"+toString(s)+" "; - sig=s; +bool Graph::signal_render(xmlIO &XML,const string &node,const float framerate) { + if (nodes.find(node)!=nodes.end()){ + Signal_node *signal_output=dynamic_cast<Signal_node*>(nodes[node]); + if (signal_output) { + //return signal_output->render(duration,framerate,signal_xml); + XML.addValue("signal_duration",duration); + XML.addValue("signal_framerate",framerate); + float sig=0.0f; + string val=""; + for (float i=0;i<duration;i+=1.0f/framerate){ + float s=(signal_output->get_output(Time_spec(i,framerate,duration))+1.0f)/10.0f; + if (!fequal(sig,s)){ + val+=toString(i)+","+toString(s)+" "; + sig=s; + } } + XML.addValue("signal",val); + return true; } - XML.addValue("signal",val); - return true; + cerr<<"Error: /"<<node<<"/ is not a signal node"<<endl; + + return false; } - cerr<<"Rotor: signal output node not found"<<endl; + cerr<<"Error: signal output node not found"<<endl; return false; } @@ -145,7 +152,7 @@ bool Graph::video_render(const string &output_filename,const float framerate,int uint16_t *audio=nullptr; int samples_in_frame; - for (auto n:nodes) n.second->reset_timer(); + for (auto n:nodes) n.second->reset(); if (usingaudio){ samples_in_frame=(audioloader.get_sample_rate())/framerate; @@ -400,10 +407,10 @@ bool Graph::parseJson(string &data,string &media_path){ //handle expandable inputs - if ((((Image_node*)nodes[nodeID])->image_inputs.size()<=jnodes[i]["image_inputs"].size())&&((Image_node*)nodes[nodeID])->duplicate_inputs){ + if ((((Image_node*)nodes[nodeID])->image_inputs.size()<jnodes[i]["image_inputs"].size())&&((Image_node*)nodes[nodeID])->duplicate_inputs){ string desc=((Image_node*)nodes[nodeID])->image_inputs[0]->description; string title=((Image_node*)nodes[nodeID])->image_inputs[0]->title; - while(((Image_node*)nodes[nodeID])->image_inputs.size()<=jnodes[i]["image_inputs"].size()){ + while(((Image_node*)nodes[nodeID])->image_inputs.size()<jnodes[i]["image_inputs"].size()){ ((Image_node*)nodes[nodeID])->create_image_input(desc,title); cerr<<"creating an image input"<<endl; } @@ -519,10 +526,10 @@ bool Graph::parseXml(string media_path){ uint32_t n3=xml.getNumTags("image_input"); for (uint32_t i3=0;i3<n3;i3++){ //handle expandable inputs - if ((((Image_node*)nodes[nodeID])->image_inputs.size()<=i3)&&((Image_node*)nodes[nodeID])->duplicate_inputs){ + if ((((Image_node*)nodes[nodeID])->image_inputs.size()<i3)&&((Image_node*)nodes[nodeID])->duplicate_inputs){ string desc=((Image_node*)nodes[nodeID])->image_inputs[0]->description; string title=((Image_node*)nodes[nodeID])->image_inputs[0]->title; - while(((Image_node*)nodes[nodeID])->image_inputs.size()<=i3){ + while(((Image_node*)nodes[nodeID])->image_inputs.size()<i3){ ((Image_node*)nodes[nodeID])->create_image_input(desc,title); } } diff --git a/rotord/src/graph.h b/rotord/src/graph.h index a231c29..b9647bc 100644 --- a/rotord/src/graph.h +++ b/rotord/src/graph.h @@ -51,7 +51,7 @@ namespace Rotor { std::unordered_map<string,Node*> nodes; vector<Node*> find_nodes(const string &type); //could be a way of finding a set based on capabilities? Node* find_node(const string &type); - bool signal_render(xmlIO &XML,const float framerate); + bool signal_render(xmlIO &XML,const string &node,const float framerate); bool video_render(const string &output_filename,const float framerate,int start, int end); bool load(string data,string media_path); bool loadFile(string &filename,string media_path); diff --git a/rotord/src/rendercontext.cpp b/rotord/src/rendercontext.cpp index 2f07c89..e73f0d3 100644 --- a/rotord/src/rendercontext.cpp +++ b/rotord/src/rendercontext.cpp @@ -296,13 +296,11 @@ void Render_context::session_command(const Session_command& command,xmlIO& XML,H if (command.commands[1]=="signal") { if (command.method=="GET") { //generate xml from 1st signal output if (state==IDLE) { - //direct call for testing - float framerate=25.0f; - //if (command.size()>2) { - // framerate=toFloat(command.id); - //} - //string signal_xml; - if (graph.signal_render(XML,framerate)){ + if (command.commands.size()>2) { + float framerate; + framerate=toFloat(command.body); + if (framerate==0.0f) framerate=graph.framerate; + if (graph.signal_render(XML,command.commands[2],framerate)){ status=HTTPResponse::HTTP_OK; logger.information("rendering signal to xml"); //XML.addValue("signal",signal_xml); //this doesn't work >> pseudo xml @@ -316,6 +314,7 @@ void Render_context::session_command(const Session_command& command,xmlIO& XML,H // status=HTTPResponse::HTTP_NOT_FOUND; // XML.addValue("error","Signal output not found in graph"); //} + } } else { status=HTTPResponse::HTTP_SERVICE_UNAVAILABLE; diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h index 943464d..50fcef7 100644 --- a/rotord/src/rotor.h +++ b/rotord/src/rotor.h @@ -373,6 +373,7 @@ namespace Rotor { }; virtual void init_attribute(const string &attr){ }; + virtual void init(){}; //initialise any state variables that expect a linear render string description; string type; string ID; @@ -410,8 +411,9 @@ namespace Rotor { void set_parameter(const std::string &key,const std::string &value){ if (parameters.find(key)!=parameters.end()) parameters[key]->value=toFloat(value); }; - void reset_timer(){ + void reset(){ time_taken=0.0f; + int(); } void time_frame(){ struct timeval end_time; @@ -508,6 +510,15 @@ namespace Rotor { #define CYCLER_abs 1 #define CYCLER_rel 2 #define CYCLER_stretch 3 + + #define CYCLER_screen 3 + #define CYCLER_multiply 4 + #define CYCLER_alpha 5 + #define CYCLER_wrap 6 + #define CYCLER_xor 7 + #define CYCLER_overlay 8 + #define CYCLER_min 9 + #define CYCLER_max 10 //new mode that remaps sequence length to segments //combined with a video mode that maps video length to duration //time remapper object @@ -537,25 +548,26 @@ namespace Rotor { Video_cycler(){ create_image_input("Image input","Image input"); create_signal_input("Selector","Selector input"); - create_attribute("mode","Cycling mode","Mode","cut",{"cut","mix"}); - create_attribute("length_mode","Transition length mode","Length mode","seconds",{"seconds","fraction"}); + create_attribute("mode","Cycling mode","Mode","cut",{"cut","mix","screen","multiply","alpha","wrap","xor","overlay","min","max"}); + create_attribute("length_mode","Transition length mode","Length mode","fraction",{"seconds","fraction"}); create_attribute("time_mode","Time mode","time mode","absolute",{"absolute","relative"}); - create_parameter("transition_length","number","transition length","Transition length",-1.0f,0.0f,0.0f); + create_parameter("transition_length","number","transition length","Transition length",1.0f,0.0f,0.0f); title="Video cycler"; description="Cycles through video inputs according to selector signal"; duplicate_inputs=true; NODEID="93dd9d76-2d09-11e3-9589-5bbbeea1b304"; - segment=0; - segment_start=segment_end=0.0f; - prevseg=0; - prevseg_start=0.0f; - lastframe=0; } Video_cycler(map<string,string> &settings):Video_cycler() { base_settings(settings); }; ~Video_cycler(){}; bool load(const string &filename); + void init(){ + segment=0; + segment_start=0.0f; + prevseg_start=0.0f; + lastframe=0; + } Image *output(const Frame_spec &frame){ //work out timing @@ -575,6 +587,7 @@ namespace Rotor { while ((int)inputs[0]->get(testframe)==seg&&testframe.time<frame.duration){ testframe=testframe.nextframe(); } + //nextseg=(int)inputs[0]->get(testframe); segment_end=((Time_spec)testframe).time; //cerr<<"Video_cycler: segment "<<seg<<" preroll: "<<prevseg_start<<" start: "<<segment_start<<" end: "<<segment_end<<endl; } @@ -643,7 +656,7 @@ namespace Rotor { //awkward, its getting close to the point where we just need access to all of the segments data everywhere? //we have 2 times here - if (attributes["mode"]->intVal==CYCLER_mix&&image_inputs.size()>1){ + if (attributes["mode"]->intVal>=CYCLER_mix&&image_inputs.size()>1){ int im1=seg%image_inputs.size(); int im2=prevseg%image_inputs.size(); @@ -658,6 +671,8 @@ namespace Rotor { break; } + //cerr<<f<<" of input "<<(seg%image_inputs.size())<<" & "<<(1.0f-f)<<" of input "<<(prevseg%image_inputs.size())<<endl; + Image *in1=image_inputs[im1]->get(attributes["time_mode"]->intVal==CYCLER_abs?frame:inframe); if (in1){ @@ -668,7 +683,37 @@ namespace Rotor { image*=f; Image i2=(*in2); i2*=(1.0f-f); - image+=i2; + switch(attributes["mode"]->intVal){ + case CYCLER_screen: + image+=i2; + break; + case CYCLER_multiply: + image*=i2; + break; + case CYCLER_xor: + image^=i2; + break; + case CYCLER_alpha: + image=image.alpha_blend(i2); + break; + case CYCLER_wrap: + image=image.add_wrap(i2); + break; + case CYCLER_overlay: + image=image.overlay(i2); + break; + case CYCLER_min: + image=image.min(i2); + break; + case CYCLER_max: + image=image.max(i2); + break; + case CYCLER_mix: //has to be last because of initialser of *in? go figure + + image+=i2; + break; + } + return ℑ } } @@ -678,9 +723,9 @@ namespace Rotor { } //cut mode //for (uint32_t i=0;i<image_inputs.size();i++){ //this skipped a beat for some reason - int whichinput=(((int)inputs[0]->get((Time_spec)frame)))%image_inputs.size(); //+i - Image *in=image_inputs[whichinput]->get(inframe); - if (in) return in; + int whichinput=(((int)inputs[0]->get((Time_spec)frame)))%image_inputs.size(); //+i + Image *in=image_inputs[whichinput]->get(inframe); + if (in) return in; //} return nullptr; } |
