r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / tracks.C
blobaaf7af7c32068f41ca9e26f6494ab5e6de03e502
1 #include "atrack.h"
2 #include "automation.h"
3 #include "cursor.h"
4 #include "defaults.h"
5 #include "edit.h"
6 #include "edits.h"
7 #include "edl.h"
8 #include "edlsession.h"
9 #include "file.h"
10 #include "filexml.h"
11 #include "intauto.h"
12 #include "intautos.h"
13 #include "localsession.h"
14 #include "module.h"
15 #include "panauto.h"
16 #include "panautos.h"
17 #include "patchbay.h"
18 #include "mainsession.h"
19 #include "theme.h"
20 #include "track.h"
21 #include "trackcanvas.h"
22 #include "tracks.h"
23 #include "transportque.inc"
24 #include "vtrack.h"
25 #include <string.h>
27 Tracks::Tracks(EDL *edl)
28  : List<Track>()
30         this->edl = edl;
33 Tracks::Tracks()
34  : List<Track>()
39 Tracks::~Tracks()
41         delete_all_tracks();
49 void Tracks::equivalent_output(Tracks *tracks, double *result)
51         if(total_playable_vtracks() != tracks->total_playable_vtracks())
52         {
53                 *result = 0;
54         }
55         else
56         {
57                 Track *current = first;
58                 Track *that_current = tracks->first;
59                 while(current || that_current)
60                 {
61 // Get next video track
62                         while(current && current->data_type != TRACK_VIDEO)
63                                 current = NEXT;
65                         while(that_current && that_current->data_type != TRACK_VIDEO)
66                                 that_current = that_current->next;
68 // One doesn't exist but the other does
69                         if((!current && that_current) ||
70                                 (current && !that_current))
71                         {
72                                 *result = 0;
73                                 break;
74                         }
75                         else
76 // Both exist
77                         if(current && that_current)
78                         {
79                                 current->equivalent_output(that_current, result);
80                                 current = NEXT;
81                                 that_current = that_current->next;
82                         }
83                 }
84         }
90 void Tracks::get_affected_edits(ArrayList<Edit*> *drag_edits, double position, Track *start_track)
92         drag_edits->remove_all();
94         for(Track *track = start_track;
95                 track;
96                 track = track->next)
97         {
98 //printf("Tracks::get_affected_edits 1 %p %d %d\n", track, track->data_type, track->record);
99                 if(track->record)
100                 {
101                         for(Edit *edit = track->edits->first; edit; edit = edit->next)
102                         {
103                                 double startproject = track->from_units(edit->startproject);
104 //printf("Tracks::get_affected_edits 1 %d\n", edl->equivalent(startproject, position));
105                                 if(edl->equivalent(startproject, position))
106                                 {
107                                         drag_edits->append(edit);
108                                         break;
109                                 }
110                         }
111                 }
112         }
118 Tracks& Tracks::operator=(Tracks &tracks)
120         Track *new_track;
121         delete_all_tracks();
122         for(Track *current = tracks.first; current; current = NEXT)
123         {
124                 switch(current->data_type)
125                 {
126                         case TRACK_AUDIO: 
127                                 new_track = add_audio_track(0, 0); 
128                                 break;
129                         case TRACK_VIDEO: 
130                                 new_track = add_video_track(0, 0); 
131                                 break;
132                 }
133                 *new_track = *current;
134         }
135         return *this;
138 int Tracks::load(FileXML *xml, int &track_offset, uint32_t load_flags)
140 // add the appropriate type of track
141         char string[BCTEXTLEN];
142         Track *track = 0;
143         sprintf(string, "");
144         
145         xml->tag.get_property("TYPE", string);
147         if((load_flags & LOAD_ALL) == LOAD_ALL ||
148                 (load_flags & LOAD_EDITS))
149         {
150                 if(!strcmp(string, "VIDEO"))
151                 {
152                         add_video_track(0, 0);
153                 }
154                 else
155                 {
156                         add_audio_track(0, 0);    // default to audio
157                 }
158                 track = last;
159         }
160         else
161         {
162                 track = get_item_number(track_offset);
163                 track_offset++;
164         }
166 // load it
167         if(track) track->load(xml, track_offset, load_flags);
169         return 0;
172 Track* Tracks::add_audio_track(int above, Track *dst_track)
174         int pixel;
175         ATrack* new_track = new ATrack(edl, this);
176         if(!dst_track)
177         {
178                 dst_track = (above ? first : last);
179         }
181         if(above)
182         {
183                 insert_before(dst_track, (Track*)new_track);
184         }
185         else
186         {
187                 insert_after(dst_track, (Track*)new_track);
188 // Shift effects referenced below the destination track
189         }
191 // Shift effects referenced below the new track
192         for(Track *track = last; 
193                 track && track != new_track; 
194                 track = track->previous)
195         {
196                 change_modules(number_of(track) - 1, number_of(track), 0);
197         }
200         new_track->create_objects();
201         new_track->set_default_title();
203         int current_pan = 0;
204         for(Track *current = first; 
205                 current != (Track*)new_track; 
206                 current = NEXT)
207         {
208                 if(current->data_type == TRACK_AUDIO) current_pan++;
209                 if(current_pan >= edl->session->audio_channels) current_pan = 0;
210         }
214         PanAuto* pan_auto = (PanAuto*)new_track->automation->pan_autos->default_auto;
215         pan_auto->values[current_pan] = 1.0;
217         BC_Pan::calculate_stick_position(edl->session->audio_channels, 
218                 edl->session->achannel_positions, 
219                 pan_auto->values, 
220                 1, 
221                 50,
222                 pan_auto->handle_x,
223                 pan_auto->handle_y);
224         return new_track;
227 Track* Tracks::add_video_track(int above, Track *dst_track)
229         int pixel;
230         VTrack* new_track = new VTrack(edl, this);
231         if(!dst_track)
232                 dst_track = (above ? first : last);
234         if(above)
235         {
236                 insert_before(dst_track, (Track*)new_track);
237         }
238         else
239         {
240                 insert_after(dst_track, (Track*)new_track);
241         }
245 // Shift effects referenced below the new track
246         for(Track *track = last; 
247                 track && track != new_track; 
248                 track = track->previous)
249         {
250                 change_modules(number_of(track) - 1, number_of(track), 0);
251         }
255         new_track->create_objects();
256         new_track->set_default_title();
257         return new_track;
261 int Tracks::delete_track()
263         delete_track(last);
264         return 0;
267 int Tracks::delete_track(Track *track)
269         int old_location = number_of(track);
270 // Shift effects referenced below the deleted track
271         for(Track *current = last; 
272                 current && current != track; 
273                 current = PREVIOUS)
274         {
275                 change_modules(number_of(current), number_of(current) - 1, 0);
276         }
277         if(track) delete track;
279         return 0;
282 int Tracks::total_of(int type)
284         int result = 0;
285         IntAuto *mute_keyframe = 0;
286         
287         for(Track *current = first; current; current = NEXT)
288         {
289                 long unit_start = current->to_units(edl->local_session->selectionstart, 0);
290                 mute_keyframe = (IntAuto*)current->automation->mute_autos->get_prev_auto(
291                         unit_start, 
292                         PLAY_FORWARD,
293                         (Auto*)mute_keyframe);
295                 result += 
296                         (current->play && type == PLAY) ||
297                         (current->record && type == RECORD) ||
298                         (current->gang && type == GANG) ||
299                         (current->draw && type == DRAW) ||
300                         (mute_keyframe->value && type == MUTE) ||
301                         (current->expand_view && type == EXPAND);
302         }
303         return result;
306 int Tracks::recordable_audio_tracks()
308         int result = 0;
309         for(Track *current = first; current; current = NEXT)
310                 if(current->data_type == TRACK_AUDIO && current->record) result++;
311         return result;
314 int Tracks::recordable_video_tracks()
316         int result = 0;
317         for(Track *current = first; current; current = NEXT)
318         {
319                 if(current->data_type == TRACK_VIDEO && current->record) result++;
320         }
321         return result;
325 int Tracks::playable_audio_tracks()
327         int result = 0;
329         for(Track *current = first; current; current = NEXT)
330         {
331                 if(current->data_type == TRACK_AUDIO && current->play)
332                 {
333                         result++;
334                 }
335         }
337         return result;
340 int Tracks::playable_video_tracks()
342         int result = 0;
344         for(Track *current = first; current; current = NEXT)
345         {
346                 if(current->data_type == TRACK_VIDEO && current->play)
347                 {
348                         result++;
349                 }
350         }
351         return result;
354 int Tracks::total_audio_tracks()
356         int result = 0;
357         for(Track *current = first; current; current = NEXT)
358                 if(current->data_type == TRACK_AUDIO) result++;
359         return result;
362 int Tracks::total_video_tracks()
364         int result = 0;
365         for(Track *current = first; current; current = NEXT)
366                 if(current->data_type == TRACK_VIDEO) result++;
367         return result;
370 double Tracks::total_playable_length() 
372         double total = 0;
373         for(Track *current = first; current; current = NEXT)
374         {
375                 double length = current->get_length();
376                 if(length > total) total = length;
377         }
378         return total; 
381 double Tracks::total_recordable_length() 
383         double total = 0;
384         for(Track *current = first; current; current = NEXT)
385         {
386                 if(current->record)
387                 {
388                         double length = current->get_length();
389                         if(length > total) total = length;
390                 }
391         }
392         return total; 
395 double Tracks::total_length() 
397         double total = 0;
398         for(Track *current = first; current; current = NEXT)
399         {
400                 if(current->get_length() > total) total = current->get_length();
401         }
402         return total; 
405 double Tracks::total_video_length() 
407         double total = 0;
408         for(Track *current = first; current; current = NEXT)
409         {
410                 if(current->data_type == TRACK_VIDEO &&
411                         current->get_length() > total) total = current->get_length();
412         }
413         return total; 
417 void Tracks::translate_camera(float offset_x, float offset_y)
419         for(Track *current = first; current; current = NEXT)
420         {
421                 if(current->data_type == TRACK_VIDEO)
422                 {
423                         ((VTrack*)current)->translate_camera(offset_x, offset_y);
424                 }
425         }
427 void Tracks::translate_projector(float offset_x, float offset_y)
429         for(Track *current = first; current; current = NEXT)
430         {
431                 if(current->data_type == TRACK_VIDEO)
432                 {
433                         ((VTrack*)current)->translate_projector(offset_x, offset_y);
434                 }
435         }
438 void Tracks::update_y_pixels(Theme *theme)
440         int y = -edl->local_session->track_start;
441         for(Track *current = first; current; current = NEXT)
442         {
443 //printf("Tracks::update_y_pixels %d\n", y);
444                 current->y_pixel = y;
445                 y += current->vertical_span(theme);
446         }
449 int Tracks::dump()
451         for(Track* current = first; current; current = NEXT)
452         {
453                 printf("  Track: %x\n", current);
454                 current->dump();
455                 printf("\n");
456         }
457         return 0;
460 void Tracks::select_all(int type,
461                 int value)
463         for(Track* current = first; current; current = NEXT)
464         {
465                 double position = edl->local_session->selectionstart;
467                 if(type == PLAY) current->play = value;
468                 if(type == RECORD) current->record = value;
469                 if(type == GANG) current->gang = value;
470                 if(type == DRAW) current->draw = value;
471                 
472                 if(type == MUTE)
473                 {
474                         ((IntAuto*)current->automation->mute_autos->get_auto_for_editing(position))->value = value;
475                 }
477                 if(type == EXPAND) current->expand_view = value;
478         }
522 // ===================================== file operations
524 int Tracks::popup_transition(int cursor_x, int cursor_y)
526         int result = 0;
527         for(Track* current = first; current && !result; current = NEXT)
528         {
529                 result = current->popup_transition(cursor_x, cursor_y);
530         }
531         return result;
535 int Tracks::change_channels(int oldchannels, int newchannels)
537         for(Track *current = first; current; current = NEXT)
538         { current->change_channels(oldchannels, newchannels); }
539         return 0;
544 int Tracks::totalpixels()
546         int result = 0;
547         for(Track* current = first; current; current = NEXT)
548         {
549                 result += edl->local_session->zoom_track;
550         }
551         return result;
554 int Tracks::number_of(Track *track)
556         int i = 0;
557         for(Track *current = first; current && current != track; current = NEXT)
558         {
559                 i++;
560         }
561         return i;
564 Track* Tracks::number(int number)
566         Track *current;
567         int i = 0;
568         for(current = first; current && i < number; current = NEXT)
569         {
570                 i++;
571         }
572         return current;
576 int Tracks::total_playable_vtracks()
578         int result = 0;
579         for(Track *current = first; current; current = NEXT)
580         {
581                 if(current->data_type == TRACK_VIDEO && current->play) result++;
582         }
583         return result;