add master/armed_gang track operations, tweak appearanceprefs layout, fix vicon video...
[goodguy/cinelerra.git] / cinelerra-5.1 / 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 "clip.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 void Tracks::clear_selected_edits()
109 {
110         for( Track *track=first; track; track=track->next ) {
111                 for( Edit *edit=track->edits->first; edit; edit=edit->next )
112                         edit->is_selected = 0;
113         }
114 }
115
116 void Tracks::get_selected_edits(ArrayList<Edit*> *drag_edits)
117 {
118         drag_edits->remove_all();
119         for( Track *track=first; track; track=track->next ) {
120                 if( !track->is_armed() ) continue;
121                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
122                         if( !edit->is_selected ) continue;
123                         drag_edits->append(edit);
124                 }
125         }
126 }
127
128 void Tracks::get_automation_extents(float *min,
129         float *max,
130         double start,
131         double end,
132         int autogrouptype)
133 {
134         *min = 0;
135         *max = 0;
136         int coords_undefined = 1;
137         for(Track *current = first; current; current = NEXT)
138         {
139                 if(current->is_armed())
140                 {
141                         current->automation->get_extents(min,
142                                 max,
143                                 &coords_undefined,
144                                 current->to_units(start, 0),
145                                 current->to_units(end, 1),
146                                 autogrouptype);
147                 }
148         }
149 }
150
151
152 void Tracks::copy_from(Tracks *tracks)
153 {
154         Track *new_track = 0;
155
156         delete_all_tracks();
157         int solo_track_id = tracks->edl->local_session->solo_track_id;
158
159         for(Track *current = tracks->first; current; current = NEXT)
160         {
161                 switch(current->data_type)
162                 {
163                 case TRACK_AUDIO:
164                         new_track = add_audio_track(0, 0);
165                         break;
166                 case TRACK_VIDEO:
167                         new_track = add_video_track(0, 0);
168                         break;
169                 case TRACK_SUBTITLE:
170                         new_track = add_subttl_track(0, 0);
171                         break;
172                 default:
173                         continue;
174                 }
175                 new_track->copy_from(current);
176
177                 if( current->get_id() == solo_track_id )
178                         edl->local_session->solo_track_id = new_track->get_id();
179         }
180 }
181
182 Tracks& Tracks::operator=(Tracks &tracks)
183 {
184 printf("Tracks::operator= 1\n");
185         copy_from(&tracks);
186         return *this;
187 }
188
189 int Tracks::load(FileXML *xml,
190         int &track_offset,
191         uint32_t load_flags)
192 {
193 // add the appropriate type of track
194         char string[BCTEXTLEN];
195         Track *track = 0;
196         string[0] = 0;
197
198         xml->tag.get_property("TYPE", string);
199
200         if((load_flags & LOAD_ALL) == LOAD_ALL ||
201                 (load_flags & LOAD_EDITS)) {
202                 if(!strcmp(string, "VIDEO")) {
203                         track = add_video_track(0, 0);
204                 }
205                 else if(!strcmp(string, "SUBTTL")) {
206                         track = add_subttl_track(0, 0);
207                 }
208                 else {
209                         track = add_audio_track(0, 0);    // default to audio
210                 }
211         }
212         else {
213                 track = get_item_number(track_offset++);
214         }
215
216 // load it
217         if( track ) track->load(xml, track_offset, load_flags);
218
219         return 0;
220 }
221
222 Track* Tracks::add_audio_track(int above, Track *dst_track)
223 {
224         ATrack* new_track = new ATrack(edl, this);
225         if(!dst_track)
226         {
227                 dst_track = (above ? first : last);
228         }
229
230         if(above)
231         {
232                 insert_before(dst_track, (Track*)new_track);
233         }
234         else
235         {
236                 insert_after(dst_track, (Track*)new_track);
237 // Shift effects referenced below the destination track
238         }
239
240 // Shift effects referenced below the new track
241         for(Track *track = last;
242                 track && track != new_track;
243                 track = track->previous)
244         {
245                 change_modules(number_of(track) - 1, number_of(track), 0);
246         }
247
248
249         new_track->create_objects();
250         new_track->set_default_title();
251
252         int current_pan = 0;
253         for(Track *current = first;
254                 current != (Track*)new_track;
255                 current = NEXT)
256         {
257                 if(current->data_type == TRACK_AUDIO) current_pan++;
258                 if(current_pan >= edl->session->audio_channels) current_pan = 0;
259         }
260
261
262
263         PanAuto* pan_auto =
264                 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
265         pan_auto->values[current_pan] = 1.0;
266
267         BC_Pan::calculate_stick_position(edl->session->audio_channels,
268                 edl->session->achannel_positions,
269                 pan_auto->values,
270                 MAX_PAN,
271                 PAN_RADIUS,
272                 pan_auto->handle_x,
273                 pan_auto->handle_y);
274         return new_track;
275 }
276
277 Track* Tracks::add_video_track(int above, Track *dst_track)
278 {
279         VTrack* new_track = new VTrack(edl, this);
280         if(!dst_track)
281                 dst_track = (above ? first : last);
282         if(above)
283                 insert_before(dst_track, (Track*)new_track);
284         else
285                 insert_after(dst_track, (Track*)new_track);
286
287         for(Track *track = last; track && track != new_track; track = track->previous)
288                 change_modules(number_of(track) - 1, number_of(track), 0);
289
290         new_track->create_objects();
291         new_track->set_default_title();
292         return new_track;
293 }
294
295
296 Track* Tracks::add_subttl_track(int above, Track *dst_track)
297 {
298         STrack* new_track = new STrack(edl, this);
299         if(!dst_track)
300                 dst_track = (above ? first : last);
301
302         if(above)
303                 insert_before(dst_track, (Track*)new_track);
304         else
305                 insert_after(dst_track, (Track*)new_track);
306
307         for(Track *track = last; track && track != new_track; track = track->previous)
308                 change_modules(number_of(track) - 1, number_of(track), 0);
309
310         new_track->create_objects();
311         new_track->set_default_title();
312 //      new_track->paste_silence(0,total_length(),0);
313         return new_track;
314 }
315
316
317 int Tracks::delete_track(Track *track)
318 {
319         if( !track ) return 0;
320         int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
321         Track *nxt = track->next;
322         if( gang ) {
323                 while( track && !track->master && track->previous )
324                         track = track->previous;
325                 while( nxt && !nxt->master )
326                         nxt = nxt->next;
327         }
328         Track *current = track;
329         int old_location = number_of(current);
330         for( Track *next_track=0; current!=nxt; current=next_track ) {
331                 next_track = current->next;
332                 detach_shared_effects(old_location);
333                 for( Track *curr=current; curr; curr=curr->next ) {
334 // Shift effects referencing effects below the deleted track
335                         change_modules(number_of(curr), number_of(curr)-1, 0);
336                 }
337                 delete current;
338         }
339         return 0;
340 }
341
342 int Tracks::detach_shared_effects(int module)
343 {
344         for(Track *current = first; current; current = NEXT)
345         {
346                 current->detach_shared_effects(module);
347         }
348
349         return 0;
350  }
351
352 int Tracks::total_of(int type)
353 {
354         int result = 0;
355
356         for(Track *current = first; current; current = NEXT)
357         {
358                 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
359                 Auto *mute_keyframe = 0;
360                 current->automation->autos[AUTOMATION_MUTE]->
361                         get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
362                 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
363
364                 result +=
365                         (current->play && type == PLAY) ||
366                         (current->is_armed() && type == RECORD) ||
367                         (current->is_ganged() && type == GANG) ||
368                         (current->draw && type == DRAW) ||
369                         (mute_auto->value && type == MUTE) ||
370                         (current->expand_view && type == EXPAND);
371         }
372         return result;
373 }
374
375 int Tracks::recordable_audio_tracks()
376 {
377         int result = 0;
378         for(Track *current = first; current; current = NEXT)
379                 if(current->data_type == TRACK_AUDIO && current->is_armed()) result++;
380         return result;
381 }
382
383 int Tracks::recordable_video_tracks()
384 {
385         int result = 0;
386         for(Track *current = first; current; current = NEXT)
387         {
388                 if(current->data_type == TRACK_VIDEO && current->is_armed()) result++;
389         }
390         return result;
391 }
392
393
394 int Tracks::playable_audio_tracks()
395 {
396         int result = 0;
397
398         for(Track *current = first; current; current = NEXT)
399         {
400                 if(current->data_type == TRACK_AUDIO && current->play)
401                 {
402                         result++;
403                 }
404         }
405
406         return result;
407 }
408
409 int Tracks::playable_video_tracks()
410 {
411         int result = 0;
412
413         for(Track *current = first; current; current = NEXT)
414         {
415                 if(current->data_type == TRACK_VIDEO && current->play)
416                 {
417                         result++;
418                 }
419         }
420         return result;
421 }
422
423 int Tracks::total_audio_tracks()
424 {
425         int result = 0;
426         for(Track *current = first; current; current = NEXT)
427                 if(current->data_type == TRACK_AUDIO) result++;
428         return result;
429 }
430
431 int Tracks::total_video_tracks()
432 {
433         int result = 0;
434         for(Track *current = first; current; current = NEXT)
435                 if(current->data_type == TRACK_VIDEO) result++;
436         return result;
437 }
438
439 double Tracks::total_playable_length()
440 {
441         double total = 0;
442         for(Track *current = first; current; current = NEXT)
443         {
444                 if( current->play )
445                 {
446                         double length = current->get_length();
447                         if(length > total) total = length;
448                 }
449         }
450         return total;
451 }
452
453 double Tracks::total_recordable_length()
454 {
455         double total = -1;
456         for(Track *current = first; current; current = NEXT)
457         {
458                 if(current->is_armed())
459                 {
460                         double length = current->get_length();
461                         if(length > total) total = length;
462                 }
463         }
464         return total;
465 }
466
467 double Tracks::total_length()
468 {
469         double total = 0;
470         for(Track *current = first; current; current = NEXT)
471         {
472                 double length = current->get_length();
473                 if(length > total) total = length;
474         }
475         return total;
476 }
477
478 double Tracks::total_audio_length()
479 {
480         double total = 0;
481         for(Track *current = first; current; current = NEXT)
482         {
483                 if(current->data_type == TRACK_AUDIO &&
484                         current->get_length() > total) total = current->get_length();
485         }
486         return total;
487 }
488
489 double Tracks::total_video_length()
490 {
491         double total = 0;
492         for(Track *current = first; current; current = NEXT)
493         {
494                 if(current->data_type == TRACK_VIDEO &&
495                         current->get_length() > total) total = current->get_length();
496         }
497         return total;
498 }
499
500 double Tracks::total_length_framealigned(double fps)
501 {
502         if (total_audio_tracks() && total_video_tracks())
503                 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
504
505         if (total_audio_tracks())
506                 return floor(total_audio_length() * fps) / fps;
507
508         if (total_video_tracks())
509                 return floor(total_video_length() * fps) / fps;
510
511         return 0;
512 }
513
514 void Tracks::translate_fauto_xy(int fauto, float dx, float dy, int all)
515 {
516         Track *track = first;
517         for( ; track; track=track->next ) {
518                 if( !all && !track->is_armed() ) continue;
519                 if( track->data_type != TRACK_VIDEO ) continue;
520                 ((VTrack*)track)->translate(fauto, dx, dy, all);
521         }
522 }
523
524 void Tracks::translate_projector(float dx, float dy, int all)
525 {
526         translate_fauto_xy(AUTOMATION_PROJECTOR_X, dx, dy, all);
527 }
528
529 void Tracks::translate_camera(float dx, float dy, int all)
530 {
531         translate_fauto_xy(AUTOMATION_CAMERA_X, dx, dy, all);
532 }
533
534 void Tracks::crop_resize(float x, float y, float z)
535 {
536         float ctr_x = edl->session->output_w / 2.;
537         float ctr_y = edl->session->output_h / 2.;
538         Track *track = first;
539         for( ; track; track=track->next ) {
540                 if( !track->is_armed() ) continue;
541                 if( track->data_type != TRACK_VIDEO ) continue;
542                 float px, py, pz;
543                 track->get_projector(px, py, pz);
544                 float old_x = px + ctr_x;
545                 float old_y = py + ctr_y;
546                 float nx = (old_x - x) * z;
547                 float ny = (old_y - y) * z;
548                 track->set_projector(nx, ny, pz * z);
549         }
550 }
551
552 void Tracks::crop_shrink(float x, float y, float z)
553 {
554         float ctr_x = edl->session->output_w / 2.;
555         float ctr_y = edl->session->output_h / 2.;
556         Track *track = first;
557         for( ; track; track=track->next ) {
558                 if( !track->is_armed() ) continue;
559                 if( track->data_type != TRACK_VIDEO ) continue;
560                 float cx, cy, cz, px, py, pz;
561                 track->get_camera(cx, cy, cz);
562                 track->get_projector(px, py, pz);
563                 float dx = x - (px + ctr_x);
564                 float dy = y - (py + ctr_y);
565                 cz *= pz;
566                 cx += dx / cz;  cy += dy / cz;
567                 track->set_camera(cx, cy, cz * z);
568                 px += dx;  py += dy;
569                 track->set_projector(px, py, 1 / z);
570         }
571 }
572
573 void Tracks::update_y_pixels(Theme *theme)
574 {
575 //      int y = -edl->local_session->track_start;
576         int y = 0;
577         for(Track *current = first; current; current = NEXT)
578         {
579 //printf("Tracks::update_y_pixels %d\n", y);
580                 current->y_pixel = y;
581                 if( current->is_hidden() ) continue;
582                 y += current->vertical_span(theme);
583         }
584 }
585
586 int Tracks::dump(FILE *fp)
587 {
588         for(Track* current = first; current; current = NEXT)
589         {
590                 fprintf(fp,"  Track: %p\n", current);
591                 current->dump(fp);
592                 fprintf(fp,"\n");
593         }
594         return 0;
595 }
596
597 void Tracks::select_all(int type,
598                 int value)
599 {
600         for(Track* current = first; current; current = NEXT)
601         {
602                 double position = edl->local_session->get_selectionstart(1);
603
604                 if(type == PLAY) current->play = value;
605                 if(type == RECORD) current->armed = value;
606                 if(type == GANG) current->ganged = value;
607                 if(type == DRAW) current->draw = value;
608
609                 if(type == MUTE)
610                 {
611                         ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
612                 }
613
614                 if(type == EXPAND) current->expand_view = value;
615         }
616 }
617
618 // ===================================== file operations
619
620 int Tracks::popup_transition(int cursor_x, int cursor_y)
621 {
622         int result = 0;
623         for(Track* current = first; current && !result; current = NEXT)
624         {
625                 result = current->popup_transition(cursor_x, cursor_y);
626         }
627         return result;
628 }
629
630
631 int Tracks::change_channels(int oldchannels, int newchannels)
632 {
633         for(Track *current = first; current; current = NEXT)
634         { current->change_channels(oldchannels, newchannels); }
635         return 0;
636 }
637
638
639
640 int Tracks::totalpixels()
641 {
642         int result = 0;
643         for(Track* current = first; current; current = NEXT)
644         {
645                 result += current->data_h;
646         }
647         return result;
648 }
649
650 int Tracks::number_of(Track *track)
651 {
652         int i = 0;
653         for(Track *current = first; current && current != track; current = NEXT)
654         {
655                 i++;
656         }
657         return i;
658 }
659
660 Track* Tracks::number(int number)
661 {
662         Track *current;
663         int i = 0;
664         for(current = first; current && i < number; current = NEXT)
665         {
666                 i++;
667         }
668         return current;
669 }
670
671 Track* Tracks::get_track_by_id(int id)
672 {
673         Track *track = edl->tracks->first;
674         while( track && track->get_id() != id ) track = track->next;
675         return track;
676 }
677
678 int Tracks::total_playable_vtracks()
679 {
680         int result = 0;
681         for(Track *current = first; current; current = NEXT)
682         {
683                 if(current->data_type == TRACK_VIDEO && current->play) result++;
684         }
685         return result;
686 }
687
688 Plugin *Tracks::plugin_exists(int plugin_id)
689 {
690         if( plugin_id < 0 ) return 0;
691         Plugin *plugin = 0;
692         for( Track *track=first; !plugin && track; track=track->next ) {
693                 plugin = track->plugin_exists(plugin_id);
694         }
695         return plugin;
696 }
697
698 int Tracks::track_exists(Track *track)
699 {
700         for(Track *current = first; current; current = NEXT)
701         {
702                 if(current == track) return 1;
703         }
704         return 0;
705 }
706
707 int Tracks::new_group(int id)
708 {
709         int count = 0;
710         for( Track *track=first; track; track=track->next ) {
711                 if( !track->is_armed() ) continue;
712                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
713                         if( edit->group_id > 0 ) continue;
714                         if( !edit->is_selected ) continue;
715                         edit->group_id = id;
716                         ++count;
717                 }
718         }
719         return count;
720 }
721
722 int Tracks::set_group_selected(int id, int v)
723 {
724         int count = 0;
725         int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
726         for( Track *track=first; track; track=track->next ) {
727                 if( track->is_hidden() ) continue;
728                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
729                         if( edit->group_id != id ) continue;
730                         if( v < 0 ) v = !edit->is_selected ? 1 : 0;
731                         edit->select_affected_edits(v, gang);
732                         ++count;
733                 }
734         }
735         return count;
736 }
737
738 int Tracks::del_group(int id)
739 {
740         int count = 0;
741         for( Track *track=first; track; track=track->next ) {
742                 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
743                         if( edit->group_id != id ) continue;
744                         edit->is_selected = 1;
745                         edit->group_id = 0;
746                         ++count;
747                 }
748         }
749         return count;
750 }
751
752 Track *Tracks::get(int idx, int data_type)
753 {
754         for(Track *current = first; current; current = NEXT)
755         {
756                 if( current->data_type != data_type ) continue;
757                 if( --idx < 0 ) return current;
758         }
759         return 0;
760 }
761
762 void Tracks::move_tracks(Track *src, Track *dst, int n)
763 {
764         if( src == dst ) return;
765         while( --n >= 0 && src ) {
766                 Track *nxt = src->next;
767                 change_modules(number_of(src), total(), 0);
768                 for( Track *track=nxt; track; track=track->next )
769                         change_modules(number_of(track), number_of(track)-1, 0);
770                 remove_pointer(src);
771                 int ndst = dst ? number_of(dst) : total();
772                 insert_before(dst, src);
773                 for( Track *track=last; track && track!=src; track=track->previous ) 
774                         change_modules(number_of(track)-1, number_of(track), 0);
775                 change_modules(total(), ndst, 0);
776                 src = nxt;
777         }
778 }
779