4 #include "edlsession.h"
5 #include "localsession.h"
8 #include "transportque.inc"
13 Autos::Autos(EDL *edl, Track *track)
18 //printf("Autos::Autos 1 %p %p %p\n", this, first, last);
25 while(last) delete last;
29 int Autos::create_objects()
32 default_auto = new_auto();
33 default_auto->is_default = 1;
37 Auto* Autos::new_auto()
39 return new Auto(edl, this);
42 void Autos::resample(double old_rate, double new_rate)
44 for(Auto *current = first; current; current = NEXT)
46 current->position = (int64_t)((double)current->position *
53 void Autos::equivalent_output(Autos *autos, int64_t startproject, int64_t *result)
56 // Default keyframe differs
57 (!total() && !(*default_auto == *autos->default_auto))
60 if(*result < 0 || *result > startproject) *result = startproject;
63 // Search for difference
65 for(Auto *current = first, *that_current = autos->first;
66 current || that_current;
68 that_current = that_current->next)
71 if(current && !that_current)
73 int64_t position1 = (autos->last ? autos->last->position : startproject);
74 int64_t position2 = current->position;
75 if(*result < 0 || *result > MIN(position1, position2))
76 *result = MIN(position1, position2);
80 if(!current && that_current)
82 int64_t position1 = (last ? last->position : startproject);
83 int64_t position2 = that_current->position;
84 if(*result < 0 || *result > MIN(position1, position2))
85 *result = MIN(position1, position2);
90 if(!(*current == *that_current) ||
91 current->position != that_current->position)
93 int64_t position1 = (current->previous ?
94 current->previous->position :
96 int64_t position2 = (that_current->previous ?
97 that_current->previous->position :
99 if(*result < 0 || *result > MIN(position1, position2))
100 *result = MIN(position1, position2);
107 void Autos::copy_from(Autos *autos)
109 Auto *current = autos->first, *this_current = first;
111 default_auto->copy_from(autos->default_auto);
113 // Detect common memory leak bug
114 if(autos->first && !autos->last)
116 printf("Autos::copy_from inconsistent pointers\n");
120 for(current = autos->first; current; current = NEXT)
122 //printf("Autos::copy_from 1 %p\n", current);
126 append(this_current = new_auto());
128 this_current->copy_from(current);
129 this_current = this_current->next;
132 for( ; this_current; )
134 Auto *next_current = this_current->next;
136 this_current = next_current;
141 // We don't replace it in pasting but
142 // when inserting the first EDL of a load operation we need to replace
143 // the default keyframe.
144 void Autos::insert_track(Autos *automation,
146 int64_t length_units,
150 insert(start_unit, start_unit + length_units);
152 if(replace_default) default_auto->copy_from(automation->default_auto);
153 for(Auto *current = automation->first; current; current = NEXT)
155 Auto *new_auto = insert_auto(start_unit + current->position);
156 new_auto->copy_from(current);
157 // Override copy_from
158 new_auto->position = current->position + start_unit;
162 Auto* Autos::get_prev_auto(int64_t position, int direction, Auto* ¤t, int use_default)
164 // Get on or before position
165 if(direction == PLAY_FORWARD)
167 // Try existing result
170 while(current && current->position < position) current = NEXT;
171 while(current && current->position > position) current = PREVIOUS;
177 current && current->position > position;
178 current = PREVIOUS) ;
180 if(!current && use_default) current = (first ? first : default_auto);
183 // Get on or after position
184 if(direction == PLAY_REVERSE)
188 while(current && current->position > position) current = PREVIOUS;
189 while(current && current->position < position) current = NEXT;
195 current && current->position < position;
199 if(!current && use_default) current = (last ? last : default_auto);
205 Auto* Autos::get_prev_auto(int direction, Auto* ¤t)
207 double position_double = edl->local_session->selectionstart;
208 position_double = edl->align_to_frame(position_double, 0);
209 int64_t position = track->to_units(position_double, 0);
211 return get_prev_auto(position, direction, current);
216 int Autos::auto_exists_for_editing(double position)
220 if(edl->session->auto_keyframes)
222 double unit_position = position;
223 unit_position = edl->align_to_frame(unit_position, 0);
224 unit_position = track->to_units(unit_position, 0);
226 for(Auto *current = first;
230 if(edl->equivalent(current->position, unit_position))
245 Auto* Autos::get_auto_for_editing(double position)
249 position = edl->local_session->selectionstart;
253 position = edl->align_to_frame(position, 0);
258 //printf("Autos::get_auto_for_editing %p %p\n", first, default_auto);
260 if(edl->session->auto_keyframes)
262 result = insert_auto(track->to_units(position, 0));
265 result = get_prev_auto(track->to_units(position, 0),
269 //printf("Autos::get_auto_for_editing %p %p %p\n", default_auto, first, result);
274 Auto* Autos::get_next_auto(int64_t position, int direction, Auto* ¤t, int use_default)
276 if(direction == PLAY_FORWARD)
280 while(current && current->position > position) current = PREVIOUS;
281 while(current && current->position < position) current = NEXT;
287 current && current->position <= position;
292 if(!current && use_default) current = (last ? last : default_auto);
295 if(direction == PLAY_REVERSE)
299 while(current && current->position < position) current = NEXT;
300 while(current && current->position > position) current = PREVIOUS;
306 current && current->position > position;
311 if(!current && use_default) current = (first ? first : default_auto);
317 Auto* Autos::insert_auto(int64_t position)
319 Auto *current, *result;
321 // Test for existence
323 current && !edl->equivalent(current->position, position);
329 //printf("Autos::insert_auto %p\n", current);
333 // Get first one on or before as a template
335 current && current->position > position;
343 insert_after(current, result = new_auto());
344 result->copy_from(current);
349 if(!current) current = default_auto;
351 insert_before(first, result = new_auto());
352 if(current) result->copy_from(current);
355 result->position = position;
365 int Autos::clear_all()
367 Auto *current_, *current;
369 for(current = first; current; current = current_)
374 add_auto(0, default_);
378 int Autos::insert(int64_t start, int64_t end)
381 Auto *current = first;
383 for( ; current && current->position < start; current = NEXT)
386 length = end - start;
388 for(; current; current = NEXT)
390 current->position += length;
395 void Autos::paste(int64_t start,
404 //printf("Autos::paste %ld\n", start);
406 result = file->read_tag();
411 if(strstr(file->tag.get_title(), "AUTOS") &&
412 file->tag.get_title()[0] == '/')
417 if(!strcmp(file->tag.get_title(), "AUTO"))
421 // Paste first active auto into default
426 current = default_auto;
430 // Paste default auto into default
432 current = default_auto;
435 int64_t position = Units::to_int64(
436 (double)file->tag.get_property("POSITION", 0) *
439 // Paste active auto into track
440 current = insert_auto(position);
455 int Autos::paste_silence(int64_t start, int64_t end)
461 int Autos::copy(int64_t start,
467 // First auto is always loaded into default even if it is discarded in a paste
469 //printf("Autos::copy 1 %d %d %p\n", default_only, start, autoof(start));
472 default_auto->copy(0, 0, file, default_only);
475 //printf("Autos::copy 10 %d %d %p\n", default_only, start, autoof(start));
478 for(Auto* current = autoof(start);
479 current && current->position <= end;
482 // Want to copy single keyframes by putting the cursor on them
483 if(current->position >= start && current->position <= end)
485 current->copy(start, end, file, default_only);
489 // Copy default auto again to make it the active auto on the clipboard
492 // Need to force position to 0 for the case of plugins
493 // and default status to 0.
494 default_auto->copy(0, 0, file, default_only);
496 //printf("Autos::copy 20\n");
501 // Remove 3 consecutive autos with the same value
502 // Remove autos which are out of order
503 void Autos::optimize()
513 for(Auto *current = first; current; current = NEXT)
515 // Get 3rd consecutive auto of equal value
518 if(*current == *PREVIOUS)
530 if(done && current->position <= PREVIOUS->position)
541 void Autos::remove_nonsequential(Auto *keyframe)
543 if((keyframe->next && keyframe->next->position <= keyframe->position) ||
544 (keyframe->previous && keyframe->previous->position >= keyframe->position))
553 void Autos::clear(int64_t start,
558 Auto *next, *current;
559 length = end - start;
562 current = autoof(start);
564 // If a range is selected don't delete the ending keyframe but do delete
565 // the beginning keyframe because shifting end handle forward shouldn't
566 // delete the first keyframe of the next edit.
569 ((end != start && current->position < end) ||
570 (end == start && current->position <= end)))
577 while(current && shift_autos)
579 current->position -= length;
584 int Autos::clear_auto(int64_t position)
587 current = autoof(position);
588 if(current->position == position) remove(current);
592 int Autos::load(FileXML *file)
595 remove(last); // remove any existing autos
597 int result = 0, first_auto = 1;
601 result = file->read_tag();
605 if(strstr(file->tag.get_title(), "AUTOS") && file->tag.get_title()[0] == '/')
610 if(!strcmp(file->tag.get_title(), "AUTO"))
614 default_auto->load(file);
615 default_auto->position = 0;
620 current = append(new_auto());
621 current->position = file->tag.get_property("POSITION", (int64_t)0);
635 int Autos::slope_adjustment(int64_t ax, double slope)
637 return (int)(ax * slope);
641 int Autos::scale_time(float rate_scale, int scale_edits, int scale_autos, int64_t start, int64_t end)
645 for(current = first; current && scale_autos; current = NEXT)
647 // if(current->position >= start && current->position <= end)
649 current->position = (int64_t)((current->position - start) * rate_scale + start + 0.5);
655 Auto* Autos::autoof(int64_t position)
660 current && current->position < position;
665 return current; // return 0 on failure
668 Auto* Autos::nearest_before(int64_t position)
672 for(current = last; current && current->position >= position; current = PREVIOUS)
676 return current; // return 0 on failure
679 Auto* Autos::nearest_after(int64_t position)
683 for(current = first; current && current->position <= position; current = NEXT)
687 return current; // return 0 on failure
690 int Autos::get_neighbors(int64_t start, int64_t end, Auto **before, Auto **after)
692 if(*before == 0) *before = first;
693 if(*after == 0) *after = last;
695 while(*before && (*before)->next && (*before)->next->position <= start)
696 *before = (*before)->next;
698 while(*after && (*after)->previous && (*after)->previous->position >= end)
699 *after = (*after)->previous;
701 while(*before && (*before)->position > start) *before = (*before)->previous;
703 while(*after && (*after)->position < end) *after = (*after)->next;
707 int Autos::automation_is_constant(int64_t start, int64_t end)
712 double Autos::get_automation_constant(int64_t start, int64_t end)
718 int Autos::init_automation(int64_t &buffer_position,
719 int64_t &input_start,
723 int64_t input_position,
731 // set start and end boundaries for automation info
732 input_start = reverse ? input_position - buffer_len : input_position;
733 input_end = reverse ? input_position : input_position + buffer_len;
735 // test automation for constant value
736 // and set up *before and *after
739 if(automation_is_constant(input_start, input_end))
741 constant += get_automation_constant(input_start, input_end);
749 int Autos::init_slope(Auto **current_auto,
752 double &slope_position,
753 int64_t &input_start,
760 *current_auto = reverse ? *after : *before;
761 // no auto before start so use first auto in range
762 // already know there is an auto since automation isn't constant
765 *current_auto = reverse ? last : first;
766 // slope_value = (*current_auto)->value;
767 slope_start = input_start;
772 // otherwise get the first slope point and advance auto
773 // slope_value = (*current_auto)->value;
774 slope_start = (*current_auto)->position;
775 slope_position = reverse ? slope_start - input_end : input_start - slope_start;
776 (*current_auto) = reverse ? (*current_auto)->previous : (*current_auto)->next;
782 int Autos::get_slope(Auto **current_auto,
788 int64_t buffer_position,
794 slope_end = reverse ? slope_start - (*current_auto)->position : (*current_auto)->position - slope_start;
796 // slope = ((*current_auto)->value - slope_value) / slope_end;
803 slope_end = buffer_len - buffer_position;
808 int Autos::advance_slope(Auto **current_auto,
811 double &slope_position,
816 slope_start = (*current_auto)->position;
817 // slope_value = (*current_auto)->value;
818 (*current_auto) = reverse ? (*current_auto)->previous : (*current_auto)->next;
824 float Autos::value_to_percentage()
829 int64_t Autos::get_length()
832 return last->position + 1;