merge: added speed auto gang/ranges, fix overlayframe norm alpha
authorGood Guy <good1.2guy@gmail.com>
Wed, 23 Mar 2016 15:53:27 +0000 (09:53 -0600)
committerGood Guy <good1.2guy@gmail.com>
Wed, 23 Mar 2016 15:53:27 +0000 (09:53 -0600)
15 files changed:
cinelerra-5.1/cinelerra/aautomation.C
cinelerra-5.1/cinelerra/amodule.C
cinelerra-5.1/cinelerra/automation.C
cinelerra-5.1/cinelerra/automation.h
cinelerra-5.1/cinelerra/automation.inc
cinelerra-5.1/cinelerra/localsession.C
cinelerra-5.1/cinelerra/localsession.h
cinelerra-5.1/cinelerra/maskengine.C
cinelerra-5.1/cinelerra/maskengine.h
cinelerra-5.1/cinelerra/mwindowmove.C
cinelerra-5.1/cinelerra/overlayframe.C
cinelerra-5.1/cinelerra/trackcanvas.C
cinelerra-5.1/cinelerra/vautomation.C
cinelerra-5.1/cinelerra/zoombar.C
cinelerra-5.1/msg.txt

index 2e1d07c1a3ff4c70d00a7be4f929578a449ede3c..0c167602ffa8f5c21bf1fa4df7011be96c5d6a23 100644 (file)
@@ -45,11 +45,16 @@ void AAutomation::create_objects()
 
        autos[AUTOMATION_FADE] = new FloatAutos(edl, track, 0.0);
        autos[AUTOMATION_FADE]->create_objects();
-       autos[AUTOMATION_FADE]->autoidx = AUTOMATION_FADE;
-       autos[AUTOMATION_FADE]->autogrouptype = AUTOGROUPTYPE_AUDIO_FADE;
+
+       autos[AUTOMATION_SPEED] = new FloatAutos(edl, track, 1.0);
+       autos[AUTOMATION_SPEED]->create_objects();
 
        autos[AUTOMATION_PAN] = new PanAutos(edl, track);
        autos[AUTOMATION_PAN]->create_objects();
-       autos[AUTOMATION_PAN]->autoidx = AUTOMATION_PAN;
-       autos[AUTOMATION_PAN]->autogrouptype = -1;
+
+       for(int i = 0; i < AUTOMATION_TOTAL; i++) {
+               if( !autos[i] ) continue;
+               autos[i]->autoidx = i;
+               autos[i]->autogrouptype = autogrouptype(i, autos[i]->track);
+       }
 }
index 479c9204021597ae22385eeec5d630e6736a3e22..bd45a39ca50af60a8cd6a9c5f8eb5b4c906a3204 100644 (file)
@@ -321,12 +321,8 @@ speed_fragment_len);
                        speed_fragment_len = (int64_t)(max_position - min_position);
                }
 
-printf("AModule::import_samples %d %f %f %f %f\n", 
-__LINE__, 
-min_position, 
-max_position,
-speed_position1,
-speed_position2);
+//printf("AModule::import_samples %d %f %f %f %f\n", 
+// __LINE__, min_position, max_position, speed_position1, speed_position2);
 
 // new start of source to read from file
                start_source = (int64_t)min_position;
index fd2de32255718b163389b2ee930cf71ce82f3ee0..298618af3359bedfe9ec9163d5fc91d4ee599f6b 100644 (file)
@@ -76,9 +76,11 @@ int Automation::autogrouptype(int autoidx, Track *track)
                        break;
                case AUTOMATION_CAMERA_Z:
                case AUTOMATION_PROJECTOR_Z:
-               case AUTOMATION_SPEED:
                        autogrouptype = AUTOGROUPTYPE_ZOOM;
                        break;
+               case AUTOMATION_SPEED:
+                       autogrouptype = AUTOGROUPTYPE_SPEED;
+                       break;
                case AUTOMATION_FADE:
                        if (track->data_type == TRACK_AUDIO)
                                autogrouptype = AUTOGROUPTYPE_AUDIO_FADE;
@@ -100,6 +102,7 @@ void Automation::create_objects()
        autos[AUTOMATION_MUTE]->autogrouptype = AUTOGROUPTYPE_INT255;
        autos[AUTOMATION_SPEED] = new FloatAutos(edl, track, 1.0);
        autos[AUTOMATION_SPEED]->create_objects();
+       autos[AUTOMATION_SPEED]->autogrouptype = AUTOGROUPTYPE_SPEED;
 }
 
 Automation& Automation::operator=(Automation& automation)
index d9b3891c1969fb066a7928991bf754e59012da8f..47df6eca0859b63ee6f2dc2ebc2fcf7504522462 100644 (file)
        if (autogrouptype == AUTOGROUPTYPE_VIDEO_FADE)                  \
                CLAMP(value, 0, 100);                                   \
        if (autogrouptype == AUTOGROUPTYPE_ZOOM && value < 0)           \
