Auto* Autos::get_auto_for_editing(double position) { if(position < 0) { position = edl->local_session->get_selectionstart(1); } Auto *result = 0; position = edl->align_to_frame(position, 0); //printf("Autos::get_auto_for_editing %p %p\n", first, default_auto); if(edl->session->auto_keyframes) { result = insert_auto(track->to_units(position, 0)); } else result = get_prev_auto(track->to_units(position, 0), PLAY_FORWARD, result); //printf("Autos::get_auto_for_editing %p %p %p\n", default_auto, first, result); return result; }
Auto* Autos::get_prev_auto(int direction, Auto* ¤t) { double position_double = edl->local_session->get_selectionstart(1); position_double = edl->align_to_frame(position_double, 0); int64_t position = track->to_units(position_double, 0); return get_prev_auto(position, direction, current); return current; }
float FloatAutos::get_value(int64_t position, int direction, FloatAuto* &previous, FloatAuto* &next) { // Calculate bezier equation at position float y0, y1, y2, y3; float t; previous = (FloatAuto*)get_prev_auto(position, direction, (Auto* &)previous, 0); next = (FloatAuto*)get_next_auto(position, direction, (Auto* &)next, 0); // Constant if(!next && !previous) return ((FloatAuto*)default_auto)->value; if(!previous) return next->value; if(!next) return previous->value; if(next == previous) return previous->value; if(direction == PLAY_FORWARD) { if(EQUIV(previous->value, next->value)) { if((previous->mode == Auto::LINEAR && next->mode == Auto::LINEAR) || (EQUIV(previous->control_out_value, 0) && EQUIV(next->control_in_value, 0))) { return previous->value; } } } else if(direction == PLAY_REVERSE) { if(EQUIV(previous->value, next->value)) { if((previous->mode == Auto::LINEAR && next->mode == Auto::LINEAR) || (EQUIV(previous->control_in_value, 0) && EQUIV(next->control_out_value, 0))) { return previous->value; } } } // Interpolate y0 = previous->value; y3 = next->value; if(direction == PLAY_FORWARD) { // division by 0 if(next->position - previous->position == 0) return previous->value; y1 = previous->value + previous->control_out_value * 2; y2 = next->value + next->control_in_value * 2; t = (double)(position - previous->position) / (next->position - previous->position); } else { // division by 0 if(previous->position - next->position == 0) return previous->value; y1 = previous->value + previous->control_in_value * 2; y2 = next->value + next->control_out_value * 2; t = (double)(previous->position - position) / (previous->position - next->position); } float result = 0; if(previous->mode == Auto::LINEAR && next->mode == Auto::LINEAR) { result = previous->value + t * (next->value - previous->value); } else { float tpow2 = t * t; float tpow3 = t * t * t; float invt = 1 - t; float invtpow2 = invt * invt; float invtpow3 = invt * invt * invt; result = ( invtpow3 * y0 + 3 * t * invtpow2 * y1 + 3 * tpow2 * invt * y2 + tpow3 * y3); //printf("FloatAutos::get_value %f %f %d %d %d %d\n", result, t, direction, position, previous->position, next->position); } return result; }