initial commit
[goodguy/history.git] / cinelerra-5.0 / cinelerra / autos.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include <stdio.h>
23 #include <stdint.h>
24 #include <string.h>
25
26 #include "autos.h"
27 #include "clip.h"
28 #include "format.inc"
29 #include "edl.h"
30 #include "edlsession.h"
31 #include "localsession.h"
32 #include "filexml.h"
33 #include "track.h"
34 #include "transportque.inc"
35
36
37 Autos::Autos(EDL *edl, Track *track)
38  : List<Auto>()
39 {
40         this->edl = edl;
41         this->track = track;
42         type = -1;
43 }
44
45
46
47 Autos::~Autos()
48 {
49         while(last) delete last;
50         delete default_auto;
51 }
52
53 void Autos::create_objects()
54 {
55 // Default
56         default_auto = new_auto();
57         default_auto->is_default = 1;
58 }
59
60 int Autos::get_type()
61 {
62         return type;
63 }
64
65 Auto* Autos::append_auto()
66 {
67         return append(new_auto());
68 }
69
70
71 Auto* Autos::new_auto()
72 {
73         return new Auto(edl, this);
74 }
75
76 void Autos::resample(double old_rate, double new_rate)
77 {
78         for(Auto *current = first; current; current = NEXT)
79         {
80                 current->position = (int64_t)((double)current->position * 
81                         new_rate / 
82                         old_rate + 
83                         0.5);
84         }
85 }
86
87 void Autos::equivalent_output(Autos *autos, int64_t startproject, int64_t *result)
88 {
89 // Default keyframe differs
90         if(!total() && !(*default_auto == *autos->default_auto))
91         {
92                 if(*result < 0 || *result > startproject) *result = startproject;
93         }
94         else
95 // Search for difference
96         {
97                 for(Auto *current = first, *that_current = autos->first; 
98                         current || that_current; 
99                         current = NEXT,
100                         that_current = that_current->next)
101                 {
102 // Total differs
103                         if(current && !that_current)
104                         {
105                                 int64_t position1 = (autos->last ? autos->last->position : startproject);
106                                 int64_t position2 = current->position;
107                                 if(*result < 0 || *result > MIN(position1, position2))
108                                         *result = MIN(position1, position2);
109                                 break;
110                         }
111                         else
112                         if(!current && that_current)
113                         {
114                                 int64_t position1 = (last ? last->position : startproject);
115                                 int64_t position2 = that_current->position;
116                                 if(*result < 0 || *result > MIN(position1, position2))
117                                         *result = MIN(position1, position2);
118                                 break;
119                         }
120                         else
121 // Keyframes differ
122                         if(!(*current == *that_current) || 
123                                 current->position != that_current->position)
124                         {
125                                 int64_t position1 = (current->previous ? 
126                                         current->previous->position : 
127                                         startproject);
128                                 int64_t position2 = (that_current->previous ? 
129                                         that_current->previous->position : 
130                                         startproject);
131                                 if(*result < 0 || *result > MIN(position1, position2))
132                                         *result = MIN(position1, position2);
133                                 break;
134                         }
135                 }
136         }
137 }
138
139 void Autos::copy_from(Autos *autos)
140 {
141         Auto *current = autos->first, *this_current = first;
142
143         default_auto->copy_from(autos->default_auto);
144
145 // Detect common memory leak bug
146         if(autos->first && !autos->last)
147         {
148                 printf("Autos::copy_from inconsistent pointers\n");
149                 exit(1);
150         }
151
152         for(current = autos->first; current; current = NEXT)
153         {
154 //printf("Autos::copy_from 1 %p\n", current);
155 //sleep(1);
156                 if(!this_current)
157                 {
158                         append(this_current = new_auto());
159                 }
160                 this_current->copy_from(current);
161                 this_current = this_current->next;
162         }
163
164         for( ; this_current; )
165         {
166                 Auto *next_current = this_current->next;
167                 delete this_current;
168                 this_current = next_current;
169         }
170 }
171
172
173 // We don't replace it in pasting but
174 // when inserting the first EDL of a load operation we need to replace
175 // the default keyframe.
176 void Autos::insert_track(Autos *automation, 
177         int64_t start_unit, 
178         int64_t length_units,
179         int replace_default)
180 {
181 // Insert silence
182         insert(start_unit, start_unit + length_units);
183
184         if(replace_default) default_auto->copy_from(automation->default_auto);
185         for(Auto *current = automation->first; current; current = NEXT)
186         {
187                 Auto *new_auto = insert_auto(start_unit + current->position);
188                 new_auto->copy_from(current);
189 // Override copy_from
190                 new_auto->position = current->position + start_unit;
191         }
192 }
193
194 Auto* Autos::get_prev_auto(int64_t position, 
195         int direction, 
196         Auto* &current, 
197         int use_default)
198 {
199 // Get on or before position
200         if(direction == PLAY_FORWARD)
201         {
202 // Try existing result
203                 if(current)
204                 {
205                         while(current && current->position < position) current = NEXT;
206                         while(current && current->position > position) current = PREVIOUS;
207                 }
208
209                 if(!current)
210                 {
211                         for(current = last; 
212                                 current && current->position > position; 
213                                 current = PREVIOUS) ;
214                 }
215                 if(!current && use_default) current = (first ? first : default_auto);
216         }
217         else
218 // Get on or after position
219         if(direction == PLAY_REVERSE)
220         {
221                 if(current)
222                 {
223                         while(current && current->position > position) current = PREVIOUS;
224                         while(current && current->position < position) current = NEXT;
225                 }
226
227                 if(!current)
228                 {
229                         for(current = first; 
230                                 current && current->position < position; 
231                                 current = NEXT) ;
232                 }
233
234                 if(!current && use_default) current = (last ? last : default_auto);
235         }
236
237         return current;
238 }
239
240 Auto* Autos::get_prev_auto(int direction, Auto* &current)
241 {
242         double position_double = edl->local_session->get_selectionstart(1);
243         position_double = edl->align_to_frame(position_double, 0);
244         int64_t position = track->to_units(position_double, 0);
245
246         return get_prev_auto(position, direction, current);
247
248         return current;
249 }
250
251 int Autos::auto_exists_for_editing(double position)
252 {
253         int result = 0;
254         
255         if(edl->session->auto_keyframes)
256         {
257                 double unit_position = position;
258                 unit_position = edl->align_to_frame(unit_position, 0);
259                 if (get_auto_at_position(unit_position))
260                         result = 1;
261         }
262         else
263         {
264                 result = 1;
265         }
266
267         return result;
268 }
269
270 Auto* Autos::get_auto_at_position(double position)
271 {
272         int64_t unit_position = track->to_units(position, 0);
273
274         for(Auto *current = first; 
275                 current; 
276                 current = NEXT)
277         {
278                 if(edl->equivalent(current->position, unit_position))
279                 {
280                         return current;
281                 }
282         }
283         return 0;
284 }
285
286
287 Auto* Autos::get_auto_for_editing(double position)
288 {
289         if(position < 0)
290         {
291                 position = edl->local_session->get_selectionstart(1);
292         }
293
294         Auto *result = 0;
295         position = edl->align_to_frame(position, 0);
296
297
298
299
300 //printf("Autos::get_auto_for_editing %p %p\n", first, default_auto);
301
302         if(edl->session->auto_keyframes)
303         {
304                 result = insert_auto(track->to_units(position, 0));
305         }
306         else
307                 result = get_prev_auto(track->to_units(position, 0), 
308                         PLAY_FORWARD, 
309                         result);
310
311 //printf("Autos::get_auto_for_editing %p %p %p\n", default_auto, first, result);
312         return result;
313 }
314
315
316 Auto* Autos::get_next_auto(int64_t position, int direction, Auto* &current, int use_default)
317 {
318         if(direction == PLAY_FORWARD)
319         {
320                 if(current)
321                 {
322                         while(current && current->position > position) current = PREVIOUS;
323                         while(current && current->position < position) current = NEXT;
324                 }
325
326                 if(!current)
327                 {
328                         for(current = first;
329                                 current && current->position <= position;
330                                 current = NEXT)
331                                 ;
332                 }
333
334                 if(!current && use_default) current = (last ? last : default_auto);
335         }
336         else
337         if(direction == PLAY_REVERSE)
338         {
339                 if(current)
340                 {
341                         while(current && current->position < position) current = NEXT;
342                         while(current && current->position > position) current = PREVIOUS;
343                 }
344
345                 if(!current)
346                 {
347                         for(current = last;
348                                 current && current->position > position;
349                                 current = PREVIOUS)
350                                 ;
351                 }
352
353                 if(!current && use_default) current = (first ? first : default_auto);
354         }
355
356         return current;
357 }
358
359 Auto* Autos::insert_auto(int64_t position)
360 {
361         Auto *current, *result;
362
363 // Test for existence
364         for(current = first; 
365                 current && !edl->equivalent(current->position, position); 
366                 current = NEXT)
367         {
368                 ;
369         }
370
371 // Insert new
372         if(!current)
373         {
374 // Get first one on or before as a template
375                 for(current = last; 
376                         current && current->position > position; 
377                         current = PREVIOUS)
378                 {
379                         ;
380                 }
381
382                 if(current)
383                 {
384                         insert_after(current, result = new_auto());
385                         result->copy_from(current);
386                 }
387                 else
388                 {
389                         current = first;
390                         if(!current) current = default_auto;
391
392                         insert_before(first, result = new_auto());
393                         if(current) result->copy_from(current);
394                 }
395
396                 result->position = position;
397 // Set curve type
398                 result->mode = edl->local_session->floatauto_type;
399         }
400         else
401         {
402                 result = current;
403         }
404
405         return result;
406 }
407
408 int Autos::clear_all()
409 {
410         Auto *current_, *current;
411         
412         for(current = first; current; current = current_)
413         {
414                 current_ = NEXT;
415                 remove(current);
416         }
417         append_auto();
418         return 0;
419 }
420
421 int Autos::insert(int64_t start, int64_t end)
422 {
423         int64_t length;
424         Auto *current = first;
425
426         for( ; current && current->position < start; current = NEXT)
427                 ;
428
429         length = end - start;
430
431         for(; current; current = NEXT)
432         {
433                 current->position += length;
434         }
435         return 0;
436 }
437
438 void Autos::paste(int64_t start, 
439         int64_t length, 
440         double scale, 
441         FileXML *file, 
442         int default_only,
443         int active_only)
444 {
445         int total = 0;
446         int result = 0;
447
448 //printf("Autos::paste %d start=" _LD "\n", __LINE__, start);
449         do{
450                 result = file->read_tag();
451
452                 if(!result)
453                 {
454 // End of list
455                         if(file->tag.get_title()[0] == '/')
456                         {
457                                 result = 1;
458                         }
459                         else
460                         if(!strcmp(file->tag.get_title(), "AUTO"))
461                         {
462                                 Auto *current = 0;
463
464 // Paste first auto into default                                
465                                 if(default_only && total == 0)
466                                 {
467                                         current = default_auto;
468                                 }
469                                 else
470 // Paste default auto into default
471                                 if(!default_only)
472                                 {
473                                         int64_t position = Units::to_int64(
474                                                 (double)file->tag.get_property("POSITION", 0) *
475                                                         scale + 
476                                                         start);
477 // Paste active auto into track
478                                         current = insert_auto(position);
479                                 }
480
481                                 if(current)
482                                 {
483                                         current->load(file);
484                                 }
485                                 total++;
486                         }
487                 }
488         }while(!result);
489         
490 }
491
492
493 int Autos::paste_silence(int64_t start, int64_t end)
494 {
495         insert(start, end);
496         return 0;
497 }
498
499 int Autos::copy(int64_t start, 
500         int64_t end, 
501         FileXML *file, 
502         int default_only,
503         int active_only)
504 {
505 // First auto always loaded with default
506 //printf("Autos::copy %d %d %d\n", __LINE__, default_only, active_only);
507         if(default_only || (!active_only && !default_only))
508         {
509                 default_auto->copy(0, 0, file, default_only);
510         }
511
512 //printf("Autos::copy 10 %d %d %p\n", default_only, start, autoof(start));
513         if(active_only || (!default_only && !active_only))
514         {
515                 for(Auto* current = autoof(start); 
516                         current && current->position <= end; 
517                         current = NEXT)
518                 {
519 // Want to copy single keyframes by putting the cursor on them
520                         if(current->position >= start && current->position <= end)
521                         {
522                                 current->copy(start, end, file, default_only);
523                         }
524                 }
525         }
526 // Copy default auto again to make it the active auto on the clipboard
527 //      else
528 //      {
529 // Need to force position to 0 for the case of plugins
530 // and default status to 0.
531 //              default_auto->copy(0, 0, file, default_only);
532 //      }
533 //printf("Autos::copy 20\n");
534
535         return 0;
536 }
537
538 // Remove 3 consecutive autos with the same value
539 // Remove autos which are out of order
540 void Autos::optimize()
541 {
542         int done = 0;
543
544
545 // Default auto should always be at 0
546         default_auto->position = 0;
547         while(!done)
548         {
549                 int consecutive = 0;
550                 done = 1;
551                 
552                 
553                 for(Auto *current = first; current; current = NEXT)
554                 {
555 // Get 3rd consecutive auto of equal value
556                         if(current != first)
557                         {
558                                 if(*current == *PREVIOUS)
559                                 {
560                                         consecutive++;
561                                         if(consecutive >= 3)
562                                         {
563                                                 delete PREVIOUS;
564                                                 break;
565                                         }
566                                 }
567                                 else
568                                         consecutive = 0;
569                                 
570                                 if(done && current->position <= PREVIOUS->position)
571                                 {
572                                         delete current;
573                                         break;
574                                 }
575                         }
576                 }
577         }
578 }
579
580
581 void Autos::remove_nonsequential(Auto *keyframe)
582 {
583         if((keyframe->next && keyframe->next->position <= keyframe->position) ||
584                 (keyframe->previous && keyframe->previous->position >= keyframe->position))
585         {
586                 delete keyframe;
587         }
588 }
589
590
591 void Autos::set_automation_mode(int64_t start, int64_t end, int mode)
592 {
593 }
594
595 void Autos::clear(int64_t start, 
596         int64_t end, 
597         int shift_autos)
598 {
599         int64_t length;
600         Auto *next, *current;
601         length = end - start;
602
603
604         current = autoof(start);
605
606 // If a range is selected don't delete the ending keyframe but do delete
607 // the beginning keyframe because shifting end handle forward shouldn't
608 // delete the first keyframe of the next edit.
609
610         while(current && 
611                 ((end != start && current->position < end) ||
612                 (end == start && current->position <= end)))
613         {
614                 next = NEXT;
615                 remove(current);
616                 current = next;
617         }
618
619         while(current && shift_autos)
620         {
621                 current->position -= length;
622                 current = NEXT;
623         }
624 }
625
626 int Autos::clear_auto(int64_t position)
627 {
628         Auto *current;
629         current = autoof(position);
630         return current->position==position ? (remove(current), 1) : 0;
631 }
632
633
634 int Autos::load(FileXML *file)
635 {
636         while(last)
637                 remove(last);    // remove any existing autos
638
639         int result = 0, first_auto = 1;
640         Auto *current;
641         
642         do{
643                 result = file->read_tag();
644                 
645                 if(!result)
646                 {
647 // First tag with leading / is taken as end of autos
648                         if(/* strstr(file->tag.get_title(), "AUTOS") && */
649
650                                 file->tag.get_title()[0] == '/')
651                         {
652                                 result = 1;
653                         }
654                         else
655                         if(!strcmp(file->tag.get_title(), "AUTO"))
656                         {
657                                 if(first_auto)
658                                 {
659                                         default_auto->load(file);
660                                         default_auto->position = 0;
661                                         first_auto = 0;
662                                 }
663                                 else
664                                 {
665                                         current = append(new_auto());
666                                         current->position = file->tag.get_property("POSITION", (int64_t)0);
667                                         current->load(file);
668                                 }
669                         }
670                 }
671         }while(!result);
672         return 0;
673 }
674
675
676
677
678
679
680 int Autos::slope_adjustment(int64_t ax, double slope)
681 {
682         return (int)(ax * slope);
683 }
684
685
686 int Autos::scale_time(float rate_scale, int scale_edits, int scale_autos, int64_t start, int64_t end)
687 {
688         Auto *current;
689         
690         for(current = first; current && scale_autos; current = NEXT)
691         {
692 //              if(current->position >= start && current->position <= end)
693 //              {
694                         current->position = (int64_t)((current->position - start) * rate_scale + start + 0.5);
695 //              }
696         }
697         return 0;
698 }
699
700 Auto* Autos::autoof(int64_t position)
701 {
702         Auto *current;
703
704         for(current = first; 
705                 current && current->position < position; 
706                 current = NEXT)
707         { 
708                 ;
709         }
710         return current;     // return 0 on failure
711 }
712
713 Auto* Autos::nearest_before(int64_t position)
714 {
715         Auto *current;
716
717         for(current = last; current && current->position >= position; current = PREVIOUS)
718         { ; }
719
720
721         return current;     // return 0 on failure
722 }
723
724 Auto* Autos::nearest_after(int64_t position)
725 {
726         Auto *current;
727
728         for(current = first; current && current->position <= position; current = NEXT)
729         { ; }
730
731
732         return current;     // return 0 on failure
733 }
734
735 int Autos::get_neighbors(int64_t start, int64_t end, Auto **before, Auto **after)
736 {
737         if(*before == 0) *before = first;
738         if(*after == 0) *after = last; 
739
740         while(*before && (*before)->next && (*before)->next->position <= start)
741                 *before = (*before)->next;
742         
743         while(*after && (*after)->previous && (*after)->previous->position >= end)
744                 *after = (*after)->previous;
745
746         while(*before && (*before)->position > start) *before = (*before)->previous;
747         
748         while(*after && (*after)->position < end) *after = (*after)->next;
749         return 0;
750 }
751
752 int Autos::automation_is_constant(int64_t start, int64_t end)
753 {
754         return 0;
755 }
756
757 double Autos::get_automation_constant(int64_t start, int64_t end)
758 {
759         return 0;
760 }
761
762
763 int Autos::init_automation(int64_t &buffer_position,
764                                 int64_t &input_start, 
765                                 int64_t &input_end, 
766                                 int &automate, 
767                                 double &constant, 
768                                 int64_t input_position,
769                                 int64_t buffer_len,
770                                 Auto **before, 
771                                 Auto **after,
772                                 int reverse)
773 {
774         buffer_position = 0;
775
776 // set start and end boundaries for automation info
777         input_start = reverse ? input_position - buffer_len : input_position;
778         input_end = reverse ? input_position : input_position + buffer_len;
779
780 // test automation for constant value
781 // and set up *before and *after
782         if(automate)
783         {
784                 if(automation_is_constant(input_start, input_end))
785                 {
786                         constant += get_automation_constant(input_start, input_end);
787                         automate = 0;
788                 }
789         }
790         return automate;
791 }
792
793
794 int Autos::init_slope(Auto **current_auto, 
795                                 double &slope_start, 
796                                 double &slope_value,
797                                 double &slope_position, 
798                                 int64_t &input_start, 
799                                 int64_t &input_end, 
800                                 Auto **before, 
801                                 Auto **after,
802                                 int reverse)
803 {
804 // apply automation
805         *current_auto = reverse ? *after : *before;
806 // no auto before start so use first auto in range
807 // already know there is an auto since automation isn't constant
808         if(!*current_auto)
809         {
810                 *current_auto = reverse ? last : first;
811 //              slope_value = (*current_auto)->value;
812                 slope_start = input_start;
813                 slope_position = 0;
814         }
815         else
816         {
817 // otherwise get the first slope point and advance auto
818 //              slope_value = (*current_auto)->value;
819                 slope_start = (*current_auto)->position;
820                 slope_position = reverse ? slope_start - input_end : input_start - slope_start;
821                 (*current_auto) = reverse ? (*current_auto)->previous : (*current_auto)->next;
822         }
823         return 0;
824 }
825
826
827 int Autos::get_slope(Auto **current_auto, 
828                                 double &slope_start, 
829                                 double &slope_end, 
830                                 double &slope_value,
831                                 double &slope, 
832                                 int64_t buffer_len, 
833                                 int64_t buffer_position,
834                                 int reverse)
835 {
836 // get the slope
837         if(*current_auto)
838         {
839                 slope_end = reverse ? slope_start - (*current_auto)->position : (*current_auto)->position - slope_start;
840                 if(slope_end) 
841 //                      slope = ((*current_auto)->value - slope_value) / slope_end;
842 //              else
843                         slope = 0;
844         }
845         else
846         {
847                 slope = 0;
848                 slope_end = buffer_len - buffer_position;
849         }
850         return 0;
851 }
852
853 int Autos::advance_slope(Auto **current_auto, 
854                                 double &slope_start, 
855                                 double &slope_value,
856                                 double &slope_position, 
857                                 int reverse)
858 {
859         if(*current_auto) 
860         {
861                 slope_start = (*current_auto)->position;
862 //              slope_value = (*current_auto)->value;
863                 (*current_auto) = reverse ? (*current_auto)->previous : (*current_auto)->next;
864                 slope_position = 0;
865         }
866         return 0;
867 }
868
869 int64_t Autos::get_length()
870 {
871         if(last) 
872                 return last->position + 1;
873         else
874                 return 0;
875 }
876
877 void Autos::get_extents(float *min, 
878         float *max,
879         int *coords_undefined,
880         int64_t unit_start,
881         int64_t unit_end)
882 {
883         
884 }
885
886
887 void Autos::dump(FILE *fp)
888 {
889 }
890
891
892
893
894
895
896
897
898
899