diff options
Diffstat (limited to 'rotord/src')
| -rw-r--r-- | rotord/src/graph.cpp | 2 | ||||
| -rw-r--r-- | rotord/src/nodes_drawing.h | 19 | ||||
| -rwxr-xr-x | rotord/src/rotor.cpp | 67 | ||||
| -rwxr-xr-x | rotord/src/rotor.h | 27 |
4 files changed, 87 insertions, 28 deletions
diff --git a/rotord/src/graph.cpp b/rotord/src/graph.cpp index 3aa2925..026325f 100644 --- a/rotord/src/graph.cpp +++ b/rotord/src/graph.cpp @@ -151,7 +151,7 @@ bool Graph::parseXml(string media_path){ } else cerr << "Rotor: linked parameter input " << i4 << " of node '" << nodeID << "' to node '" << fromID << "'" << endl; } - else cerr << "Rotor: linking parameter input " << i4 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl; + else if (fromID!="") cerr << "Rotor: linking parameter input " << i4 << " of node: '" << nodeID << "', cannot find target '" << fromID << "'" << endl; } else cerr << "Rotor: cannot find parameter input '" << parameter << "' of "<<nodetype<<" "<< nodeID << endl; } diff --git a/rotord/src/nodes_drawing.h b/rotord/src/nodes_drawing.h index 91771f8..d6b7abe 100644 --- a/rotord/src/nodes_drawing.h +++ b/rotord/src/nodes_drawing.h @@ -113,6 +113,25 @@ namespace Rotor { private: Colour colour; }; + class Waves: public Draw_node { + public: + Waves(){ + title="Waves"; + description="Draws audio waveforms"; + } + Waves(map<string,string> &settings):Waves() { + base_settings(settings); + }; + ~Waves(){}; + Waves* clone(map<string,string> &_settings) { return new Waves(_settings);}; + void vector_output(cairo_t * cr,const Frame_spec &frame){ + if (frame.audio){ + + } + else cerr<<"error: visualisation audio not found"<<endl; + } + private: + }; } #endif diff --git a/rotord/src/rotor.cpp b/rotord/src/rotor.cpp index 90f60a9..6e0c790 100755 --- a/rotord/src/rotor.cpp +++ b/rotord/src/rotor.cpp @@ -34,6 +34,7 @@ Node_factory::Node_factory(){ //nodes_drawing.h add_type("shape",new Shape()); add_type("hello",new Hello_draw()); + add_type("waves",new Waves()); //nodes_filters.h add_type("blur",new Blur()); add_type("luma_levels",new Luma_levels()); @@ -212,28 +213,53 @@ bool Video_output::render(const float duration, const float framerate,const stri gettimeofday(&start, NULL); + uint16_t *audioframe; + int samples_in_frame; + if (usingaudio){ - //does audioloader output interleaved samples? - int samples_in_frame=(audioloader.codecContext->channels*audioloader.codecContext->sample_rate)/framerate; + //does audioloader output interleaved samples? + samples_in_frame=(audioloader.codecContext->sample_rate)/framerate; string whether=usingaudio?"Loading":"Cannot load"; logger.information(whether+" audio file: "+audio_filename+", each frame contains "+ofToString(samples_in_frame)+" samples at "+ofToString(audioloader.codecContext->sample_rate)+" hz"); - uint16_t *audioframe; + audioframe=new uint16_t[(samples_in_frame+exporter.get_audio_framesize())*audioloader.codecContext->channels]; } float vstep=1.0f/framerate; float v=0.0f; float vf=0.0f; float af=0.0f; + int aoffs=0; + int audioend=0; while (vf<duration){ //-vstep) { + uint16_t *audio=nullptr; if (usingaudio) { - while (!fless(af,vf)) { - //insert audio frames until we are ahead of the video - //instead: get full amount of samples for frame + uint16_t *audio=audioloader.get_samples(samples_in_frame); + if (aoffs>0){ + //shift down samples + int s=0; + while ((s+aoffs)<audioend) { + for (int j=0;j<audioloader.codecContext->channels;j++){ + audioframe[s*audioloader.codecContext->channels+j]=audioframe[(s+aoffs)*audioloader.codecContext->channels+j]; + } + s++; + } + aoffs=s; + } + for (int i=0;i<samples_in_frame;i++){ + for (int j=0;j<audioloader.codecContext->channels;j++){ + audioframe[(aoffs+i)*audioloader.codecContext->channels+j]=audio[i*audioloader.codecContext->channels+j]; + } + } + audioend=aoffs+samples_in_frame; + aoffs=0; + //while (fless(vf+vstep,af+exporter.get_audio_step())) { + while (aoffs+exporter.get_audio_framesize()<audioend) { + //insert audio frames until we are only 1 audio frame behind the next video frame //send audio_framesize() of them through until buffer is used //pass full buffer within frame_spec for av nodes - - exporter.encodeFrame(audioloader.get_samples(exporter.get_audio_framesize())); + exporter.encodeFrame(audioframe+(aoffs*audioloader.codecContext->channels)); af+=exporter.get_audio_step(); + aoffs+=exporter.get_audio_framesize(); } } @@ -246,9 +272,12 @@ bool Video_output::render(const float duration, const float framerate,const stri //[libx264 @ 0x7fffe8003940] 264 - core 123 r2189 35cf912 - H.264/MPEG-4 AVC codec - Copyleft 2003-2012 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=10 keyint_min=1 scenecut=40 intra_refresh=0 rc_lookahead=10 rc=abr mbtree=1 bitrate=400 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 //Assertion ff_avcodec_locked failed at libavcodec/utils.c:2967 - //cerr<<"videoloader: "<<vf<<" seconds, vstep "<<vstep<<" ,asking for frame "<<((int)((vf*framerate)+0.5))<<endl; - - Image* i=get_output(Frame_spec(vf,framerate,duration,outW,outH)); + //cerr<<"videoloader: "<<vf<<" seconds, vstep "<<vstep<<" ,asking for frame "<<((int)((vf*framerate)+0.5))<<endl + Image* i; + if (usingaudio) { + i=get_output(Frame_spec(vf,framerate,duration,outW,outH,&Audio_frame(audio,audioloader.codecContext->channels,samples_in_frame))); + } + else i=get_output(Frame_spec(vf,framerate,duration,outW,outH)); if (i) { exporter.encodeFrame(i->RGBdata); @@ -264,11 +293,11 @@ bool Video_output::render(const float duration, const float framerate,const stri float mtime = ((end.tv_sec-start.tv_sec) + (end.tv_usec-start.tv_usec)/1000000.0) + 0.5; logger.information("Video_output: rendered "+output_filename+": in "+ofToString(mtime)+" seconds"); - + if (usingaudio) { audioloader.close(); - //delete[] audioframe; - } + delete[] audioframe; + } @@ -296,15 +325,15 @@ bool Video_loader::load(const string &_filename){ +", channels:"+ofToString(player.getNumberOfChannels())); return true; } - + logger.error("Video_loader failed to load "+_filename); - + return false; } Image* Video_loader::output(const Frame_spec &frame){ if (isLoaded){ - //this approach is running into the inability to seek when requesting playback speed > 1. + //this approach is running into the inability to seek when requesting playback speed > 1. //need to cache frames so as to avoid asking for a frame other than the next one. //need an algorithm to find the previous keyframe and seek forward @@ -324,7 +353,7 @@ Image* Video_loader::output(const Frame_spec &frame){ if (!player.fetchFrame(frame.w,frame.h,wanted)) { //seek fail Logger& logger = Logger::get("Rotor"); logger.error("Video_loader failed to seek frame "+ofToString(wanted)+" of "+attributes["filename"]->value); - + if (image.w>0) return ℑ //just return the previous frame if possible else return nullptr; } @@ -334,4 +363,4 @@ Image* Video_loader::output(const Frame_spec &frame){ return ℑ } return nullptr; -};
\ No newline at end of file +}; diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h index fc557cd..84a42e3 100755 --- a/rotord/src/rotor.h +++ b/rotord/src/rotor.h @@ -28,13 +28,24 @@ namespace Rotor { class Image_node; class Parameter; + class Audio_frame{ + public: + Audio_frame(uint16_t *_samples,int _channels,int _numsamples){ + samples=_samples; + channels=_channels; + numsamples=_numsamples; + } + uint16_t *samples; + int channels,numsamples; + }; class Time_spec{ public: Time_spec(){}; - Time_spec(float _time,float _framerate,float _duration){ time=_time; framerate=_framerate; duration=_duration;}; + Time_spec(float _time,float _framerate,float _duration,Audio_frame *_audio=nullptr){ time=_time; framerate=_framerate; duration=_duration; audio=_audio;}; float time; //num/denom ? float framerate; float duration; + Audio_frame *audio; Time_spec lastframe() const{ return Time_spec(time-(1.0f/framerate),framerate,duration); } @@ -44,10 +55,10 @@ namespace Rotor { }; class Frame_spec: public Time_spec{ public: - Frame_spec(float _time,float _framerate,float _duration,int _w,int _h) - { time=_time; framerate=_framerate; duration=_duration; w=_w; h=_h;}; - Frame_spec(int _frame,float _framerate,float _duration,int _w,int _h) - { time=((float)_frame)/_framerate; framerate=_framerate; duration=_duration; w=_w; h=_h;}; + Frame_spec(float _time,float _framerate,float _duration,int _w,int _h,Audio_frame *_audio=nullptr) + { time=_time; framerate=_framerate; duration=_duration; w=_w; h=_h;audio=_audio;}; + Frame_spec(int _frame,float _framerate,float _duration,int _w,int _h,Audio_frame *_audio=nullptr) + { time=((float)_frame)/_framerate; framerate=_framerate; duration=_duration; w=_w; h=_h;audio=_audio;}; int h,w; Frame_spec lastframe(){ return Frame_spec(time-(1.0f/framerate),framerate,duration,w,h); @@ -381,14 +392,14 @@ namespace Rotor { public: Signal_colour(){ create_signal_input("Selector","Selector input"); - create_attribute("colours","palette list of web colours","Colours","000000"); + create_attribute("palette","palette list of web colours","Colour palette","000000"); title="Signal colour"; description="Cycles through a palette of background colours according to selector signal"; }; Signal_colour(map<string,string> &settings):Signal_colour() { base_settings(settings); - for (int i=0;i<attributes["colours"]->value.size()/6;i++){ - palette.push_back(Colour(attributes["colours"]->value.substr(i*6,6))); + for (int i=0;i<attributes["palette"]->value.size()/6;i++){ + palette.push_back(Colour(attributes["palette"]->value.substr(i*6,6))); } prevcol=-1; }; |
