From dab459d8fcf93c377836bc30a1c4bc5505b79323 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Wed, 23 Mar 2016 09:53:27 -0600 Subject: [PATCH] merge: added speed auto gang/ranges, fix overlayframe norm alpha --- cinelerra-5.1/cinelerra/aautomation.C | 13 +- cinelerra-5.1/cinelerra/amodule.C | 8 +- cinelerra-5.1/cinelerra/automation.C | 5 +- cinelerra-5.1/cinelerra/automation.h | 6 +- cinelerra-5.1/cinelerra/automation.inc | 1 + cinelerra-5.1/cinelerra/localsession.C | 5 + cinelerra-5.1/cinelerra/localsession.h | 5 +- cinelerra-5.1/cinelerra/maskengine.C | 119 +++++++---- cinelerra-5.1/cinelerra/maskengine.h | 32 +-- cinelerra-5.1/cinelerra/mwindowmove.C | 8 + cinelerra-5.1/cinelerra/overlayframe.C | 4 +- cinelerra-5.1/cinelerra/trackcanvas.C | 283 +++++++++++-------------- cinelerra-5.1/cinelerra/vautomation.C | 11 +- cinelerra-5.1/cinelerra/zoombar.C | 19 +- cinelerra-5.1/msg.txt | 12 +- 15 files changed, 270 insertions(+), 261 deletions(-) diff --git a/cinelerra-5.1/cinelerra/aautomation.C b/cinelerra-5.1/cinelerra/aautomation.C index 2e1d07c1..0c167602 100644 --- a/cinelerra-5.1/cinelerra/aautomation.C +++ b/cinelerra-5.1/cinelerra/aautomation.C @@ -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); + } } diff --git a/cinelerra-5.1/cinelerra/amodule.C b/cinelerra-5.1/cinelerra/amodule.C index 479c9204..bd45a39c 100644 --- a/cinelerra-5.1/cinelerra/amodule.C +++ b/cinelerra-5.1/cinelerra/amodule.C @@ -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; diff --git a/cinelerra-5.1/cinelerra/automation.C b/cinelerra-5.1/cinelerra/automation.C index fd2de322..298618af 100644 --- a/cinelerra-5.1/cinelerra/automation.C +++ b/cinelerra-5.1/cinelerra/automation.C @@ -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) diff --git a/cinelerra-5.1/cinelerra/automation.h b/cinelerra-5.1/cinelerra/automation.h index d9b3891c..47df6eca 100644 --- a/cinelerra-5.1/cinelerra/automation.h +++ b/cinelerra-5.1/cinelerra/automation.h @@ -44,10 +44,14 @@ 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; diff --git a/cinelerra-5.1/cinelerra/automation.inc b/cinelerra-5.1/cinelerra/automation.inc index 5f1d16ef..98ba2b00 100644 --- a/cinelerra-5.1/cinelerra/automation.inc +++ b/cinelerra-5.1/cinelerra/automation.inc @@ -68,6 +68,7 @@ enum AUTOGROUPTYPE_AUDIO_FADE, AUTOGROUPTYPE_VIDEO_FADE, AUTOGROUPTYPE_ZOOM, + AUTOGROUPTYPE_SPEED, AUTOGROUPTYPE_X, AUTOGROUPTYPE_Y, AUTOGROUPTYPE_INT255, diff --git a/cinelerra-5.1/cinelerra/localsession.C b/cinelerra-5.1/cinelerra/localsession.C index 56a1f922..c4d672c7 100644 --- a/cinelerra-5.1/cinelerra/localsession.C +++ b/cinelerra-5.1/cinelerra/localsession.C @@ -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; diff --git a/cinelerra-5.1/cinelerra/localsession.h b/cinelerra-5.1/cinelerra/localsession.h index 4399626b..c00f2318 100644 --- a/cinelerra-5.1/cinelerra/localsession.h +++ b/cinelerra-5.1/cinelerra/localsession.h @@ -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; diff --git a/cinelerra-5.1/cinelerra/maskengine.C b/cinelerra-5.1/cinelerra/maskengine.C index a9186daa..9f2861fe 100644 --- a/cinelerra-5.1/cinelerra/maskengine.C +++ b/cinelerra-5.1/cinelerra/maskengine.C @@ -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, diff --git a/cinelerra-5.1/cinelerra/maskengine.h b/cinelerra-5.1/cinelerra/maskengine.h index 340d923c..1b63a764 100644 --- a/cinelerra-5.1/cinelerra/maskengine.h +++ b/cinelerra-5.1/cinelerra/maskengine.h @@ -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; }; diff --git a/cinelerra-5.1/cinelerra/mwindowmove.C b/cinelerra-5.1/cinelerra/mwindowmove.C index b66cf973..62460c51 100644 --- a/cinelerra-5.1/cinelerra/mwindowmove.C +++ b/cinelerra-5.1/cinelerra/mwindowmove.C @@ -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: diff --git a/cinelerra-5.1/cinelerra/overlayframe.C b/cinelerra-5.1/cinelerra/overlayframe.C index c660dbbb..4de38e36 100644 --- a/cinelerra-5.1/cinelerra/overlayframe.C +++ b/cinelerra-5.1/cinelerra/overlayframe.C @@ -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 diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index 28f149f3..016e6aa3 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -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; diff --git a/cinelerra-5.1/cinelerra/vautomation.C b/cinelerra-5.1/cinelerra/vautomation.C index 52e87afb..70df4e74 100644 --- a/cinelerra-5.1/cinelerra/vautomation.C +++ b/cinelerra-5.1/cinelerra/vautomation.C @@ -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); } } diff --git a/cinelerra-5.1/cinelerra/zoombar.C b/cinelerra-5.1/cinelerra/zoombar.C index 7730d918..81a523db 100644 --- a/cinelerra-5.1/cinelerra/zoombar.C +++ b/cinelerra-5.1/cinelerra/zoombar.C @@ -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; } diff --git a/cinelerra-5.1/msg.txt b/cinelerra-5.1/msg.txt index 22ed63f4..f1a0ab3e 100644 --- a/cinelerra-5.1/msg.txt +++ b/cinelerra-5.1/msg.txt @@ -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 -- 2.26.2