X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ffloatautos.C;h=04741afe145fabd6fdefc63b31daab1c641f7bb4;hb=5e3715ec449272335bab3419bf21ed4cd6d4bcbf;hp=41001e8e3e104521eb64a533abdbc9a40b50821c;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/cinelerra/floatautos.C b/cinelerra-5.1/cinelerra/floatautos.C index 41001e8e..04741afe 100644 --- a/cinelerra-5.1/cinelerra/floatautos.C +++ b/cinelerra-5.1/cinelerra/floatautos.C @@ -2,21 +2,21 @@ /* * CINELERRA * Copyright (C) 2008 Adam Williams - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * */ #include "automation.inc" @@ -31,7 +31,7 @@ #include "transportque.inc" FloatAutos::FloatAutos(EDL *edl, - Track *track, + Track *track, float default_) : Autos(edl, track) { @@ -48,7 +48,7 @@ void FloatAutos::set_automation_mode(int64_t start, int64_t end, int mode) FloatAuto *current = (FloatAuto*)first; while(current) { -// Is current auto in range? +// Is current auto in range? if(current->position >= start && current->position < end) { current->change_curve_mode((FloatAuto::t_mode)mode); @@ -77,8 +77,8 @@ int FloatAutos::get_testy(float slope, int cursor_x, int ax, int ay) return (int)(slope * (cursor_x - ax)) + ay; } -int FloatAutos::automation_is_constant(int64_t start, - int64_t length, +int FloatAutos::automation_is_constant(int64_t start, + int64_t length, int direction, double &constant) { @@ -133,7 +133,7 @@ int FloatAutos::automation_is_constant(int64_t start, // keyframes before and after region but not in region if(prev_position >= 0 && - prev_position < start && + prev_position < start && current->position >= end) { // Get value now in case change doesn't occur @@ -144,7 +144,7 @@ int FloatAutos::automation_is_constant(int64_t start, // Keyframe occurs in the region if(!test_previous_current && - current->position < end && + current->position < end && current->position >= start) { @@ -186,13 +186,13 @@ int FloatAutos::automation_is_constant(int64_t start, !EQUIV(float_current->get_control_in_value(), 0) || !EQUIV(float_previous->get_control_out_value(), 0)) { -// printf("FloatAutos::automation_is_constant %d %d %d %f %f %f %f\n", -// start, -// float_previous->position, -// float_current->position, -// float_previous->get_value(), -// float_current->get_value(), -// float_previous->get_control_out_value(), +// printf("FloatAutos::automation_is_constant %d %d %d %f %f %f %f\n", +// start, +// float_previous->position, +// float_current->position, +// float_previous->get_value(), +// float_current->get_value(), +// float_previous->get_control_out_value(), // float_current->get_control_in_value()); return 0; } @@ -206,8 +206,8 @@ int FloatAutos::automation_is_constant(int64_t start, double FloatAutos::get_automation_constant(int64_t start, int64_t end) { Auto *current_auto, *before = 0, *after = 0; - -// quickly get autos just outside range + +// quickly get autos just outside range get_neighbors(start, end, &before, &after); // no auto before range so use first @@ -223,9 +223,9 @@ double FloatAutos::get_automation_constant(int64_t start, int64_t end) } -float FloatAutos::get_value(int64_t position, - int direction, - FloatAuto* &previous, +float FloatAutos::get_value(int64_t position, + int direction, + FloatAuto* &previous, FloatAuto* &next) { // Calculate bezier equation at position @@ -275,7 +275,7 @@ float FloatAutos::calculate_bezier(FloatAuto *previous, FloatAuto *next, int64_t // control points float y1 = previous->get_value() + previous->get_control_out_value(); float y2 = next->get_value() + next->get_control_in_value(); - float t = (float)(position - previous->position) / + float t = (float)(position - previous->position) / (next->position - previous->position); float tpow2 = t * t; @@ -283,10 +283,10 @@ float FloatAutos::calculate_bezier(FloatAuto *previous, FloatAuto *next, int64_t float invt = 1 - t; float invtpow2 = invt * invt; float invtpow3 = invt * invt * invt; - + float result = ( invtpow3 * y0 + 3 * t * invtpow2 * y1 - + 3 * tpow2 * invt * y2 + + 3 * tpow2 * invt * y2 + tpow3 * y3); //printf("FloatAutos::get_value(t=%5.3f)->%6.2f (prev,pos,next)=(%d,%d,%d)\n", t, result, previous->position, position, next->position); @@ -306,30 +306,30 @@ float FloatAutos::calculate_bezier_derivation(FloatAuto *previous, FloatAuto *ne } float y0 = previous->get_value(); float y3 = next->get_value(); - + // control points float y1 = previous->get_value() + previous->get_control_out_value(); float y2 = next->get_value() + next->get_control_in_value(); -// normalized scale - float t = (float)(position - previous->position) / scale; - +// normalized scale + float t = (float)(position - previous->position) / scale; + float tpow2 = t * t; float invt = 1 - t; float invtpow2 = invt * invt; - + float slope = 3 * ( - invtpow2 * y0 - invt * ( 2*t - invt ) * y1 - + t * ( 2*invt - t ) * y2 + + t * ( 2*invt - t ) * y2 + tpow2 * y3 ); - + return slope / scale; } -void FloatAutos::get_extents(float *min, +void FloatAutos::get_extents(float *min, float *max, int *coords_undefined, int64_t unit_start, @@ -371,7 +371,7 @@ void FloatAutos::get_extents(float *min, *min = *max = current->get_value(); *coords_undefined = 0; } - + *min = MIN(current->get_value(), *min); *min = MIN(current->get_value() + current->get_control_in_value(), *min); *min = MIN(current->get_value() + current->get_control_out_value(), *min); @@ -387,12 +387,12 @@ void FloatAutos::get_extents(float *min, FloatAuto *next = 0; int64_t unit_step = edl->local_session->zoom_sample; if(track->data_type == TRACK_VIDEO) - unit_step = (int64_t)(unit_step * - edl->session->frame_rate / + unit_step = (int64_t)(unit_step * + edl->session->frame_rate / edl->session->sample_rate); unit_step = MAX(unit_step, 1); - for(int64_t position = unit_start; - position < unit_end; + for(int64_t position = unit_start; + position < unit_end; position += unit_step) { float value = get_value(position,PLAY_FORWARD,prev,next); @@ -405,22 +405,89 @@ void FloatAutos::get_extents(float *min, { *min = MIN(value, *min); *max = MAX(value, *max); - } + } + } +} + +void FloatAutos::set_proxy(int orig_scale, int new_scale) +{ + float orig_value; + orig_value = ((FloatAuto*)default_auto)->value * orig_scale; + ((FloatAuto*)default_auto)->value = orig_value / new_scale; + + for( FloatAuto *current= (FloatAuto*)first; current; current=(FloatAuto*)NEXT ) { + orig_value = current->value * orig_scale; + current->value = orig_value / new_scale; + orig_value = current->control_in_value * orig_scale; + current->control_in_value = orig_value / new_scale; + orig_value = current->control_out_value * orig_scale; + current->control_out_value = orig_value / new_scale; } } void FloatAutos::dump() { printf(" FloatAutos::dump %p\n", this); - printf(" Default: position %jd value=%f\n", + printf(" Default: position %jd value=%f\n", default_auto->position, ((FloatAuto*)default_auto)->get_value()); for(Auto* current = first; current; current = NEXT) { - printf(" position %jd value=%7.3f invalue=%7.3f outvalue=%7.3f %s\n", - current->position, + printf(" position %jd value=%7.3f invalue=%7.3f outvalue=%7.3f %s\n", + current->position, ((FloatAuto*)current)->get_value(), ((FloatAuto*)current)->get_control_in_value(), ((FloatAuto*)current)->get_control_out_value(), FloatAuto::curve_name(((FloatAuto*)current)->curve_mode)); } } + +double FloatAutos::automation_integral(int64_t start, int64_t length, int direction) +{ + if( direction == PLAY_REVERSE ) + start -= length; + if( start < 0 ) { + length += start; + start = 0; + } + int64_t end = start + length; + double value = 0, track_length = track->get_length(); + int64_t pos = start, len = track->to_units(track_length,0); + if( end > len ) end = len; + while( pos < end ) { + int64_t prev_pos = 0, next_pos = len; + Auto *zprev = 0, *znext = 0; + FloatAuto *prev = (FloatAuto*)get_prev_auto(pos, direction, zprev, 0); + if( prev ) prev_pos = prev->position; + FloatAuto *next = (FloatAuto*)get_next_auto(pos, direction, znext, 0); + if( next ) next_pos = next->position; + if( !prev && !next ) prev = next = (FloatAuto*)default_auto; + else if( !prev ) prev = next; + else if( !next ) next = prev; + + double dt = next_pos - prev_pos; + double t0 = (pos - prev_pos) / dt; + if( (pos = next_pos) > end ) pos = end; + double t1 = (pos - prev_pos) / dt; + + double y0 = prev->get_value(), y1 = y0 + prev->get_control_out_value(); + double y3 = next->get_value(), y2 = y3 + next->get_control_in_value(); + if( y0 != y1 || y1 != y2 || y2 != y3 ) { +// bezier definite integral t0..t1 + double f4 = -y0/4 + 3*y1/4 - 3*y2/4 + y3/4; + double f3 = y0 - 2*y1 + y2; + double f2 = -3*y0/2 + 3*y1/2; + double f1 = y0, t = t0; + double t2 = t*t, t3 = t2*t, t4 = t3*t; + t0 = t4*f4 + t3*f3 + t2*f2 + t*f1; + t = t1; t2 = t*t; t3 = t2*t; t4 = t3*t; + t1 = t4*f4 + t3*f3 + t2*f2 + t*f1; + } + else { + t0 *= y0; t1 *= y0; + } + value += dt * (t1 - t0); + } + + return value + 1e-6; +} +