summaryrefslogtreecommitdiff
path: root/rotord/rotor.h
diff options
context:
space:
mode:
authorTim Redfern <tim@herge.(none)>2013-03-06 17:26:24 +0000
committerTim Redfern <tim@herge.(none)>2013-03-06 17:26:24 +0000
commit4e2395d52f9da8efbf7385519f4d7d11a7498f90 (patch)
tree3d46a4f098adb92889381ba5103090ccf241675f /rotord/rotor.h
parentcf9568da9b7698e4d2d507030c1e9ea80cf15291 (diff)
mysterious
Diffstat (limited to 'rotord/rotor.h')
-rwxr-xr-xrotord/rotor.h258
1 files changed, 175 insertions, 83 deletions
diff --git a/rotord/rotor.h b/rotord/rotor.h
index 7c27c36..9f847f6 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -3,36 +3,17 @@ requirement driven design
do we store graphs as files or in a db with UUID as key?
-do we traverse the graph as direct recursive function calls or programmatically from outside?
-or keep a reference to the container graph in each node?
-
-graph parent;
-vector<signal_input> signal_inputs;
-vector<image_input> image_inputs;
-
-//in input
-int input_id;
-
-
-&image get_ouput()
-{
- for (int i=0;i<inputs.size;i++){
- if (inputs[i].input_id) parent.nodes[input_id].get_output(); ///how to find the output in the node? uids for everything?
- }
-
- render();
- return &image_data;
-}
-
-OR
-
-for (int i=0;i<inputs.size;i++){
- if (inputs[i].connection) inputs[i].connection->get_output(); ///methinks this is neater? you can check pointer for NULL, can't be ref
-}
+we traverse the graph as recursive function calls until we satisfy all dependencies
NO NODE HAS MORE THAN ONE OUTPUT
WE DON'T LINK TO AN OUTPUT OBJECT WE LINK TO THE NODE - GET_OUTPUT IS THE RENDER FUNCTION
+??the only node with more than 1 output is audio?
+??lets rethink this
+??audio analysis nodes can be seperate - they can all load from the same audio file - were gonna have to process each pass
+??output splitter? channel splitter? these can be done as 1 object per channel?
+??I think so
+
settings - how do we deal with settings being controllable
signal inputs can have a gui representation as well
other gui items don't have an input
@@ -45,29 +26,16 @@ maybe we should look at time in int (frames) - - what does this imply
is it easier to have a function like:
bool Same_frame(float time1, float time2);
-2 main questions
-authentication - how
-authentication to renderer or just session?
-files - where
-generated images & movies where?
-
-nb where a signal enters a channel comp input - it is duplicated
-
-next - Poco create thread
-
-1st - create thread and return id - create method to kill it
+nb where a signal enters a channel comp input - it is duplicated - so nodes should cache a value (more for time effects)
sql stuff
+NB best way to use is: interface uploads audio and makes thumbnail: graph determines what kind of audio analysis is used by referring to plugins
+jesus where is it hanging in the frigging debugger
-messaging - http factory includes a poco notication center
-when it creates the rotor session it registers it
-session messages are posted thus and consumed
+GOOD GOOD GOOD
-best way to control the rendering process? work queue isn't bad as it means we keep concurrency
-also need to:
-find out what the renderer is doing
-get progress
+next - build signal_output and make a working chain with dummy data
*/
@@ -114,6 +82,7 @@ namespace Rotor {
//forward declaration
class Node;
+
class Render_status{
public:
int id;
@@ -130,40 +99,11 @@ namespace Rotor {
std::string description;
Poco::Net::HTTPResponse::HTTPStatus status;
};
- class Render_context: public Poco::Task { //Poco task object
- //manages a 'patchbay'
- //high level interfaces for the wizard
- //and low level interface onto the graph
- public:
- Render_context(const std::string& name): Task(name) {
- state=IDLE;
- };
- void runTask();
- void add_queue(int item);
- Command_response session_command(const std::vector<std::string>& command);
- Render_status get_status();
- void cancel(); //interrupt locking process
- int make_preview(int nodeID, float time); //starts a frame preview - returns status code - how to retrieve?
- int load_graph(Poco::UUID uid);
- bool load_graph(string graph_filename); //should eventually be as above
- UUID save_graph(); //returns UUID of saved graph
- int load_audio(string filename);
- Render_requirements get_requirements();
- int load_video(int num,string filename); //can be performance or clip
-
- private:
- int state;
- float progress; //for a locking process: audio analysis or rendering
- std::deque<int> work_queue;
- Poco::Mutex mutex; //lock for access from parent thread
- std::string audio_filename;
- vampHost::QMAnalyser audio_analyser;
- xmlIO xml;
- };
class Input{
public:
+ Input(const string &_desc): description(_desc){};
Node* connection;
-
+ string description;
};
class Image_input: public Input{
public:
@@ -171,19 +111,42 @@ namespace Rotor {
};
class Signal_input: public Input{
public:
-
+ bool connect(Node* source);
+ Signal_input(const string &_desc): Input(_desc){};
+
};
class Node{
public:
+ Node(){};
+ virtual ~Node() {};
+ Node(map<string,string> &settings){
+ cerr << "Node:";
+ for (map<string,string>::iterator it=settings.begin();it!=settings.end();++it) {
+ cerr << it->first << "," << it->second << " ";
+ }
+ cerr << endl;
+ description=settings["description"];type=settings["type"];output_type=settings["output"];ID=settings["ID"];
+ };
UUID uid; //every usable node has a UUID
int id;
- vector<Signal_input> inputs; //simple node has signal inputs and outputs
- void get_output(float time);
- void gather_inputs(float time) {
+ vector<Signal_input*> inputs; //simple node has signal inputs and outputs
+ void create_signal_input(const string &description) {inputs.push_back(new Signal_input(description));};
+ void gather_inputs(const float &time) {
for (uint i=0;i<inputs.size();i++){
- if (inputs[i].connection) inputs[i].connection->get_output(time);
+ if (inputs[i]->connection) inputs[i]->connection->get_output(time);
+ }
+ }
+ float get_output(const float &time) { //default is to pass through first input, if disconnected returns 0
+ cerr << "getting output for " << type << "," << ID << endl;
+ if (inputs.size()) {
+ if (inputs[0]->connection) return inputs[0]->connection->get_output(time);
}
+ return 0.0f;
}
+ string description;
+ string type;
+ string output_type;
+ string ID;
};
class Image{
char* data;
@@ -191,7 +154,7 @@ namespace Rotor {
class Image_node: public Node{
public:
vector<Image_input> image_inputs; //image node also has image inputs and outputs
- void gather_inputs(float time) {
+ void gather_inputs(const float &time) {
Node::gather_inputs(time);
for (uint i=0;i<image_inputs.size();i++){
if (image_inputs[i].connection) image_inputs[i].connection->get_output(time);
@@ -209,15 +172,144 @@ namespace Rotor {
private:
float image_time;
};
+ //actual nodes-------------------------------------------------
+ class Audio_analysis: public Node {
+ public:
+ Audio_analysis(){};
+ Audio_analysis(map<string,string> &settings) {
+ cerr << "Audio analysis:";
+ for (map<string,string>::iterator it=settings.begin();it!=settings.end();++it) {
+ cerr << it->first << "," << it->second << " ";
+ }
+ cerr << endl;
+ description=settings["description"];type=settings["type"];output_type=settings["output"];ID=settings["ID"];
+ };
+ float get_output(const float &time) {
+ float t=time;
+ return t;
+ }
+ };
+ class Is_new_integer: public Node {
+ //does this require knowing what the framerate is?
+ //for now, assume 25
+ //what to cache? for now, don't cache
+ public:
+ Is_new_integer(){};
+ Is_new_integer(map<string,string> &settings) {
+ cerr << "Is new integer:";
+ for (map<string,string>::iterator it=settings.begin();it!=settings.end();++it) {
+ cerr << it->first << "," << it->second << " ";
+ }
+ cerr << endl;
+ description=settings["description"];type=settings["type"];output_type=settings["output"];ID=settings["ID"];
+ };
+ float get_output(const float &time) {
+ if (((int)Node::get_output(time))>((int)Node::get_output(time-.04))) return 1.0f;
+ else return 0.0f;
+ }
+ };
+ class Signal_output: public Node {
+ public:
+ Signal_output(){};
+ Signal_output(map<string,string> &settings) {
+ cerr << "Signal output:";
+ for (map<string,string>::iterator it=settings.begin();it!=settings.end();++it) {
+ cerr << it->first << "," << it->second << " ";
+ }
+ cerr << endl;
+ description=settings["description"];type=settings["type"];output_type=settings["output"];ID=settings["ID"];
+ };
+
+ bool render(const float duration, const float framerate,string &xml_out);
+ };
+ //-------------------------------------------------------------------
+ class Node_factory{
+ public:
+ Node_factory();
+ template <typename T>
+ T* clone(T proto,map<string,string> &settings) {
+ cerr << "Factory settings: ";
+ for (map<string,string>::iterator it=settings.begin();it!=settings.end();++it) {
+ cerr << it->first << "," << it->second << " ";
+ }
+ cerr << endl;
+ return new T(settings);
+ }
+ void add_type(string type,Node proto){
+ type_map[type]=proto;
+ };
+ Node* create(map<string,string> &settings){
+ if (type_map.find(settings["type"])!=type_map.end()) {
+ return clone(type_map[settings["type"]],settings);
+ }
+ else return NULL;
+ };
+ private:
+ map<string,Node> type_map;
+ };
class Graph{
public:
- UUID uid; //every version of a graph has a UUID
+ Graph(){framerate=25.0f;duration=10.0f;};
+ Graph(const string& _uid,const string& _desc){ uid=_uid;description=_desc;framerate=25.0f;duration=10.0f;};
+ string uid; //every version of a graph has a UUID, no particular need to actually read its data(?)
+ //?? is it faster than using strings??
+ string description;
+ std::unordered_map<string,Node*> nodes;
+ Node* find(const string &type){
+ for (std::unordered_map<string,Node*>::iterator it=nodes.begin();it!=nodes.end();++it) {
+ if (it->second->type==type) return it->second;
+ }
+ return NULL;
+ };
+ bool signal_render(const float _fr,string &signal_xml) {
+ if (_fr>.001) framerate=_fr;
+ if (find("signal_output")) {
+ Signal_output *signal_output=dynamic_cast<Signal_output*>(find("signal_output"));
+ return signal_output->render(duration,framerate,signal_xml);
+ }
+ else return false;
+ }
+ private:
+ Node_factory factory;
+ float framerate;
+ float duration;
+ };
+ class Render_context: public Poco::Task { //Poco task object
+ //manages a 'patchbay'
+ //high level interfaces for the wizard
+ //and low level interface onto the graph
+ public:
+ Render_context(const std::string& name): Task(name) {
+ state=IDLE;
+ };
+ void runTask();
+ void add_queue(int item);
+ Command_response session_command(const std::vector<std::string>& command);
+ Render_status get_status();
+ void cancel(); //interrupt locking process
+ int make_preview(int nodeID, float time); //starts a frame preview - returns status code - how to retrieve?
+ int load_graph(Poco::UUID uid);
+ bool load_graph(string graph_filename); //should eventually be as above
+ UUID save_graph(); //returns UUID of saved graph
+ int load_audio(string filename);
+ Render_requirements get_requirements();
+ int load_video(int num,string filename); //can be performance or clip
+
private:
- std::unordered_map<int,Node> nodes;
+ int state;
+ float progress; //for a locking process: audio analysis or rendering
+ std::deque<int> work_queue;
+ Poco::Mutex mutex; //lock for access from parent thread
+ std::string audio_filename;
+ vampHost::QMAnalyser audio_analyser;
+ xmlIO xml;
+ Graph graph;
+ Node_factory factory;
};
}
/*
coding style
Types begin with a capital, use underscore as a seperator
+instances begin with a small letter
*/