1 #include "automation.inc"
4 #include "edlsession.h"
7 #include "floatautos.h"
9 #include "localsession.h"
10 #include "transportque.inc"
12 FloatAutos::FloatAutos(EDL *edl,
17 this->default_ = default_;
18 type = AUTOMATION_TYPE_FLOAT;
21 FloatAutos::~FloatAutos()
25 int FloatAutos::draw_joining_line(BC_SubWindow *canvas, int vertical, int center_pixel, int x1, int y1, int x2, int y2)
28 canvas->draw_line(center_pixel - y1, x1, center_pixel - y2, x2);
30 canvas->draw_line(x1, center_pixel + y1, x2, center_pixel + y2);
33 Auto* FloatAutos::add_auto(int64_t position, float value)
35 FloatAuto* current = (FloatAuto*)autoof(position);
38 insert_before(current, result = (FloatAuto*)new_auto());
40 result->position = position;
41 result->value = value;
46 Auto* FloatAutos::new_auto()
48 FloatAuto *result = new FloatAuto(edl, this);
49 result->value = default_;
53 int FloatAutos::get_testy(float slope, int cursor_x, int ax, int ay)
55 return (int)(slope * (cursor_x - ax)) + ay;
58 int FloatAutos::automation_is_constant(int64_t start,
63 int total_autos = total();
65 if(direction == PLAY_FORWARD)
76 // No keyframes on track
79 constant = ((FloatAuto*)default_auto)->value;
83 // Only one keyframe on track.
86 constant = ((FloatAuto*)first)->value;
90 // Last keyframe is before region
91 if(last->position <= start)
93 constant = ((FloatAuto*)last)->value;
97 // First keyframe is after region
98 if(first->position > end)
100 constant = ((FloatAuto*)first)->value;
105 int64_t prev_position = -1;
106 for(Auto *current = first; current; current = NEXT)
108 int test_current_next = 0;
109 int test_previous_current = 0;
110 FloatAuto *float_current = (FloatAuto*)current;
112 // keyframes before and after region but not in region
113 if(prev_position >= 0 &&
114 prev_position < start &&
115 current->position >= end)
117 // Get value now in case change doesn't occur
118 constant = float_current->value;
119 test_previous_current = 1;
121 prev_position = current->position;
123 // Keyframe occurs in the region
124 if(!test_previous_current &&
125 current->position < end &&
126 current->position >= start)
129 // Get value now in case change doesn't occur
130 constant = float_current->value;
132 // Keyframe has neighbor
133 if(current->previous)
135 test_previous_current = 1;
140 test_current_next = 1;
144 if(test_current_next)
146 //printf("FloatAutos::automation_is_constant 1 %d\n", start);
147 FloatAuto *float_next = (FloatAuto*)current->next;
149 // Change occurs between keyframes
150 if(!EQUIV(float_current->value, float_next->value) ||
151 !EQUIV(float_current->control_out_value, 0) ||
152 !EQUIV(float_next->control_in_value, 0))
158 if(test_previous_current)
160 FloatAuto *float_previous = (FloatAuto*)current->previous;
162 // Change occurs between keyframes
163 if(!EQUIV(float_current->value, float_previous->value) ||
164 !EQUIV(float_current->control_in_value, 0) ||
165 !EQUIV(float_previous->control_out_value, 0))
167 // printf("FloatAutos::automation_is_constant %d %d %d %f %f %f %f\n",
169 // float_previous->position,
170 // float_current->position,
171 // float_previous->value,
172 // float_current->value,
173 // float_previous->control_out_value,
174 // float_current->control_in_value);
180 // Got nothing that changes in the region.
184 double FloatAutos::get_automation_constant(int64_t start, int64_t end)
186 Auto *current_auto, *before = 0, *after = 0;
188 // quickly get autos just outside range
189 get_neighbors(start, end, &before, &after);
191 // no auto before range so use first
193 current_auto = before;
195 current_auto = first;
197 // no autos at all so use default value
198 if(!current_auto) current_auto = default_auto;
200 return ((FloatAuto*)current_auto)->value;
204 float FloatAutos::get_value(int64_t position,
206 FloatAuto* &previous,
212 // Calculate bezier equation at position
213 float y0, y1, y2, y3;
216 previous = (FloatAuto*)get_prev_auto(position, direction, (Auto* &)previous, 0);
217 next = (FloatAuto*)get_next_auto(position, direction, (Auto* &)next, 0);
220 if(!next && !previous)
222 return ((FloatAuto*)default_auto)->value;
232 return previous->value;
237 return previous->value;
241 if(direction == PLAY_FORWARD &&
242 EQUIV(previous->value, next->value) &&
243 EQUIV(previous->control_out_value, 0) &&
244 EQUIV(next->control_in_value, 0))
246 return previous->value;
249 if(direction == PLAY_REVERSE &&
250 EQUIV(previous->value, next->value) &&
251 EQUIV(previous->control_in_value, 0) &&
252 EQUIV(next->control_out_value, 0))
254 return previous->value;
260 y0 = previous->value;
263 if(direction == PLAY_FORWARD)
265 y1 = previous->value + previous->control_out_value * 2;
266 y2 = next->value + next->control_in_value * 2;
267 t = (double)(position - previous->position) /
268 (next->position - previous->position);
270 if(next->position - previous->position == 0) return previous->value;
274 y1 = previous->value + previous->control_in_value * 2;
275 y2 = next->value + next->control_out_value * 2;
276 t = (double)(previous->position - position) /
277 (previous->position - next->position);
279 if(previous->position - next->position == 0) return previous->value;
283 float tpow3 = t * t * t;
285 float invtpow2 = invt * invt;
286 float invtpow3 = invt * invt * invt;
288 float result = ( invtpow3 * y0
289 + 3 * t * invtpow2 * y1
290 + 3 * tpow2 * invt * y2
292 //printf("FloatAutos::get_value %f %f %d %d %d %d\n", result, t, direction, position, previous->position, next->position);
298 // get_fade_automation(slope,
304 // return (float)intercept;
308 void FloatAutos::get_fade_automation(double &slope,
310 int64_t input_position,
315 FloatAuto *prev_keyframe =
316 (FloatAuto*)get_prev_auto(input_position, direction, current);
317 FloatAuto *next_keyframe =
318 (FloatAuto*)get_next_auto(input_position, direction, current);
319 int64_t new_slope_len;
321 if(direction == PLAY_FORWARD)
323 new_slope_len = next_keyframe->position - prev_keyframe->position;
325 //printf("FloatAutos::get_fade_automation %d %d %d\n",
326 // prev_keyframe->position, input_position, next_keyframe->position);
328 // Two distinct automation points within range
329 if(next_keyframe->position > prev_keyframe->position)
331 slope = ((double)next_keyframe->value - prev_keyframe->value) /
333 intercept = ((double)input_position - prev_keyframe->position) * slope + prev_keyframe->value;
335 if(next_keyframe->position < input_position + new_slope_len)
336 new_slope_len = next_keyframe->position - input_position;
337 slope_len = MIN(slope_len, new_slope_len);
340 // One automation point within range
343 intercept = prev_keyframe->value;
348 new_slope_len = prev_keyframe->position - next_keyframe->position;
349 // Two distinct automation points within range
350 if(next_keyframe->position < prev_keyframe->position)
352 slope = ((double)next_keyframe->value - prev_keyframe->value) / new_slope_len;
353 intercept = ((double)prev_keyframe->position - input_position) * slope + prev_keyframe->value;
355 if(prev_keyframe->position > input_position - new_slope_len)
356 new_slope_len = input_position - prev_keyframe->position;
357 slope_len = MIN(slope_len, new_slope_len);
360 // One automation point within range
363 intercept = next_keyframe->value;
368 void FloatAutos::get_extents(float *min,
370 int *coords_undefined,
376 printf("FloatAutos::get_extents edl == NULL\n");
382 printf("FloatAutos::get_extents track == NULL\n");
389 FloatAuto *current = (FloatAuto*)default_auto;
390 if(*coords_undefined)
392 *min = *max = current->value;
393 *coords_undefined = 0;
396 *min = MIN(current->value, *min);
397 *max = MAX(current->value, *max);
401 for(FloatAuto *current = (FloatAuto*)first; current; current = (FloatAuto*)NEXT)
403 if(current->position >= unit_start && current->position < unit_end)
405 if(*coords_undefined)
407 *min = *max = current->value;
408 *coords_undefined = 0;
411 *min = MIN(current->value, *min);
412 *min = MIN(current->value + current->control_in_value, *min);
413 *min = MIN(current->value + current->control_out_value, *min);
415 *max = MAX(current->value, *max);
416 *max = MAX(current->value + current->control_in_value, *max);
417 *max = MAX(current->value + current->control_out_value, *max);
421 // Test joining regions
424 int64_t unit_step = edl->local_session->zoom_sample;
425 if(track->data_type == TRACK_VIDEO)
426 unit_step = (int64_t)(unit_step *
427 edl->session->frame_rate /
428 edl->session->sample_rate);
429 unit_step = MAX(unit_step, 1);
430 for(int64_t position = unit_start;
432 position += unit_step)
434 float value = get_value(position,
438 if(*coords_undefined)
441 *coords_undefined = 0;
445 *min = MIN(value, *min);
446 *max = MAX(value, *max);
451 void FloatAutos::dump()
453 printf(" FloatAutos::dump %p\n", this);
454 printf(" Default: position %lld value=%f\n",
455 default_auto->position,
456 ((FloatAuto*)default_auto)->value);
457 for(Auto* current = first; current; current = NEXT)
459 printf(" position %lld value=%f invalue=%f outvalue=%f\n",
461 ((FloatAuto*)current)->value,
462 ((FloatAuto*)current)->control_in_value,
463 ((FloatAuto*)current)->control_out_value);