summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Redfern <tim@herge.(none)>2013-04-10 16:31:40 +0100
committerTim Redfern <tim@herge.(none)>2013-04-10 16:31:40 +0100
commita29217ecc368cdeee7e908fc7db3c717cc51fd70 (patch)
tree1f6447cfecc19c90a98ff86cb575ad7109371267
parent6275e8f15b63f85c2206f0acb64023610c711f24 (diff)
signal and audio stuff working
-rw-r--r--rotord/rotor.cpp23
-rwxr-xr-xrotord/rotor.h35
-rwxr-xr-xrotord/rotord.cpp37
3 files changed, 35 insertions, 60 deletions
diff --git a/rotord/rotor.cpp b/rotord/rotor.cpp
index af0bd7e..360b75e 100644
--- a/rotord/rotor.cpp
+++ b/rotord/rotor.cpp
@@ -54,11 +54,12 @@ bool Signal_input::connect(Signal_node* source) {
};
bool Signal_output::render(const float duration, const float framerate,string &xml_out){
+ //testing signal routes
cerr << "Rotor: Signal_output rendering " << duration << " seconds at " << framerate << " frames per second" << endl;
float step=1.0f/framerate;
float v=0.0f;
for (float f=0.0f;f<duration;f+=step) {
- float u=get_output(f);
+ float u=get_output(Time_spec(f,framerate));
if (!fequal(u,v)) {
xml_out+=("<signal time='"+ofToString(f)+"'>"+ofToString(u)+"</signal>\n");
v=u;
@@ -68,18 +69,18 @@ bool Signal_output::render(const float duration, const float framerate,string &x
}
Command_response Render_context::session_command(const std::vector<std::string>& command){
- //method,id,command1,{command2,}{body}
- //here we allow the controlling server to communicate with running tasks
+ //method,id,command1,{command2,}{body}
+ //here we allow the controlling server to communicate with running tasks
Command_response response;
response.status=HTTPResponse::HTTP_BAD_REQUEST;
if (command[2]=="audio") {
- if (command[0]=="PUT") { //get audio file location and initiate analysis
+ if (command[0]=="PUT") { //get audio file location and initiate analysis
if (command.size()>2) {
if (state==IDLE) {
- //check file exists
+ //check file exists
Poco::File f=Poco::File(command[3]);
if (f.exists()) {
- //pass to worker thread ??if engine is ready?? ??what if engine has finished but results aren't read??
+ //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.description="<status context='"+command[1]+"'>Starting audio analysis: "+command[3]+"</status>\n";
@@ -133,10 +134,10 @@ Command_response Render_context::session_command(const std::vector<std::string>&
response.description="<status>Rotor: graph not loaded</status>\n";
}
}
- if (command[0]=="PUT") { //get new graph from file
+ if (command[0]=="PUT") { //get new graph from file
if (command.size()>2) {
- //should interrupt whatever is happening?
- //before begining to load from xml
+ //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]);
if (f.exists()) {
@@ -173,7 +174,7 @@ Command_response Render_context::session_command(const std::vector<std::string>&
if (command[0]=="GET") { //generate xml from 1st signal output
if (state==IDLE) {
//direct call for testing
- float framerate=0.0f;
+ float framerate=25.0f;
if (command.size()>2) {
framerate=ofToFloat(command[3]);
}
@@ -324,6 +325,7 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process
av_dump_format(formatContext, 0, 0, false); //avformat.h line 1256
int samples = ((formatContext->duration + 5000)*codecContext->sample_rate)/AV_TIME_BASE;
+ graph.duration=((float)formatContext->duration)/AV_TIME_BASE;
std::cout << "This stream has " << codecContext->channels << " channels, a sample rate of " << codecContext->sample_rate << "Hz and "<<samples <<" samples" << std::endl;
std::cout << "The data is in format " <<codecContext->sample_fmt<< " (aka "<< av_get_sample_fmt_name(codecContext->sample_fmt) << ") "<<std::endl;
@@ -407,6 +409,7 @@ bool Render_context::load_audio(const string &filename,vector<Base_audio_process
p->cleanup();
}
+
av_free(frame);
avcodec_close(codecContext);
av_close_input_file(formatContext);
diff --git a/rotord/rotor.h b/rotord/rotor.h
index 7dbb18d..36ef0aa 100755
--- a/rotord/rotor.h
+++ b/rotord/rotor.h
@@ -139,7 +139,15 @@ namespace Rotor {
AVPacket packet;
};
-
+ class Time_spec{
+ public:
+ Time_spec(float _seconds,float _framerate){ seconds=_seconds; framerate=_framerate; };
+ float seconds;
+ float framerate;
+ const Time_spec lastframe(){
+ return Time_spec(seconds-(1.0f/framerate),framerate);
+ }
+ };
class Render_status{
public:
int id;
@@ -196,7 +204,7 @@ namespace Rotor {
};
class Signal_node: public Node{
public:
- virtual float get_output(const float &time) { return 0.0f; };
+ virtual float get_output(const Time_spec &time) { return 0.0f; };
/*{ //default is to pass through first input, if disconnected returns 0
cerr << "getting output for " << type << "," << ID << endl;
@@ -210,14 +218,14 @@ namespace Rotor {
class Image_node: public Node{
public:
vector<Image_input> image_inputs; //image node also has image inputs and outputs
- Image* get_output(float time){ //sample implementation
+ Image* get_output(const Time_spec &time){ //sample implementation
//do something with the inputs
//and then
return ((Image_node*)image_inputs[0].connection)->get_output(time);
}
- void get_preview(float time);
+ void get_preview(const Time_spec &time);
Image* image; //this can be privately allocated or just passed on as the node see fit
private:
float image_time;
@@ -243,15 +251,15 @@ namespace Rotor {
bool init(int _channels,int _bits,int _samples,int _rate);
void cleanup();
int process_frame(uint8_t *data,int samples_in_frame);
- float get_output(const float &time) {
+ float get_output(const Time_spec &time) {
if (analyser.features.size()) {
- auto i=analyser.features.lower_bound(time);
+ auto i=analyser.features.lower_bound(time.seconds);
if (i!=analyser.features.end()){
float lk=i->first;
int ln=i->second;
if (i++!=analyser.features.end()){
float uk=i->first;
- return (((time-lk)/(uk-lk))+ln);
+ return (((time.seconds-lk)/(uk-lk))+ln);
}
else return (float)ln;
}
@@ -273,7 +281,7 @@ namespace Rotor {
divide_amount=ofToFloat(check(settings,"amount"));
};
Signal_divide* clone(map<string,string> &_settings) { return new Signal_divide(_settings);};
- float get_output(const float &time) {
+ float get_output(const Time_spec &time) {
if (inputs[0]->connection) {
return (((Signal_node*)inputs[0]->connection)->get_output(time))/divide_amount;
}
@@ -282,7 +290,8 @@ namespace Rotor {
float divide_amount;
};
class Is_new_integer: public Signal_node {
- //does this require knowing what the framerate is?
+ //outputs a 1 every time a signal passes a new integer, otherwise a 0.
+ //this requires knowing what the framerate is? how to do this?
//for now, assume 25
//what to cache? for now, don't cache
public:
@@ -291,10 +300,10 @@ namespace Rotor {
base_settings(settings);
};
Is_new_integer* clone(map<string,string> &_settings) { return new Is_new_integer(_settings);};
- float get_output(const float &time) {
+ float get_output(const Time_spec &time) {
if (inputs[0]->connection) {
float s1=(((Signal_node*)(inputs[0]->connection))->get_output(time));
- float s2=(((Signal_node*)(inputs[0]->connection))->get_output(time-.04));
+ float s2=(((Signal_node*)(inputs[0]->connection))->get_output(time.lastframe()));
if (((int)s1)>((int)s2)) {
return 1.0f;
}
@@ -310,7 +319,7 @@ namespace Rotor {
};
Signal_output* clone(map<string,string> &_settings) { return new Signal_output(_settings);};
bool render(const float duration, const float framerate,string &xml_out);
- float get_output(const float &time) {
+ float get_output(const Time_spec &time) {
if (inputs[0]->connection) {
return ((Signal_node*)(inputs[0]->connection))->get_output(time);
}
@@ -369,11 +378,11 @@ namespace Rotor {
bool load(string &graph_filename);
UUID save(); //save to DB, returns UUID of saved graph
bool loaded;
+ float duration;
const string toString();
private:
Node_factory factory;
float framerate;
- float duration;
xmlIO xml;
};
class Audio_thumbnailer: public Base_audio_processor {
diff --git a/rotord/rotord.cpp b/rotord/rotord.cpp
index 734e159..a919a0b 100755
--- a/rotord/rotord.cpp
+++ b/rotord/rotord.cpp
@@ -124,43 +124,6 @@ HTTPRequestHandler* RotorRequestHandlerFactory::createRequestHandler(const HTTPS
os<<request.stream().rdbuf();
body=os.str();
-
- /*
- if (segments.size() == 0) {
- return new RotorRequestHandler(_format);
- }
- else if (segments[0]=="vamp"&&segments.size()>3) {
- // vamp/plugin/filter/filename
- // how do deal with error condition?
-
- //Settings(string _so="",string _filter="",string _id="",string _input="");
- return new AudioAnalyserHandler(vampHost::Settings(segments[1],segments[2],segments[3]));
- //string audioData=runPlugin(string myname, string soname, string id,
- // string output, int outputNo, string wavname,
- // string outfilename, bool useFrames);
- return 0;
- }
- else if (segments[0]=="new") {
- // create a new render context
-
- return 0;
- }
- else {
- return 0;
- }
- */
-
-
- //at this point we are within app
- //making a new contexthandler?
- //how will this have access to the thread that it refers to
- //how will messages be passed
- //we need to do testing etc here and
-
- //what does the handler do?
- //it gets passed the response- gets to set response code
-
-
if (command.size()) {
if (command[0]=="new") {
if (request.getMethod()=="GET") {