summaryrefslogtreecommitdiff
path: root/rotord
diff options
context:
space:
mode:
Diffstat (limited to 'rotord')
-rw-r--r--rotord/src/rotor.h63
1 files changed, 51 insertions, 12 deletions
diff --git a/rotord/src/rotor.h b/rotord/src/rotor.h
index e087bac..14397e8 100644
--- a/rotord/src/rotor.h
+++ b/rotord/src/rotor.h
@@ -120,6 +120,9 @@ namespace Rotor {
Time_spec lastframe() const{
return Time_spec(time-(1.0f/framerate),framerate,duration);
}
+ Time_spec nextframe() const{
+ return Time_spec(time+(1.0f/framerate),framerate,duration);
+ }
int frame(){
return (int)((time*framerate)+0.5); //rounded to the nearest frame
}
@@ -134,6 +137,9 @@ namespace Rotor {
Frame_spec lastframe() const{
return Frame_spec(time-(1.0f/framerate),framerate,duration,w,h);
}
+ Frame_spec nextframe() const{
+ return Frame_spec(time+(1.0f/framerate),framerate,duration,w,h);
+ }
};
class Colour{
public:
@@ -392,14 +398,14 @@ namespace Rotor {
create_signal_input("Selector","Selector input");
create_attribute("mode","Cycling mode {cut|mix}","Mode","cut",{"cut","mix"});
create_attribute("length_mode","Transition length mode","Length mode","seconds",{"seconds","fraction"});
- create_attribute("time_mode","Time mode","time mode","absolute",{"absolute","relative","stretch"});
+ 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);
title="Video cycler";
description="Cycles through video inputs according to selector signal";
duplicate_inputs=true;
UID="93dd9d76-2d09-11e3-9589-5bbbeea1b304";
segment=0;
- segment_start=0.0f;
+ segment_start=segment_end=0.0f;
lastframe=0;
}
Video_cycler(map<string,string> &settings):Video_cycler() {
@@ -417,9 +423,15 @@ namespace Rotor {
if(thisframe==lastframe||thisframe==lastframe+1){
if (segment!=seg){
//start of new segment
- cerr<<"Video_cycler: segment "<<seg<<" started: "<<((Time_spec)frame).time<<endl;
segment=seg;
segment_start=((Time_spec)frame).time;
+ //find segment end
+ Time_spec testframe=(Time_spec)frame.nextframe();
+ while ((int)inputs[0]->get(testframe)==seg&&testframe.time<frame.duration){
+ testframe=testframe.nextframe();
+ }
+ segment_end=((Time_spec)testframe).time;
+ cerr<<"Video_cycler: segment "<<seg<<" start: "<<segment_start<<" end: "<<segment_end<<endl;
}
}
else {
@@ -430,26 +442,53 @@ namespace Rotor {
else {
//find segment start
Time_spec testframe=(Time_spec)frame.lastframe();
- while ((int)inputs[0]->get(testframe)==seg&&testframe.frame()>0){
+ while ((int)inputs[0]->get(testframe)==seg&&testframe.frame()>1){
testframe=testframe.lastframe();
-
}
segment_start=testframe.time;
segment=seg;
- cerr<<"Video_cycler: segment "<<seg<<" started: "<<((Time_spec)frame).time<<endl;
+
+ testframe=(Time_spec)frame.nextframe();
+ while ((int)inputs[0]->get(testframe)==seg&&testframe.time<frame.duration){
+ testframe=testframe.nextframe();
+ }
+ segment_end=((Time_spec)testframe).time;
+ cerr<<"Video_cycler: segment "<<seg<<" start: "<<segment_start<<" end: "<<segment_end<<endl;
+
}
}
lastframe=thisframe;
- float wanted=(((Time_spec)frame).time-segment_start);
+ float start_time=(((Time_spec)frame).time-segment_start);
+ float end_time=(((Time_spec)frame).time-segment_end);
+
+ Frame_spec inframe=frame;
+ Frame_spec outframe=frame;
+ switch (attributes["time_mode"]->intVal){
+ case CYCLER_abs:
+ inframe=frame;
+ break;
+ case CYCLER_rel:
+ inframe=Frame_spec(start_time,frame.framerate,frame.duration,frame.w,frame.h,frame.audio);
+ outframe=Frame_spec(end_time,frame.framerate,frame.duration,frame.w,frame.h,frame.audio);
+ break;
+ }
+
+ //to x fade between segments in relative mode, need to know the end of the segment as well as the beginning?
+ //or keep an index of segment times?
+
+ //we don't want to mix from this input to the next
+ //we want to mix out the previous segment whose start time was the previous segment (or the end one)
+ //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){
int im1=((int)inputs[0]->get((Time_spec)frame))%image_inputs.size();
int im2=(im1+1)%image_inputs.size();
float f=fmod(inputs[0]->get((Time_spec)frame),1.0f);
- Image *in1=image_inputs[im1]->get(frame);
+ Image *in1=image_inputs[im1]->get(inframe);
if (in1){
- Image *in2=image_inputs[im2]->get(frame);
+ Image *in2=image_inputs[im2]->get(outframe);
if (in2){
image=(*in1);
image*=(1.0f-f);
@@ -465,14 +504,14 @@ namespace Rotor {
//cut mode
for (uint32_t i=0;i<image_inputs.size();i++){
int whichinput=((int)inputs[0]->get((Time_spec)frame)+i)%image_inputs.size();
- Image *in=image_inputs[whichinput]->get(frame);
+ Image *in=image_inputs[whichinput]->get(inframe);
if (in) return in;
}
return nullptr;
}
Video_cycler* clone(map<string,string> &_settings) { return new Video_cycler(_settings);};
private:
- float segment_start;
+ float segment_start,segment_end;
int segment;
int lastframe;
};
@@ -698,7 +737,7 @@ namespace Rotor {
else {
//find segment start
Time_spec testframe=(Time_spec)frame.lastframe();
- while ((int)inputs[0]->get(testframe)==seg&&testframe.frame()>0){
+ while ((int)inputs[0]->get(testframe)==seg&&testframe.frame()>1){
testframe=testframe.lastframe();
}