-               value = 0;
+               value = 0;                                              \
+       else if (autogrouptype == AUTOGROUPTYPE_SPEED && value < 0.001) \
+               value = 0.001;
 
 #define AUTOMATIONVIEWCLAMPS(value, autogrouptype)                     \
        if (autogrouptype == AUTOGROUPTYPE_ZOOM && value < 0)           \
+               value = 0;                                              \
+       else if (autogrouptype == AUTOGROUPTYPE_SPEED && value < 0)     \
                value = 0;
 
 
index 5f1d16efd5fbba2e46d3be269ece51605716c34f..98ba2b00d2d821ed7e01d72a0537c9f3c98d3f66 100644 (file)
@@ -68,6 +68,7 @@ enum
        AUTOGROUPTYPE_AUDIO_FADE,
        AUTOGROUPTYPE_VIDEO_FADE,
        AUTOGROUPTYPE_ZOOM,
+       AUTOGROUPTYPE_SPEED,
        AUTOGROUPTYPE_X,
        AUTOGROUPTYPE_Y,
        AUTOGROUPTYPE_INT255,
index 56a1f92291d772672108b140392e80f8cb0a2fda..c4d672c7dad537826d83f905a43049ae4ee21b7c 100644 (file)
@@ -34,6 +34,7 @@ static const char *xml_autogrouptypes_titlesmax[] =
        "AUTOGROUPTYPE_AUDIO_FADE_MAX",
        "AUTOGROUPTYPE_VIDEO_FADE_MAX",
        "AUTOGROUPTYPE_ZOOM_MAX",
+       "AUTOGROUPTYPE_SPEED_MAX",
        "AUTOGROUPTYPE_X_MAX",
        "AUTOGROUPTYPE_Y_MAX",
        "AUTOGROUPTYPE_INT255_MAX"
@@ -44,6 +45,7 @@ static const char *xml_autogrouptypes_titlesmin[] =
        "AUTOGROUPTYPE_AUDIO_FADE_MIN",
        "AUTOGROUPTYPE_VIDEO_FADE_MIN",
        "AUTOGROUPTYPE_ZOOM_MIN",
+       "AUTOGROUPTYPE_SPEED_MIN",
        "AUTOGROUPTYPE_X_MIN",
        "AUTOGROUPTYPE_Y_MIN",
        "AUTOGROUPTYPE_INT255_MIN"
@@ -84,6 +86,9 @@ LocalSession::LocalSession(EDL *edl)
        automation_mins[AUTOGROUPTYPE_ZOOM] = 0.001;
        automation_maxs[AUTOGROUPTYPE_ZOOM] = 4;
 
+       automation_mins[AUTOGROUPTYPE_SPEED] = 0.05;
+       automation_maxs[AUTOGROUPTYPE_SPEED] = 3;
+
        automation_mins[AUTOGROUPTYPE_X] = -100;
        automation_maxs[AUTOGROUPTYPE_X] = 100;
 
index 4399626b128c85859785335add5e56d72f29be90..c00f23185f0ab930f98a347a1d9b7bf096cee152 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef LOCALSESSION_H
 #define LOCALSESSION_H
 
+#include "automation.inc"
 #include "bcwindowbase.inc"
 #include "bchash.inc"
 #include "edl.inc"
@@ -100,8 +101,8 @@ public:
        int64_t zoom_track;
 // Vertical automation scale
 
-       float automation_mins[6];
-       float automation_maxs[6];
+       float automation_mins[AUTOGROUPTYPE_COUNT];
+       float automation_maxs[AUTOGROUPTYPE_COUNT];
        int zoombar_showautotype;
 // Default type of float keyframe
        int floatauto_type;
index a9186daa09fefddd61181572d6f28a57c4e509d1..9f2861feae44c6dd580ecfb04dda7a9c5384e217 100644 (file)
@@ -63,60 +63,101 @@ MaskUnit::~MaskUnit()
 
 #define OVERSAMPLE 8
 
