rework histogram_bezier, init wm icon set_icon(gg), update de.po+msg/txt
[goodguy/history.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
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         int autogrouptype)
141 {
142         *min = 0;
143         *max = 0;
144         int coords_undefined = 1;
145         for(Track *current = first; current; current = NEXT)
146         {
147                 if(current->record)
148                 {
149                         current->automation->get_extents(min,
150                                 max,
151                                 &coords_undefined,
152                                 current->to_units(start, 0),
153                                 current->to_units(end, 1),
154                                 autogrouptype);
155                 }
156         }
157 }
158
159
160 void Tracks::copy_from(Tracks *tracks)
161 {
162         Track *new_track = 0;
163
164         delete_all_tracks();
165         for(Track *current = tracks->first; current; current = NEXT)
166         {
167                 switch(current->data_type)
168                 {
169                 case TRACK_AUDIO:
170                         new_track = add_audio_track(0, 0);
171                         break;
172                 case TRACK_VIDEO:
173                         new_track = add_video_track(0, 0);
174                         break;
175                 case TRACK_SUBTITLE:
176                         new_track = add_subttl_track(0, 0);
177                         break;
178                 default:
179                         continue;
180                 }
181                 new_track->copy_from(current);
182         }
183 }
184
185 Tracks& Tracks::operator=(Tracks &tracks)
186 {
187 printf("Tracks::operator= 1\n");
188         copy_from(&tracks);
189         return *this;
190 }
191
192 int Tracks::load(FileXML *xml,
193         int &track_offset,
194         uint32_t load_flags)
195 {
196 // add the appropriate type of track
197         char string[BCTEXTLEN];
198         Track *track = 0;
199         string[0] = 0;
200
201         xml->tag.get_property("TYPE", string);
202
203         if((load_flags & LOAD_ALL) == LOAD_ALL ||
204                 (load_flags & LOAD_EDITS)) {
205                 if(!strcmp(string, "VIDEO")) {
206                         track = add_video_track(0, 0);
207                 }
208                 else if(!strcmp(string, "SUBTTL")) {
209                         track = add_subttl_track(0, 0);
210                 }
211                 else {
212                         track = add_audio_track(0, 0);    // default to audio
213                 }
214         }
215         else {
216                 track = get_item_number(track_offset++);
217         }
218
219 // load it
220         if( track ) track->load(xml, track_offset, load_flags);
221
222         return 0;
223 }
224
225 Track* Tracks::add_audio_track(int above, Track *dst_track)
226 {
227         ATrack* new_track = new ATrack(edl, this);
228         if(!dst_track)
229         {
230                 dst_track = (above ? first : last);
231         }
232
233         if(above)
234         {
235                 insert_before(dst_track, (Track*)new_track);
236         }
237         else
238         {
239                 insert_after(dst_track, (Track*)new_track);
240 // Shift effects referenced below the destination track
241         }
242
243 // Shift effects referenced below the new track
244         for(Track *track = last;
245                 track && track != new_track;
246                 track = track->previous)
247         {
248                 change_modules(number_of(track) - 1, number_of(track), 0);
249         }
250
251
252         new_track->create_objects();
253         new_track->set_default_title();
254
255         int current_pan = 0;
256         for(Track *current = first;
257                 current != (Track*)new_track;
258                 current = NEXT)
259         {
260                 if(current->data_type == TRACK_AUDIO) current_pan++;
261                 if(current_pan >= edl->session->audio_channels) current_pan = 0;
262         }
263
264
265
266         PanAuto* pan_auto =
267                 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
268         pan_auto->values[current_pan] = 1.0;
269
270         BC_Pan::calculate_stick_position(edl->session->audio_channels,
271                 edl->session->achannel_positions,
272                 pan_auto->values,
273                 MAX_PAN,
274                 PAN_RADIUS,
275                 pan_auto->handle_x,
276                 pan_auto->handle_y);
277         return new_track;
278 }
279
280 Track* Tracks::add_video_track(int above, Track *dst_track)
281 {
282         VTrack* new_track = new VTrack(edl, this);
283         if(!dst_track)
284                 dst_track = (above ? first : last);
285         if(above)
286                 insert_before(dst_track, (Track*)new_track);
287         else
288                 insert_after(dst_track, (Track*)new_track);
289
290         for(Track *track = last; track && track != new_track; track = track->previous)
291                 change_modules(number_of(track) - 1, number_of(track), 0);
292
293         new_track->create_objects();
294         new_track->set_default_title();
295         return new_track;
296 }
297
298
299 Track* Tracks::add_subttl_track(int above, Track *dst_track)
300 {
301         STrack* new_track = new STrack(edl, this);
302         if(!dst_track)
303                 dst_track = (above ? first : last);
304
305         if(above)
306                 insert_before(dst_track, (Track*)new_track);
307         else
308                 insert_after(dst_track, (Track*)new_track);
309
310         for(Track *track = last; track && track != new_track; track = track->previous)
311                 change_modules(number_of(track) - 1, number_of(track), 0);
312
313         new_track->create_objects();
314         new_track->set_default_title();
315 //      new_track->paste_silence(0,total_length(),0);
316         return new_track;
317 }
318
319
320 int Tracks::delete_track(Track *track)
321 {
322         if (!track)
323                 return 0;
324
325         int old_location = number_of(track);
326         detach_shared_effects(old_location);
327
328 // Shift effects referencing effects below the deleted track
329         for(Track *current = track;
330                 current;
331                 current = NEXT)
332         {
333                 change_modules(number_of(current), number_of(current) - 1, 0);
334         }
335         if(track) delete track;
336
337         return 0;
338 }
339
340 int Tracks::detach_shared_effects(int module)
341 {
342         for(Track *current = first; current; current = NEXT)
343         {
344                 current->detach_shared_effects(module);
345         }
346
347         return 0;
348  }
349
350 int Tracks::total_of(int type)
351 {
352         int result = 0;
353
354         for(Track *current = first; current; current = NEXT)
355         {
356                 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
357                 Auto *mute_keyframe = 0;
358                 current->automation->autos[AUTOMATION_MUTE]->
359                         get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
360                 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
361
362                 result +=
363                         (current->play && type == PLAY) ||
364                         (current->record && type == RECORD) ||
365                         (current->gang && type == GANG) ||
366                         (current->draw && type == DRAW) ||
367                         (mute_auto->value && type == MUTE) ||
368                         (current->expand_view && type == EXPAND);
369         }
370         return result;
371 }
372
373 int Tracks::recordable_audio_tracks()
374 {
375         int result = 0;
376         for(Track *current = first; current; current = NEXT)
377                 if(current->data_type == TRACK_AUDIO && current->record) result++;
378         return result;
379 }
380
381 int Tracks::recordable_video_tracks()
382 {
383         int result = 0;
384         for(Track *current = first; current; current = NEXT)
385         {
386                 if(current->data_type == TRACK_VIDEO && current->record) result++;
387         }
388         return result;
389 }
390
391
392 int Tracks::playable_audio_tracks()
393 {
394         int result = 0;
395
396         for(Track *current = first; current; current = NEXT)
397         {
398                 if(current->data_type == TRACK_AUDIO && current->play)
399                 {
400                         result++;
401                 }
402         }
403
404         return result;
405 }
406
407 int Tracks::playable_video_tracks()
408 {
409         int result = 0;
410
411         for(Track *current = first; current; current = NEXT)
412         {
413                 if(current->data_type == TRACK_VIDEO && current->play)
414                 {
415                         result++;
416                 }
417         }
418         return result;
419 }
420
421 int Tracks::total_audio_tracks()
422 {
423         int result = 0;
424         for(Track *current = first; current; current = NEXT)
425                 if(current->data_type == TRACK_AUDIO) result++;
426         return result;
427 }
428
429 int Tracks::total_video_tracks()
430 {
431         int result = 0;
432         for(Track *current = first; current; current = NEXT)
433                 if(current->data_type == TRACK_VIDEO) result++;
434         return result;
435 }
436
437 double Tracks::total_playable_length()
438 {
439         double total = 0;
440         for(Track *current = first; current; current = NEXT)
441         {
442                 if( current->play )
443                 {
444                         double length = current->get_length();
445                         if(length > total) total = length;
446                 }
447         }
448         return total;
449 }
450
451 double Tracks::total_recordable_length()
452 {
453         double total = -1;
454         for(Track *current = first; current; current = NEXT)
455         {
456                 if(current->record)
457                 {
458                         double length = current->get_length();
459                         if(length > total) total = length;
460                 }
461         }
462         return total;
463 }
464
465 double Tracks::total_length()
466 {
467         double total = 0;
468         for(Track *current = first; current; current = NEXT)
469         {
470                 double length = current->get_length();
471                 if(length > total) total = length;
472         }
473         return total;
474 }
475
476 double Tracks::total_audio_length()
477 {
478         double total = 0;
479         for(Track *current = first; current; current = NEXT)
480         {
481                 if(current->data_type == TRACK_AUDIO &&
482                         current->get_length() > total) total = current->get_length();
483         }
484         return total;
485 }
486
487 double Tracks::total_video_length()
488 {
489         double total = 0;
490         for(Track *current = first; current; current = NEXT)
491         {
492                 if(current->data_type == TRACK_VIDEO &&
493                         current->get_length() > total) total = current->get_length();
494         }
495         return total;
496 }
497
498 double Tracks::total_length_framealigned(double fps)
499 {
500         if (total_audio_tracks() && total_video_tracks())
501                 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
502
503         if (total_audio_tracks())
504                 return floor(total_audio_length() * fps) / fps;
505
506         if (total_video_tracks())
507                 return floor(total_video_length() * fps) / fps;
508
509         return 0;
510 }
511
512 void Tracks::translate_projector(float offset_x, float offset_y)
513 {
514         for(Track *current = first; current; current = NEXT)
515         {
516                 if(current->data_type == TRACK_VIDEO)
517                 {
518                         ((VTrack*)current)->translate(offset_x, offset_y, 0);
519                 }
520         }
521 }
522
523 void Tracks::update_y_pixels(Theme *theme)
524 {
525 //      int y = -edl->local_session->track_start;
526         int y = 0;
527         for(Track *current = first; current; current = NEXT)
528         {
529 //printf("Tracks::update_y_pixels %d\n", y);
530                 current->y_pixel = y;
531                 y += current->vertical_span(theme);
532         }
533 }
534
535 int Tracks::dump(FILE *fp)
536 {
537         for(Track* current = first; current; current = NEXT)
538         {
539                 fprintf(fp,"  Track: %p\n", current);
540                 current->dump(fp);
541                 fprintf(fp,"\n");
542         }
543         return 0;
544 }
545
546 void Tracks::select_all(int type,
547                 int value)
548 {
549         for(Track* current = first; current; current = NEXT)
550         {
551                 double position = edl->local_session->get_selectionstart(1);
552
553                 if(type == PLAY) current->play = value;
554                 if(type == RECORD) current->record = value;
555                 if(type == GANG) current->gang = value;
556                 if(type == DRAW) current->draw = value;
557
558                 if(type == MUTE)
559                 {
560                         ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
561                 }
562
563                 if(type == EXPAND) current->expand_view = value;
564         }
565 }
566
567 // ===================================== file operations
568
569 int Tracks::popup_transition(int cursor_x, int cursor_y)
570 {
571         int result = 0;
572         for(Track* current = first; current && !result; current = NEXT)
573         {
574                 result = current->popup_transition(cursor_x, cursor_y);
575         }
576         return result;
577 }
578
579
580 int Tracks::change_channels(int oldchannels, int newchannels)
581 {
582         for(Track *current = first; current; current = NEXT)
583         { current->change_channels(oldchannels, newchannels); }
584         return 0;
585 }
586
587
588
589 int Tracks::totalpixels()
590 {
591         int result = 0;
592         for(Track* current = first; current; current = NEXT)
593         {
594                 result += edl->local_session->zoom_track;
595         }
596         return result;
597 }
598
599 int Tracks::number_of(Track *track)
600 {
601         int i = 0;
602         for(Track *current = first; current && current != track; current = NEXT)
603         {
604                 i++;
605         }
606         return i;
607 }
608
609 Track* Tracks::number(int number)
610 {
611         Track *current;
612         int i = 0;
613         for(current = first; current && i < number; current = NEXT)
614         {
615                 i++;
616         }
617         return current;
618 }
619
620
621 int Tracks::total_playable_vtracks()
622 {
623         int result = 0;
624         for(Track *current = first; current; current = NEXT)
625         {
626                 if(current->data_type == TRACK_VIDEO && current->play) result++;
627         }
628         return result;
629 }
630
631 int Tracks::plugin_exists(Plugin *plugin)
632 {
633         for(Track *track = first; track; track = track->next)
634         {
635                 if(track->plugin_exists(plugin)) return 1;
636         }
637         return 0;
638 }
639
640 int Tracks::track_exists(Track *track)
641 {
642         for(Track *current = first; current; current = NEXT)
643         {
644                 if(current == track) return 1;
645         }
646         return 0;
647 }
648
649
650 Track *Tracks::get(int idx, int data_type)
651 {
652         for(Track *current = first; current; current = NEXT)
653         {
654                 if( current->data_type != data_type ) continue;
655                 if( --idx < 0 ) return current;
656         }
657         return 0;
658 }
659
660