centos build workarounds
[goodguy/history.git] / cinelerra-5.0 / cinelerra / tracks.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  * 
19  */
20
21 #include "atrack.h"
22 #include "automation.h"
23 #include "cursor.h"
24 #include "bchash.h"
25 #include "edit.h"
26 #include "edits.h"
27 #include "edl.h"
28 #include "edlsession.h"
29 #include "file.h"
30 #include "filexml.h"
31 #include "intauto.h"
32 #include "intautos.h"
33 #include "localsession.h"
34 #include "module.h"
35 #include "panauto.h"
36 #include "panautos.h"
37 #include "patchbay.h"
38 #include "mainsession.h"
39 #include "strack.h"
40 #include "theme.h"
41 #include "track.h"
42 #include "trackcanvas.h"
43 #include "tracks.h"
44 #include "transportque.inc"
45 #include "vtrack.h"
46 #include <string.h>
47
48 Tracks::Tracks(EDL *edl)
49  : List<Track>()
50 {
51         this->edl = edl;
52 }
53
54 Tracks::Tracks()
55  : List<Track>()
56 {
57 }
58
59
60 Tracks::~Tracks()
61 {
62         delete_all_tracks();
63 }
64
65
66
67
68
69 void Tracks::equivalent_output(Tracks *tracks, double *result)
70 {
71         if(total_playable_vtracks() != tracks->total_playable_vtracks())
72         {
73                 *result = 0;
74         }
75         else
76         {
77                 Track *current = first;
78                 Track *that_current = tracks->first;
79                 while(current || that_current)
80                 {
81 // Get next video track
82                         while(current && current->data_type != TRACK_VIDEO)
83                                 current = NEXT;
84
85                         while(that_current && that_current->data_type != TRACK_VIDEO)
86                                 that_current = that_current->next;
87
88 // One doesn't exist but the other does
89                         if((!current && that_current) ||
90                                 (current && !that_current))
91                         {
92                                 *result = 0;
93                                 break;
94                         }
95                         else
96 // Both exist
97                         if(current && that_current)
98                         {
99                                 current->equivalent_output(that_current, result);
100                                 current = NEXT;
101                                 that_current = that_current->next;
102                         }
103                 }
104         }
105 }
106
107
108
109
110 void Tracks::get_affected_edits(ArrayList<Edit*> *drag_edits, double position, Track *start_track)
111 {
112         drag_edits->remove_all();
113
114         for(Track *track = start_track;
115                 track;
116                 track = track->next)
117         {
118 //printf("Tracks::get_affected_edits 1 %p %d %d\n", track, track->data_type, track->record);
119                 if(track->record)
120                 {
121                         for(Edit *edit = track->edits->first; edit; edit = edit->next)
122                         {
123                                 double startproject = track->from_units(edit->startproject);
124 //printf("Tracks::get_affected_edits 1 %d\n", edl->equivalent(startproject, position));
125                                 if(edl->equivalent(startproject, position))
126                                 {
127                                         drag_edits->append(edit);
128                                         break;
129                                 }
130                         }
131                 }
132         }
133
134 }
135
136 void Tracks::get_automation_extents(float *min, 
137         float *max,
138         double start,
139         double end)
140 {
141         *min = 0;
142         *max = 0;
143         int coords_undefined = 1;
144         for(Track *current = first; current; current = NEXT)
145         {
146                 if(current->record)
147                 {
148                         current->automation->get_extents(min,
149                                 max,
150                                 &coords_undefined,
151                                 current->to_units(start, 1),
152                                 current->to_units(end, 1));
153                 }
154         }
155 }
156
157
158 void Tracks::copy_from(Tracks *tracks)
159 {
160         Track *new_track = 0;
161
162         delete_all_tracks();
163         for(Track *current = tracks->first; current; current = NEXT)
164         {
165                 switch(current->data_type)
166                 {
167                 case TRACK_AUDIO: 
168                         new_track = add_audio_track(0, 0); 
169                         break;
170                 case TRACK_VIDEO: 
171                         new_track = add_video_track(0, 0); 
172                         break;
173                 case TRACK_SUBTITLE: 
174                         new_track = add_subttl_track(0, 0);
175                         break;
176                 default:
177                         continue;
178                 }
179                 new_track->copy_from(current);
180         }
181 }
182
183 Tracks& Tracks::operator=(Tracks &tracks)
184 {
185 printf("Tracks::operator= 1\n");
186         copy_from(&tracks);
187         return *this;
188 }
189
190 int Tracks::load(FileXML *xml, 
191         int &track_offset, 
192         uint32_t load_flags)
193 {
194 // add the appropriate type of track
195         char string[BCTEXTLEN];
196         Track *track = 0;
197         string[0] = 0;
198         
199         xml->tag.get_property("TYPE", string);
200
201         if((load_flags & LOAD_ALL) == LOAD_ALL ||
202                 (load_flags & LOAD_EDITS))
203         {
204                 if(!strcmp(string, "VIDEO"))
205                 {
206                         add_video_track(0, 0);
207                 }
208                 else
209                 if(!strcmp(string, "SUBTTL"))
210                 {
211                         add_subttl_track(0, 0);
212                 }
213                 else
214                 {
215                         add_audio_track(0, 0);    // default to audio
216                 }
217                 track = last;
218         }
219         else
220         {
221                 track = get_item_number(track_offset);
222                 track_offset++;
223         }
224
225 // load it
226         if(track) track->load(xml, track_offset, load_flags);
227
228         return 0;
229 }
230
231 Track* Tracks::add_audio_track(int above, Track *dst_track)
232 {
233         ATrack* new_track = new ATrack(edl, this);
234         if(!dst_track)
235         {
236                 dst_track = (above ? first : last);
237         }
238
239         if(above)
240         {
241                 insert_before(dst_track, (Track*)new_track);
242         }
243         else
244         {
245                 insert_after(dst_track, (Track*)new_track);
246 // Shift effects referenced below the destination track
247         }
248
249 // Shift effects referenced below the new track
250         for(Track *track = last; 
251                 track && track != new_track; 
252                 track = track->previous)
253         {
254                 change_modules(number_of(track) - 1, number_of(track), 0);
255         }
256
257
258         new_track->create_objects();
259         new_track->set_default_title();
260
261         int current_pan = 0;
262         for(Track *current = first; 
263                 current != (Track*)new_track; 
264                 current = NEXT)
265         {
266                 if(current->data_type == TRACK_AUDIO) current_pan++;
267                 if(current_pan >= edl->session->audio_channels) current_pan = 0;
268         }
269
270
271
272         PanAuto* pan_auto = 
273                 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
274         pan_auto->values[current_pan] = 1.0;
275
276         BC_Pan::calculate_stick_position(edl->session->audio_channels, 
277                 edl->session->achannel_positions, 
278                 pan_auto->values, 
279                 MAX_PAN, 
280                 PAN_RADIUS,
281                 pan_auto->handle_x,
282                 pan_auto->handle_y);
283         return new_track;
284 }
285
286 Track* Tracks::add_video_track(int above, Track *dst_track)
287 {
288 const int debug = 0;
289 if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
290         VTrack* new_track = new VTrack(edl, this);
291 if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
292         if(!dst_track)
293                 dst_track = (above ? first : last);
294
295 if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
296         if(above)
297         {
298                 insert_before(dst_track, (Track*)new_track);
299         }
300         else
301         {
302                 insert_after(dst_track, (Track*)new_track);
303         }
304 if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
305
306
307
308 // Shift effects referenced below the new track
309         for(Track *track = last; 
310                 track && track != new_track; 
311                 track = track->previous)
312         {
313                 change_modules(number_of(track) - 1, number_of(track), 0);
314         }
315
316 if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
317
318
319         new_track->create_objects();
320 if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
321         new_track->set_default_title();
322 if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
323         return new_track;
324 }
325
326
327 Track* Tracks::add_subttl_track(int above, Track *dst_track)
328 {
329 const int debug = 0;
330 if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
331         STrack* new_track = new STrack(edl, this);
332 if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
333         if(!dst_track)
334                 dst_track = (above ? first : last);
335
336 if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
337         if(above)
338         {
339                 insert_before(dst_track, (Track*)new_track);
340         }
341         else
342         {
343                 insert_after(dst_track, (Track*)new_track);
344         }
345 if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
346
347
348
349 // Shift effects referenced below the new track
350         for(Track *track = last; 
351                 track && track != new_track; 
352                 track = track->previous)
353         {
354                 change_modules(number_of(track) - 1, number_of(track), 0);
355         }
356
357 if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
358
359
360         new_track->create_objects();
361 if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
362         new_track->set_default_title();
363 if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
364
365 //      new_track->paste_silence(0,total_length(),0);
366         return new_track;
367 }
368
369
370 int Tracks::delete_track(Track *track)
371 {
372         if (!track)
373                 return 0;
374
375         int old_location = number_of(track);
376         detach_shared_effects(old_location);
377
378 // Shift effects referencing effects below the deleted track
379         for(Track *current = track; 
380                 current;
381                 current = NEXT)
382         {
383                 change_modules(number_of(current), number_of(current) - 1, 0);
384         }
385         if(track) delete track;
386
387         return 0;
388 }
389
390 int Tracks::detach_shared_effects(int module)
391 {
392         for(Track *current = first; current; current = NEXT)
393         {
394                 current->detach_shared_effects(module);
395         }
396  
397         return 0;
398  }
399
400 int Tracks::total_of(int type)
401 {
402         int result = 0;
403         IntAuto *mute_keyframe = 0;
404         
405         for(Track *current = first; current; current = NEXT)
406         {
407                 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
408                 mute_keyframe = 
409                         (IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_prev_auto(
410                         unit_start, 
411                         PLAY_FORWARD,
412                         (Auto* &)mute_keyframe);
413
414                 result += 
415                         (current->play && type == PLAY) ||
416                         (current->record && type == RECORD) ||
417                         (current->gang && type == GANG) ||
418                         (current->draw && type == DRAW) ||
419                         (mute_keyframe->value && type == MUTE) ||
420                         (current->expand_view && type == EXPAND);
421         }
422         return result;
423 }
424
425 int Tracks::recordable_audio_tracks()
426 {
427         int result = 0;
428         for(Track *current = first; current; current = NEXT)
429                 if(current->data_type == TRACK_AUDIO && current->record) result++;
430         return result;
431 }
432
433 int Tracks::recordable_video_tracks()
434 {
435         int result = 0;
436         for(Track *current = first; current; current = NEXT)
437         {
438                 if(current->data_type == TRACK_VIDEO && current->record) result++;
439         }
440         return result;
441 }
442
443
444 int Tracks::playable_audio_tracks()
445 {
446         int result = 0;
447
448         for(Track *current = first; current; current = NEXT)
449         {
450                 if(current->data_type == TRACK_AUDIO && current->play)
451                 {
452                         result++;
453                 }
454         }
455
456         return result;
457 }
458
459 int Tracks::playable_video_tracks()
460 {
461         int result = 0;
462
463         for(Track *current = first; current; current = NEXT)
464         {
465                 if(current->data_type == TRACK_VIDEO && current->play)
466                 {
467                         result++;
468                 }
469         }
470         return result;
471 }
472
473 int Tracks::total_audio_tracks()
474 {
475         int result = 0;
476         for(Track *current = first; current; current = NEXT)
477                 if(current->data_type == TRACK_AUDIO) result++;
478         return result;
479 }
480
481 int Tracks::total_video_tracks()
482 {
483         int result = 0;
484         for(Track *current = first; current; current = NEXT)
485                 if(current->data_type == TRACK_VIDEO) result++;
486         return result;
487 }
488
489 double Tracks::total_playable_length() 
490 {
491         double total = 0;
492         for(Track *current = first; current; current = NEXT)
493         {
494                 double length = current->get_length();
495                 if(length > total) total = length;
496         }
497         return total; 
498 }
499
500 double Tracks::total_recordable_length() 
501 {
502         double total = 0;
503         for(Track *current = first; current; current = NEXT)
504         {
505                 if(current->record)
506                 {
507                         double length = current->get_length();
508                         if(length > total) total = length;
509                 }
510         }
511         return total; 
512 }
513
514 double Tracks::total_length() 
515 {
516         double total = 0;
517         for(Track *current = first; current; current = NEXT)
518         {
519                 if(current->get_length() > total) total = current->get_length();
520         }
521         return total; 
522 }
523
524 double Tracks::total_video_length() 
525 {
526         double total = 0;
527         for(Track *current = first; current; current = NEXT)
528         {
529                 if(current->data_type == TRACK_VIDEO &&
530                         current->get_length() > total) total = current->get_length();
531         }
532         return total; 
533 }
534
535
536 void Tracks::translate_camera(float offset_x, float offset_y)
537 {
538         for(Track *current = first; current; current = NEXT)
539         {
540                 if(current->data_type == TRACK_VIDEO)
541                 {
542                         ((VTrack*)current)->translate(offset_x, offset_y, 1);
543                 }
544         }
545 }
546 void Tracks::translate_projector(float offset_x, float offset_y)
547 {
548         for(Track *current = first; current; current = NEXT)
549         {
550                 if(current->data_type == TRACK_VIDEO)
551                 {
552                         ((VTrack*)current)->translate(offset_x, offset_y, 0);
553                 }
554         }
555 }
556
557 void Tracks::update_y_pixels(Theme *theme)
558 {
559 //      int y = -edl->local_session->track_start;
560         int y = 0;
561         for(Track *current = first; current; current = NEXT)
562         {
563 //printf("Tracks::update_y_pixels %d\n", y);
564                 current->y_pixel = y;
565                 y += current->vertical_span(theme);
566         }
567 }
568
569 int Tracks::dump(FILE *fp)
570 {
571         for(Track* current = first; current; current = NEXT)
572         {
573                 fprintf(fp,"  Track: %p\n", current);
574                 current->dump(fp);
575                 fprintf(fp,"\n");
576         }
577         return 0;
578 }
579
580 void Tracks::select_all(int type,
581                 int value)
582 {
583         for(Track* current = first; current; current = NEXT)
584         {
585                 double position = edl->local_session->get_selectionstart(1);
586
587                 if(type == PLAY) current->play = value;
588                 if(type == RECORD) current->record = value;
589                 if(type == GANG) current->gang = value;
590                 if(type == DRAW) current->draw = value;
591                 
592                 if(type == MUTE)
593                 {
594                         ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
595                 }
596
597                 if(type == EXPAND) current->expand_view = value;
598         }
599 }
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642 // ===================================== file operations
643
644 int Tracks::popup_transition(int cursor_x, int cursor_y)
645 {
646         int result = 0;
647         for(Track* current = first; current && !result; current = NEXT)
648         {
649                 result = current->popup_transition(cursor_x, cursor_y);
650         }
651         return result;
652 }
653
654
655 int Tracks::change_channels(int oldchannels, int newchannels)
656 {
657         for(Track *current = first; current; current = NEXT)
658         { current->change_channels(oldchannels, newchannels); }
659         return 0;
660 }
661
662
663
664 int Tracks::totalpixels()
665 {
666         int result = 0;
667         for(Track* current = first; current; current = NEXT)
668         {
669                 result += edl->local_session->zoom_track;
670         }
671         return result;
672 }
673
674 int Tracks::number_of(Track *track)
675 {
676         int i = 0;
677         for(Track *current = first; current && current != track; current = NEXT)
678         {
679                 i++;
680         }
681         return i;
682 }
683
684 Track* Tracks::number(int number)
685 {
686         Track *current;
687         int i = 0;
688         for(current = first; current && i < number; current = NEXT)
689         {
690                 i++;
691         }
692         return current;
693 }
694
695
696 int Tracks::total_playable_vtracks()
697 {
698         int result = 0;
699         for(Track *current = first; current; current = NEXT)
700         {
701                 if(current->data_type == TRACK_VIDEO && current->play) result++;
702         }
703         return result;
704 }
705
706 int Tracks::plugin_exists(Plugin *plugin)
707 {
708         for(Track *track = first; track; track = track->next)
709         {
710                 if(track->plugin_exists(plugin)) return 1;
711         }
712         return 0;
713 }
714
715 int Tracks::track_exists(Track *track)
716 {
717         for(Track *current = first; current; current = NEXT)
718         {
719                 if(current == track) return 1;
720         }
721         return 0;
722 }
723
724
725 Track *Tracks::get(int idx, int data_type)
726 {
727         for(Track *current = first; current; current = NEXT)
728         {
729                 if( current->data_type != data_type ) continue;
730                 if( --idx < 0 ) return current;
731         }
732         return 0;
733 }
734
735
736
737