+#if 1
+// Bresenham's
+void MaskUnit::draw_line_clamped(VFrame *frame,
+               int x1,int y1, int x2,int y2, unsigned char k)
+{
+       int w = frame->get_w(), h = frame->get_h();
+       unsigned char **rows = (unsigned char**)frame->get_rows();
+       int dx = x2-x1, dy = y2-y1;
+//printf("MaskUnit::draw_line_clamped(%d,%d -> %d,%d, 0x%02x\n", x1,y1, x2,y2, k);
+
+       int ax = 2*abs(dx), ay = 2*abs(dy);
+       if( ax > ay ) {         /* x dominant */
+               if( dx == 0 ) return;
+               if( x1 > x2 ) {
+                       int xx = x2;  x2 = x1;  x1 = xx;
+                       int yy = y2;  y2 = y1;  y1 = yy;
+               }
+               if( x1 >= w || x2 < 0 ) return;
+               if( dx < 0 ) {  dx = -dx;  dy = -dy; }
+               int x = x1,  y = y1, d = dx;
+               int sy = dy < 0 ? -1 : 1;
+               if( x1 < 0 ) {
+                       double py = -(double)dy/dx * x1 + y1 + 0.5;
+                       x = 0;  y = py;
+                       d = (py - y) * ay;
+               }
 
+               for( int y0=-1;;) {
+                       if( x >= w ) return;
+                       if( y != y0 && y >= 0 && y < h ) {
+                               y0 = y;
+                               unsigned char *bp = rows[y] + x;
+                               *bp = *bp == k ? 0 : k;
+                       }
+                       if( x == x2 ) return;
+                       if( d < 0 ) { d += ax;  y += sy; }
+                       d -= ay;  ++x;
+               }
+       }
+       else {                  /* y dominant */
+               if( dy == 0 ) return;
+               if( y1 > y2 ) {
+                       int xx = x2;  x2 = x1;  x1 = xx;
+                       int yy = y2;  y2 = y1;  y1 = yy;
+               }
+               if( y1 >= h || y2 < 0 ) return;
+               if( dy < 0 ) {  dx = -dx;  dy = -dy; }
+               int x = x1, y = y1, d = dy;
+               int sx = dx < 0 ? -1 : 1;
+               if( y1 < 0 ) {
+                       double px = -(double)dx/dy * y1 + x1 + 0.5;
+                       x = px;  y = 0;
+                       d = (px - x) * ax;
+               }
 
+               for(;;) {
+                       if( y >= h ) return;
+                       if( x >= 0 && x < w ) {
+                               unsigned char *bp = rows[y] + x;
+                               *bp = *bp == k ? 0 : k;
+                       }
+                       if( y == y2 ) return;
+                       if( d < 0 ) { d += ay;  x += sx; }
+                       d -= ax;  ++y;
+               }
+       }
+}
 
