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,
167 // Get on or before position
168 if(direction == PLAY_FORWARD)
170 // Try existing result
173 while(current && current->position < position) current = NEXT;
174 while(current && current->position > position) current = PREVIOUS;
180 current && current->position > position;
181 current = PREVIOUS) ;
183 if(!current && use_default) current = (first ? first : default_auto);
186 // Get on or after position
187 if(direction == PLAY_REVERSE)
191 while(current && current->position > position) current = PREVIOUS;
192 while(current && current->position < position) current = NEXT;
198 current && current->position < position;
202 if(!current && use_default) current = (last ? last : default_auto);
208 Auto* Autos::get_prev_auto(int direction, Auto* ¤t)
210 double position_double = edl->local_session->selectionstart;
211 position_double = edl->align_to_frame(position_double, 0);
212 int64_t position = track->to_units(position_double, 0);
214 return get_prev_auto(position, direction, current);
219 int Autos::auto_exists_for_editing(double position)
223 if(edl->session->auto_keyframes)
225 double unit_position = position;
226 unit_position = edl->align_to_frame(unit_position, 0);
227 if (get_auto_at_position(unit_position))
238 Auto* Autos::get_auto_at_position(double position)
240 int64_t unit_position = track->to_units(position, 0);
242 for(Auto *current = first;
246 if(edl->equivalent(current->position, unit_position))
255 Auto* Autos::get_auto_for_editing(double position)
259 position = edl->local_session->selectionstart;
263 position = edl->align_to_frame(position, 0);
268 //printf("Autos::get_auto_for_editing %p %p\n", first, default_auto);
270 if(edl->session->auto_keyframes)
272 result = insert_auto_for_editing(track->to_units(position, 0));
275 result = get_prev_auto(track->to_units(position, 0),
279 //printf("Autos::get_auto_for_editing %p %p %p\n", default_auto, first, result);
284 Auto* Autos::get_next_auto(int64_t position, int direction, Auto* ¤t, int use_default)
286 if(direction == PLAY_FORWARD)
290 while(current && current->position > position) current = PREVIOUS;
291 while(current && current->position < position) current = NEXT;
297 current && current->position <= position;
302 if(!current && use_default) current = (last ? last : default_auto);
305 if(direction == PLAY_REVERSE)
309 while(current && current->position < position) current = NEXT;
310 while(current && current->position > position) current = PREVIOUS;
316 current && current->position > position;
321 if(!current && use_default) current = (first ? first : default_auto);
327 Auto* Autos::insert_auto(int64_t position)
329 Auto *current, *result;
331 // Test for existence
333 current && !edl->equivalent(current->position, position);
339 //printf("Autos::insert_auto %p\n", current);
343 // Get first one on or before as a template
345 current && current->position > position;
353 insert_after(current, result = new_auto());
354 result->copy_from(current);
359 if(!current) current = default_auto;
361 insert_before(first, result = new_auto());
362 if(current) result->copy_from(current);
365 result->position = position;
375 Auto* Autos::insert_auto_for_editing(int64_t position)
377 Auto *current, *result;
379 // Test for existence
381 current && !edl->equivalent(current->position, position);
387 //printf("Autos::insert_auto_for_editing %p\n", current);
391 // Get first one on or before as a template
393 current && current->position > position;
402 insert_after(current, result = new_auto());
403 result->interpolate_from(current, next, position);
408 if(!current) current = default_auto;
410 insert_before(first, result = new_auto());
411 if(current) result->copy_from(current);
414 result->position = position;
424 int Autos::clear_all()
426 Auto *current_, *current;
428 for(current = first; current; current = current_)
433 add_auto(0, default_);
437 int Autos::insert(int64_t start, int64_t end)
440 Auto *current = first;
442 for( ; current && current->position < start; current = NEXT)
445 length = end - start;
447 for(; current; current = NEXT)
449 current->position += length;
454 void Autos::paste(int64_t start,
463 //printf("Autos::paste %ld\n", start);
465 result = file->read_tag();
470 if(strstr(file->tag.get_title(), "AUTOS") &&
471 file->tag.get_title()[0] == '/')
476 if(!strcmp(file->tag.get_title(), "AUTO"))
480 // Paste first active auto into default
485 current = default_auto;
489 // Paste default auto into default
491 current = default_auto;
494 int64_t position = Units::to_int64(
495 (double)file->tag.get_property("POSITION", 0) *
498 // Paste active auto into track
499 current = insert_auto(position);
514 int Autos::paste_silence(int64_t start, int64_t end)
520 int Autos::copy(int64_t start,
526 // First auto is always loaded into default even if it is discarded in a paste
528 //printf("Autos::copy 1 %d %d %p\n", default_only, start, autoof(start));
531 default_auto->copy(0, 0, file, default_only);
534 //printf("Autos::copy 10 %d %d %p\n", default_only, start, autoof(start));
537 for(Auto* current = autoof(start);
538 current && current->position <= end;
541 // Want to copy single keyframes by putting the cursor on them
542 if(current->position >= start && current->position <= end)
544 current->copy(start, end, file, default_only);
548 // Copy default auto again to make it the active auto on the clipboard
551 // Need to force position to 0 for the case of plugins
552 // and default status to 0.
553 default_auto->copy(0, 0, file, default_only);
555 //printf("Autos::copy 20\n");
560 // Remove 3 consecutive autos with the same value
561 // Remove autos which are out of order
562 void Autos::optimize()
567 // Default auto should always be at 0
568 default_auto->position = 0;
575 for(Auto *current = first; current; current = NEXT)
577 // Get 3rd consecutive auto of equal value
580 if(*current == *PREVIOUS)
592 if(done && current->position <= PREVIOUS->position)
603 void Autos::remove_nonsequential(Auto *keyframe)
605 if((keyframe->next && keyframe->next->position <= keyframe->position) ||
606 (keyframe->previous && keyframe->previous->position >= keyframe->position))
615 void Autos::clear(int64_t start,
620 Auto *next, *current;
621 length = end - start;
624 current = autoof(start);
626 // If a range is selected don't delete the ending keyframe but do delete
627 // the beginning keyframe because shifting end handle forward shouldn't
628 // delete the first keyframe of the next edit.
631 ((end != start && current->position < end) ||
632 (end == start && current->position <= end)))
639 while(current && shift_autos)
641 current->position -= length;
646 int Autos::clear_auto(int64_t position)
649 current = autoof(position);
650 if(current->position == position) remove(current);
654 int Autos::load(FileXML *file)
657 remove(last); // remove any existing autos
659 int result = 0, first_auto = 1;
663 result = file->read_tag();
667 if(strstr(file->tag.get_title(), "AUTOS") && file->tag.get_title()[0] == '/')
672 if(!strcmp(file->tag.get_title(), "AUTO"))
676 default_auto->load(file);
677 default_auto->position = 0;
682 current = append(new_auto());
683 current->position = file->tag.get_property("POSITION", (int64_t)0);
697 int Autos::slope_adjustment(int64_t ax, double slope)
699 return (int)(ax * slope);
703 int Autos::scale_time(float rate_scale, int scale_edits, int scale_autos, int64_t start, int64_t end)
707 for(current = first; current && scale_autos; current = NEXT)
709 // if(current->position >= start && current->position <= end)
711 current->position = (int64_t)((current->position - start) * rate_scale + start + 0.5);
717 Auto* Autos::autoof(int64_t position)
722 current && current->position < position;
727 return current; // return 0 on failure
730 Auto* Autos::nearest_before(int64_t position)
734 for(current = last; current && current->position >= position; current = PREVIOUS)
738 return current; // return 0 on failure
741 Auto* Autos::nearest_after(int64_t position)
745 for(current = first; current && current->position <= position; current = NEXT)
749 return current; // return 0 on failure
752 int Autos::get_neighbors(int64_t start, int64_t end, Auto **before, Auto **after)
754 if(*before == 0) *before = first;
755 if(*after == 0) *after = last;
757 while(*before && (*before)->next && (*before)->next->position <= start)
758 *before = (*before)->next;
760 while(*after && (*after)->previous && (*after)->previous->position >= end)
761 *after = (*after)->previous;
763 while(*before && (*before)->position > start) *before = (*before)->previous;
765 while(*after && (*after)->position < end) *after = (*after)->next;
769 int Autos::automation_is_constant(int64_t start, int64_t end)
774 double Autos::get_automation_constant(int64_t start, int64_t end)
780 int Autos::init_automation(int64_t &buffer_position,
781 int64_t &input_start,
785 int64_t input_position,
793 // set start and end boundaries for automation info
794 input_start = reverse ? input_position - buffer_len : input_position;
795 input_end = reverse ? input_position : input_position + buffer_len;
797 // test automation for constant value
798 // and set up *before and *after
801 if(automation_is_constant(input_start, input_end))
803 constant += get_automation_constant(input_start, input_end);
811 int Autos::init_slope(Auto **current_auto,
814 double &slope_position,
815 int64_t &input_start,
822 *current_auto = reverse ? *after : *before;
823 // no auto before start so use first auto in range
824 // already know there is an auto since automation isn't constant
827 *current_auto = reverse ? last : first;
828 // slope_value = (*current_auto)->value;
829 slope_start = input_start;
834 // otherwise get the first slope point and advance auto
835 // slope_value = (*current_auto)->value;
836 slope_start = (*current_auto)->position;
837 slope_position = reverse ? slope_start - input_end : input_start - slope_start;
838 (*current_auto) = reverse ? (*current_auto)->previous : (*current_auto)->next;
844 int Autos::get_slope(Auto **current_auto,
850 int64_t buffer_position,
856 slope_end = reverse ? slope_start - (*current_auto)->position : (*current_auto)->position - slope_start;
858 // slope = ((*current_auto)->value - slope_value) / slope_end;
865 slope_end = buffer_len - buffer_position;
870 int Autos::advance_slope(Auto **current_auto,
873 double &slope_position,
878 slope_start = (*current_auto)->position;
879 // slope_value = (*current_auto)->value;
880 (*current_auto) = reverse ? (*current_auto)->previous : (*current_auto)->next;
886 float Autos::value_to_percentage()
891 int64_t Autos::get_length()
894 return last->position + 1;