-
-
-
-
-
-
-
-
-
-
-
+#else
 
 void MaskUnit::draw_line_clamped(VFrame *frame, 
-       int &x1, 
-       int &y1, 
-       int x2, 
-       int y2,
-       unsigned char k)
+       int x1, int y1, int x2, int y2, unsigned char k)
 {
-       int draw_x1;
-       int draw_y1;
-       int draw_x2;
-       int draw_y2;
+       int draw_x1, draw_y1;
+       int draw_x2, draw_y2;
 
-       if(y2 < y1)
-       {
-               draw_x1 = x2;
-               draw_y1 = y2;
-               draw_x2 = x1;
-               draw_y2 = y1;
+       if(y2 < y1) {
+               draw_x1 = x2;  draw_y1 = y2;
+               draw_x2 = x1;  draw_y2 = y1;
        }
-       else
-       {
-               draw_x1 = x1;
-               draw_y1 = y1;
-               draw_x2 = x2;
-               draw_y2 = y2;
+       else {
+               draw_x1 = x1;  draw_y1 = y1;
+               draw_x2 = x2;  draw_y2 = y2;
        }
 
        unsigned char **rows = (unsigned char**)frame->get_rows();
 
-       if(draw_y2 != draw_y1)
-       {
+       if(draw_y2 != draw_y1) {
                float slope = ((float)draw_x2 - draw_x1) / ((float)draw_y2 - draw_y1);
                int w = frame->get_w() - 1;
                int h = frame->get_h();
 
-               for(float y = draw_y1; y < draw_y2; y++)
-               {
-                       if(y >= 0 && y < h)
-                       {
+               for(float y = draw_y1; y < draw_y2; y++) {
+                       if(y >= 0 && y < h) {
                                int x = (int)((y - draw_y1) * slope + draw_x1);
                                int y_i = (int)y;
                                int x_i = CLIP(x, 0, w);
@@ -130,6 +171,8 @@ void MaskUnit::draw_line_clamped(VFrame *frame,
        }
 }
 
+#endif
+
 void MaskUnit::blur_strip(double *val_p, 
        double *val_m, 
        double *dst, 
index 340d923c851db18f546feb9352ef2176e1e340ba..1b63a7648a3a0582e38f209a89e82a62863d3998 100644 (file)
@@ -59,28 +59,16 @@ public:
 
        void process_package(LoadPackage *package);
        void draw_line_clamped(VFrame *frame, 
-               int &x1, 
-               int &y1, 
-               int x2, 
-               int y2, 
-               unsigned char value);
-       void do_feather(VFrame *output,
-               VFrame *input, 
-               double feather, 
-               int start_y, 
-               int end_y, 
-               int start_x, 
-               int end_x);
-       void blur_strip(double *val_p, 
-               double *val_m, 
-               double *dst, 
-               double *src, 
-               int size,
-               int max);
-
-    double n_p[5], n_m[5];
-    double d_p[5], d_m[5];
-    double bd_p[5], bd_m[5];
+               int x1, int y1, int x2, int y2, unsigned char value);
+       void do_feather(VFrame *output, VFrame *input, 
+               double feather, int start_y, int end_y, int start_x, int end_x);
+       void blur_strip(double *val_p, double *val_m, 
+               double *dst, double *src, int size, int max);
+
+       double n_p[5], n_m[5];
+       double d_p[5], d_m[5];
+       double bd_p[5], bd_m[5];
+
        MaskEngine *engine;
        VFrame *temp;
 };
index b66cf973270bad2cbf9c8a5055ebcc2d54354794..62460c516c58c99cae12444aca599d46cc0722bb 100644 (file)
@@ -190,6 +190,12 @@ void MWindow::fit_autos(int doall)
                                max = floor(max*200)/100;
                        }
                        break;
+               case AUTOGROUPTYPE_SPEED:
+                       if (range < 0.001) {
+                               min = floor(min*5)/100;
+                               max = floor(max*300)/100;
+                       }
+                       break;
                case AUTOGROUPTYPE_X:
                case AUTOGROUPTYPE_Y:
                        if (range < 5) {
@@ -233,6 +239,7 @@ void MWindow::change_currentautorange(int autogrouptype, int increment, int chan
                        val += 1;
                        break;
                case AUTOGROUPTYPE_ZOOM:
+               case AUTOGROUPTYPE_SPEED:
                        if (val == 0)
                                val = 0.001;
                        else
@@ -254,6 +261,7 @@ void MWindow::change_currentautorange(int autogrouptype, int increment, int chan
                        val -= 1;
                        break;
                case AUTOGROUPTYPE_ZOOM:
+               case AUTOGROUPTYPE_SPEED:
                        if (val > 0) val = val/2;
                        break;
                case AUTOGROUPTYPE_X:
index c660dbbb745539b86ab930dad1a9bedc76cf9e07..4de38e3670ce12afb261ea8983639e8b5496942f 100644 (file)
@@ -361,8 +361,8 @@ int OverlayFrame::overlay(VFrame *output, VFrame *input,
        return 0;
 }
 
-// NORMAL      [Sa * Sa + Da * (1 - Sa), Sc * Sa + Dc * (1 - Sa)])
-#define ALPHA_NORMAL(mx, Sa, Da) ((Sa * Sa + Da * (mx - Sa)) / mx)
+// NORMAL      [Sa + Da * (1 - Sa), Sc * Sa + Dc * (1 - Sa)])
+#define ALPHA_NORMAL(mx, Sa, Da) (Sa + (Da * (mx - Sa)) / mx)
 #define COLOR_NORMAL(mx, Sc, Sa, Dc, Da) ((Sc * Sa + Dc * (mx - Sa)) / mx)
 #define CHROMA_NORMAL COLOR_NORMAL
 
index 28f149f351ff84f7830e8ed2035e975aa59f5800..016e6aa3b5bff84e127f45e25d46d7443f1bc1fc 100644 (file)
@@ -2014,7 +2014,7 @@ int TrackCanvas::do_keyframes(int cursor_x,
                                        {
                                                if (buttonpress != 3)
                                                {
-                                                       if(i == AUTOMATION_FADE)
+                                                       if(i == AUTOMATION_FADE || i == AUTOMATION_SPEED)
                                                                synchronize_autos(0,
                                                                        track,
                                                                        (FloatAuto*)mwindow->session->drag_auto,
@@ -2311,8 +2311,7 @@ float levered_position(float position, float ref_pos)
 {
        if( 1e-6 > fabs(ref_pos) || isnan(ref_pos)) 
                return 0.0;
-       else 
-               return ref_pos / position;
+       return ref_pos / position;
 }
 
 
@@ -2324,10 +2323,9 @@ float TrackCanvas::value_to_percentage(float auto_value, int autogrouptype)
        float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype];
        float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype];
        float automation_range = automation_max - automation_min;
-       if(0 == automation_range || isnan(auto_value) || isinf(auto_value))
+       if( 0 >= automation_range || isnan(auto_value) || isinf(auto_value) )
                return 0;
-       else
-               return (auto_value - automation_min) / automation_range;
+       return (auto_value - automation_min) / automation_range;
 }
 
 
@@ -2596,71 +2594,62 @@ int TrackCanvas::test_floatline(int center_pixel,
 
 
 void TrackCanvas::synchronize_autos(float change,
-       Track *skip,
-       FloatAuto *fauto,
-       int fill_gangs)
+               Track *skip, FloatAuto *fauto, int fill_gangs)
 {
 // Handles the special case of modifying a fadeauto
 // when there are ganged faders on several tracks
 // (skip and fauto may be NULL if fill_gangs==-1)
-       if (fill_gangs == 1 && skip->gang)
-       {
-               for(Track *current = mwindow->edl->tracks->first;
-                       current;
-                       current = NEXT)
-               {
-                       if(current->data_type == skip->data_type &&
-                               current->gang &&
-                               current->record &&
-                               current != skip)
-                       {
-                               FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
-                               double position = skip->from_units(fauto->position);
-                               FloatAuto *previous = 0, *next = 0;
 
-                               float init_value = fade_autos->get_value(fauto->position, PLAY_FORWARD, previous, next);
-                               FloatAuto *keyframe;
-                               keyframe = (FloatAuto*)fade_autos->get_auto_at_position(position);
-
-                               if (!keyframe)
-                               {
+       if( fill_gangs > 0 && skip->gang ) {
+               double position = skip->from_units(fauto->position);
+               int autoidx = fauto->autos->autoidx;
+
+               for(Track *current = mwindow->edl->tracks->first; current; current = NEXT) {
+                       if( (current->data_type == skip->data_type || get_double_click()) &&
+                           current->gang && current->record && current != skip ) {
+                               int64_t current_position = current->to_units(position, 1);
+                               FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[autoidx];
+                               float auto_min = mwindow->edl->local_session->automation_mins[fade_autos->autogrouptype];
+                               float auto_max = mwindow->edl->local_session->automation_maxs[fade_autos->autogrouptype];
+                               FloatAuto *previous = 0, *next = 0;
+                               FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_at_position(current_position);
+                               if( !keyframe ) {
 // create keyframe on neighbouring track at the point in time given by fauto
-                                       keyframe = (FloatAuto*)fade_autos->insert_auto(fauto->position);
-                                       keyframe->set_value(init_value + change);
+                                       float init_value = fade_autos->get_value(current_position, PLAY_FORWARD, previous, next);
+                                       float new_value = init_value + change;
+                                       CLAMP(new_value, auto_min, auto_max);
+                                       keyframe = (FloatAuto*)fade_autos->insert_auto(current_position);
+                                       keyframe->set_value(new_value);
                                }
-                               else
-                               {
+                               else {
 // keyframe exists, just change it
-                                       keyframe->adjust_to_new_coordinates(fauto->position, keyframe->get_value() + change);
+                                       float new_value = keyframe->get_value() + change;
+                                       CLAMP(new_value, auto_min, auto_max);
+                                       keyframe->adjust_to_new_coordinates(current_position, new_value);
 // need to (re)set the position, as the existing node could be on a "equivalent" position (within half a frame)
                                }
 
                                mwindow->session->drag_auto_gang->append((Auto *)keyframe);
                        }
                }
-       } else
-// move the gangs
-       if (fill_gangs == 0)
-       {
-// Move the gang!
-               for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
-               {
+       }
+       else if( !fill_gangs ) {
+               double position = skip->from_units(fauto->position);
+// Move the gangs
+               for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) {
                        FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
-
+                       int64_t keyframe_position = keyframe->autos->track->to_units(position, 1);
                        float new_value = keyframe->get_value() + change;
                        CLAMP(new_value,
                              mwindow->edl->local_session->automation_mins[keyframe->autos->autogrouptype],
                              mwindow->edl->local_session->automation_maxs[keyframe->autos->autogrouptype]);
-                       keyframe->adjust_to_new_coordinates(fauto->position, new_value);
+                       keyframe->adjust_to_new_coordinates(keyframe_position, new_value);
                }
 
        }
-       else
+       else {
 // remove the gangs
-       if (fill_gangs == -1)
-       {
-               for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++)
-               {
+               for (int i = 0; i < mwindow->session->drag_auto_gang->total; i++) {
                        FloatAuto *keyframe = (FloatAuto *)mwindow->session->drag_auto_gang->values[i];
                        keyframe->autos->remove_nonsequential(
                                        keyframe);
@@ -3485,36 +3474,22 @@ int TrackCanvas::get_drag_values(float *percentage,
 
 
 #define UPDATE_DRAG_HEAD(do_clamp) \
-       int result = 0; \
+       int result = 0, center_pixel; \
        if(!current->autos->track->record) return 0; \
-       double view_start; \
-       double unit_start; \
-       double view_end; \
-       double unit_end; \
-       double yscale; \
-       int center_pixel; \
-       double zoom_sample; \
-       double zoom_units; \
+       double view_start, unit_start, view_end, unit_end; \
+       double yscale, zoom_sample, zoom_units; \
  \
        calculate_viewport(current->autos->track,  \
-               view_start, \
-               unit_start, \
-               view_end, \
-               unit_end, \
-               yscale, \
-               center_pixel, \
-               zoom_sample, \
-               zoom_units); \
+               view_start, unit_start, view_end, unit_end, \
+               yscale, center_pixel, zoom_sample, zoom_units); \
  \
        float percentage = (float)(mwindow->session->drag_origin_y - cursor_y) / \
-               yscale +  \
-               mwindow->session->drag_start_percentage; \
+               yscale +  mwindow->session->drag_start_percentage; \
        if(do_clamp) CLAMP(percentage, 0, 1); \
  \
        int64_t position = Units::to_int64(zoom_units * \
                (cursor_x - mwindow->session->drag_origin_x) + \
                mwindow->session->drag_start_position); \
- \
        if((do_clamp) && position < 0) position = 0;
 
 
@@ -3523,119 +3498,99 @@ int TrackCanvas::update_drag_floatauto(int cursor_x, int cursor_y)
        FloatAuto *current = (FloatAuto*)mwindow->session->drag_auto;
 
        UPDATE_DRAG_HEAD(mwindow->session->drag_handle == 0);
-       int x = cursor_x - mwindow->session->drag_origin_x; \
-       int y = cursor_y - mwindow->session->drag_origin_y; \
-
-       float value;
-       float old_value;
+       int x = cursor_x - mwindow->session->drag_origin_x;
+       int y = cursor_y - mwindow->session->drag_origin_y;
+       float value, old_value;
+
+       if( mwindow->session->drag_handle == 0 && (ctrl_down() && !shift_down()) ) {
+// not really editing the node, rather start editing the curve
+// tangent is editable and drag movement is significant
+               if( (FloatAuto::FREE == current->curve_mode ||
+                    FloatAuto::TFREE==current->curve_mode) &&                                          
+                   (fabs(x) > HANDLE_W / 2 || fabs(y) > HANDLE_W / 2))
+                       mwindow->session->drag_handle = x < 0 ? 1 : 2;
+       }
 
-       switch(mwindow->session->drag_handle)
-       {
-// Center
-               case 0:
-                       if(ctrl_down())
-                       // not really editing the node, rather start editing the curve
-                       {
-                               // tangent is editable and drag movement is significant
-                               if( (FloatAuto::FREE == current->curve_mode ||
-                                    FloatAuto::TFREE==current->curve_mode) &&                                          
-                                   (fabs(x) > HANDLE_W / 2 || fabs(y) > HANDLE_W / 2))
-                                       mwindow->session->drag_handle = x < 0 ? 1 : 2;
-                               break;
-                       }
+       switch(mwindow->session->drag_handle) {
+       case 0: // Center
 // Snap to nearby values
-                       old_value = current->get_value();
-                       if(shift_down())
-                       {
-                               double value1;
-                               double distance1;
-                               double value2;
-                               double distance2;
-
-                               if(current->previous)
-                               {
-                                       int autogrouptype = current->previous->autos->autogrouptype;
-                                       value = percentage_to_value(percentage, 0, 0, autogrouptype);
-                                       value1 = ((FloatAuto*)current->previous)->get_value();
-                                       distance1 = fabs(value - value1);
-                                       current->set_value(value1);
-                               }
+               old_value = current->get_value();
+               if(shift_down()) {
+                       double value1, value2, distance1, distance2;
 
-                               if(current->next)
-                               {
-                                       int autogrouptype = current->next->autos->autogrouptype;
-                                       value = percentage_to_value(percentage, 0, 0, autogrouptype);
-                                       value2 = ((FloatAuto*)current->next)->get_value();
-                                       distance2 = fabs(value - value2);
-                                       if(!current->previous || distance2 < distance1)
-                                       {
-                                               current->set_value(value2);
-                                       }
-                               }
+                       if(current->previous) {
+                               int autogrouptype = current->previous->autos->autogrouptype;
+                               value = percentage_to_value(percentage, 0, 0, autogrouptype);
+                               value1 = ((FloatAuto*)current->previous)->get_value();
+                               distance1 = fabs(value - value1);
+                               current->set_value(value1);
+                       }
 
-                               if(!current->previous && !current->next)
-                               {
-                                       current->set_value( ((FloatAutos*)current->autos)->default_);
+                       if(current->next) {
+                               int autogrouptype = current->next->autos->autogrouptype;
+                               value = percentage_to_value(percentage, 0, 0, autogrouptype);
+                               value2 = ((FloatAuto*)current->next)->get_value();
+                               distance2 = fabs(value - value2);
+                               if(!current->previous || distance2 < distance1) {
+                                       current->set_value(value2);
                                }
-                               value = current->get_value();
                        }
-                       else
-                       {
-                               int autogrouptype = current->autos->autogrouptype;
-                               value = percentage_to_value(percentage, 0, 0, autogrouptype);
+
+                       if(!current->previous && !current->next) {
+                               current->set_value( ((FloatAutos*)current->autos)->default_);
                        }
+                       value = current->get_value();
+               }
+               else {
+                       int autogrouptype = current->autos->autogrouptype;
+                       value = percentage_to_value(percentage, 0, 0, autogrouptype);
+               }
 
-                       if(alt_down())
+               if(alt_down() && !shift_down())
 // ALT constrains movement: fixed position, only changing the value
-                               position = mwindow->session->drag_start_position;
+                       position = mwindow->session->drag_start_position;
 
-                       if(value != old_value || position != current->position)
-                       {
-                               result = 1;
-                               float change = value - old_value;               
-                               current->adjust_to_new_coordinates(position, value);
-                               synchronize_autos(change, current->autos->track, current, 0);
-                               show_message(current, 1,", %.2f", current->get_value());
-                       }
-                       break;
+               if(value != old_value || position != current->position) {
+                       result = 1;
+                       float change = value - old_value;               
+                       current->adjust_to_new_coordinates(position, value);
+                       synchronize_autos(change, current->autos->track, current, 0);
+                       show_message(current, 1,", %.2f", current->get_value());
+               }
+               break;
 
 // In control
-               case 1:
+       case 1: {
+               int autogrouptype = current->autos->autogrouptype;
+               value = percentage_to_value(percentage, 0, current, autogrouptype);
+               if(value != current->get_control_in_value())
                {
-                       int autogrouptype = current->autos->autogrouptype;
-                       value = percentage_to_value(percentage, 0, current, autogrouptype);
-                       if(value != current->get_control_in_value())
-                       {
-                               result = 1;
-                               // note: (position,value) need not be at the location of the ctrl point,
-                               // but could be somewhere in between on the curve (or even outward or
-                               // on the opposit side). We set the new control point such as
-                               // to point the curve through (position,value)
-                               current->set_control_in_value(
-                                       value * levered_position(position - current->position,
-                                                                current->get_control_in_position()));
-                               synchronize_autos(0, current->autos->track, current, 0);
-                               show_message(current, 1,", %.2f", current->get_control_in_value());
-                       }
+                       result = 1;
+                       // note: (position,value) need not be at the location of the ctrl point,
+                       // but could be somewhere in between on the curve (or even outward or
+                       // on the opposit side). We set the new control point such as
+                       // to point the curve through (position,value)
+                       current->set_control_in_value(
+                               value * levered_position(position - current->position,
+                                                        current->get_control_in_position()));
+                       synchronize_autos(0, current->autos->track, current, 0);
+                       show_message(current, 1,", %.2f", current->get_control_in_value());
                }
-                       break;
+               break; }
 
 // Out control
-               case 2:
-               {
-                       int autogrouptype = current->autos->autogrouptype;
-                       value = percentage_to_value(percentage, 0, current, autogrouptype);
-                       if(value != current->get_control_out_value())
-                       {
-                               result = 1;
-                               current->set_control_out_value(
-                                       value * levered_position(position - current->position,
-                                                                current->get_control_out_position()));
-                               synchronize_autos(0, current->autos->track, current, 0);
-                               show_message(current, 1,", %.2f", current->get_control_out_value());
-                       }
+       case 2: {
+               int autogrouptype = current->autos->autogrouptype;
+               value = percentage_to_value(percentage, 0, current, autogrouptype);
+               if(value != current->get_control_out_value()) {
+                       result = 1;
+                       current->set_control_out_value(
+                               value * levered_position(position - current->position,
+                                                        current->get_control_out_position()));
+                       synchronize_autos(0, current->autos->track, current, 0);
+                       show_message(current, 1,", %.2f", current->get_control_out_value());
                }
-                       break;
+               break; }
        }
 
        return result;
index 52e87afb28274b545bea0ff2e003f1437ad2c198..70df4e741a6d449dc0edd0bf092a952315545cab 100644 (file)
@@ -52,6 +52,9 @@ void VAutomation::create_objects()
        autos[AUTOMATION_FADE] = new FloatAutos(edl, track, 100);
        autos[AUTOMATION_FADE]->create_objects();
 
+       autos[AUTOMATION_SPEED] = new FloatAutos(edl, track, 1.);
+       autos[AUTOMATION_SPEED]->create_objects();
+
        autos[AUTOMATION_MODE] = new IntAutos(edl, track, TRANSFER_NORMAL);
        autos[AUTOMATION_MODE]->create_objects();
 
@@ -76,11 +79,9 @@ void VAutomation::create_objects()
        autos[AUTOMATION_PROJECTOR_Z] = new FloatAutos(edl, track, 1.0);
        autos[AUTOMATION_PROJECTOR_Z]->create_objects();
        for(int i = 0; i < AUTOMATION_TOTAL; i++) {
-               if (autos[i])
-               {
-                       autos[i]->autoidx = i;
-                       autos[i]->autogrouptype = autogrouptype(i, autos[i]->track);
-               }
+               if( !autos[i] ) continue;
+               autos[i]->autoidx = i;
+               autos[i]->autogrouptype = autogrouptype(i, autos[i]->track);
        }
 }
 
index 7730d918bc675df3403a1bfcc917bbdad55c95cd..81a523dbdbd1706560fb75e10ecce1aea921c3d5 100644 (file)
@@ -179,6 +179,7 @@ void ZoomBar::update_autozoom()
                        mwindow->edl->local_session->automation_maxs[mwindow->edl->local_session->zoombar_showautotype]);
                break;
        case AUTOGROUPTYPE_ZOOM:
+       case AUTOGROUPTYPE_SPEED:
                sprintf(string, "%0.03f to %0.03f\n", 
                        mwindow->edl->local_session->automation_mins[mwindow->edl->local_session->zoombar_showautotype],
                        mwindow->edl->local_session->automation_maxs[mwindow->edl->local_session->zoombar_showautotype]);
@@ -460,6 +461,7 @@ void AutoTypeMenu::create_objects()
        add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_AUDIO_FADE)));
        add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_VIDEO_FADE)));
        add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_ZOOM)));
+       add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_SPEED)));
        add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_X)));
        add_item(new BC_MenuItem(to_text(AUTOGROUPTYPE_Y)));
 }
@@ -470,6 +472,7 @@ const char* AutoTypeMenu::to_text(int mode)
        case AUTOGROUPTYPE_AUDIO_FADE: return _("Audio Fade:");
        case AUTOGROUPTYPE_VIDEO_FADE: return _("Video Fade:");
        case AUTOGROUPTYPE_ZOOM: return _("Zoom:");
+       case AUTOGROUPTYPE_SPEED: return _("Speed:");
        case AUTOGROUPTYPE_X: return "X:";
        case AUTOGROUPTYPE_Y: return "Y:";
        }
@@ -478,16 +481,12 @@ const char* AutoTypeMenu::to_text(int mode)
 
 int AutoTypeMenu::from_text(char *text)
 {
-       if(!strcmp(text, to_text(AUTOGROUPTYPE_AUDIO_FADE)))
-               return AUTOGROUPTYPE_AUDIO_FADE;
-       if(!strcmp(text, to_text(AUTOGROUPTYPE_VIDEO_FADE)))
-               return AUTOGROUPTYPE_VIDEO_FADE;
-       if(!strcmp(text, to_text(AUTOGROUPTYPE_ZOOM)))
-               return AUTOGROUPTYPE_ZOOM;
-       if(!strcmp(text, to_text(AUTOGROUPTYPE_X)))
-               return AUTOGROUPTYPE_X;
-       if(!strcmp(text, to_text(AUTOGROUPTYPE_Y)))
-               return AUTOGROUPTYPE_Y;
+       if(!strcmp(text, to_text(AUTOGROUPTYPE_AUDIO_FADE))) return AUTOGROUPTYPE_AUDIO_FADE;
+       if(!strcmp(text, to_text(AUTOGROUPTYPE_VIDEO_FADE))) return AUTOGROUPTYPE_VIDEO_FADE;
+       if(!strcmp(text, to_text(AUTOGROUPTYPE_ZOOM))) return AUTOGROUPTYPE_ZOOM;
+       if(!strcmp(text, to_text(AUTOGROUPTYPE_SPEED))) return AUTOGROUPTYPE_SPEED;
+       if(!strcmp(text, to_text(AUTOGROUPTYPE_X))) return AUTOGROUPTYPE_X;
+       if(!strcmp(text, to_text(AUTOGROUPTYPE_Y))) return AUTOGROUPTYPE_Y;
        return AUTOGROUPTYPE_INT255;
 }
 
index 22ed63f4fd5bb46c953f5a9195ef0b221c4c27c0..f1a0ab3e8d640a4150bdb39f478cd1236ab0a63c 100644 (file)
@@ -1,6 +1,6 @@
-email cinelerra@cinelerra-cv.org for bugs or help 
-check the manual https://cinelerra-cv.org/docs/cinelerra_cv_manual_en.html 
-testers are welcome to report and supply examples; join at cinelerra-cv.org
-if logged in as root, can capture crashes and email /tmp/cin*.dmp file 
-volunteer to help with language translations which will help you
-helpful videos: http://beccatoria.dreamwidth.org/144288.html#cutid2
+Email cinelerra@lists.cinelerra-cv.org for bugs or help 
+Check the manual https://cinelerra-cv.org/docs/cinelerra_cv_manual_en.html 
+Testers are welcome to report and supply examples; join at cinelerra-cv.org
+If logged in as root, can capture crashes and email /tmp/cin*.dmp file 
+Volunteer to help with language translations which will help you
+Helpful videos: http://beccatoria.dreamwidth.org/144288.html#cutid2