3 * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "automation.h"
28 #include "edlsession.h"
33 #include "localsession.h"
38 #include "mainsession.h"
42 #include "trackcanvas.h"
44 #include "transportque.inc"
48 Tracks::Tracks(EDL *edl)
69 void Tracks::equivalent_output(Tracks *tracks, double *result)
71 if(total_playable_vtracks() != tracks->total_playable_vtracks())
77 Track *current = first;
78 Track *that_current = tracks->first;
79 while(current || that_current)
81 // Get next video track
82 while(current && current->data_type != TRACK_VIDEO)
85 while(that_current && that_current->data_type != TRACK_VIDEO)
86 that_current = that_current->next;
88 // One doesn't exist but the other does
89 if((!current && that_current) ||
90 (current && !that_current))
97 if(current && that_current)
99 current->equivalent_output(that_current, result);
101 that_current = that_current->next;
108 void Tracks::clear_selected_edits()
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;
116 void Tracks::select_affected_edits(double position, Track *start_track, int sense)
118 for( Track *track=start_track; track; track=track->next ) {
119 if( !track->record ) continue;
120 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
121 if( edit->silence() ) continue;
122 double startproject = track->from_units(edit->startproject);
123 if( edl->equivalent(startproject, position) ) {
124 edit->is_selected = sense >= 0 ? sense :
125 edit->is_selected ? 0 : 1;
132 void Tracks::get_selected_edits(ArrayList<Edit*> *drag_edits)
134 drag_edits->remove_all();
135 for( Track *track=first; track; track=track->next ) {
136 if( !track->record ) continue;
137 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
138 if( !edit->is_selected ) continue;
139 drag_edits->append(edit);
144 void Tracks::get_automation_extents(float *min,
152 int coords_undefined = 1;
153 for(Track *current = first; current; current = NEXT)
157 current->automation->get_extents(min,
160 current->to_units(start, 0),
161 current->to_units(end, 1),
168 void Tracks::copy_from(Tracks *tracks)
170 Track *new_track = 0;
173 int solo_track_id = tracks->edl->local_session->solo_track_id;
175 for(Track *current = tracks->first; current; current = NEXT)
177 switch(current->data_type)
180 new_track = add_audio_track(0, 0);
183 new_track = add_video_track(0, 0);
186 new_track = add_subttl_track(0, 0);
191 new_track->copy_from(current);
193 if( current->get_id() == solo_track_id )
194 edl->local_session->solo_track_id = new_track->get_id();
198 Tracks& Tracks::operator=(Tracks &tracks)
200 printf("Tracks::operator= 1\n");
205 int Tracks::load(FileXML *xml,
209 // add the appropriate type of track
210 char string[BCTEXTLEN];
214 xml->tag.get_property("TYPE", string);
216 if((load_flags & LOAD_ALL) == LOAD_ALL ||
217 (load_flags & LOAD_EDITS)) {
218 if(!strcmp(string, "VIDEO")) {
219 track = add_video_track(0, 0);
221 else if(!strcmp(string, "SUBTTL")) {
222 track = add_subttl_track(0, 0);
225 track = add_audio_track(0, 0); // default to audio
229 track = get_item_number(track_offset++);
233 if( track ) track->load(xml, track_offset, load_flags);
238 Track* Tracks::add_audio_track(int above, Track *dst_track)
240 ATrack* new_track = new ATrack(edl, this);
243 dst_track = (above ? first : last);
248 insert_before(dst_track, (Track*)new_track);
252 insert_after(dst_track, (Track*)new_track);
253 // Shift effects referenced below the destination track
256 // Shift effects referenced below the new track
257 for(Track *track = last;
258 track && track != new_track;
259 track = track->previous)
261 change_modules(number_of(track) - 1, number_of(track), 0);
265 new_track->create_objects();
266 new_track->set_default_title();
269 for(Track *current = first;
270 current != (Track*)new_track;
273 if(current->data_type == TRACK_AUDIO) current_pan++;
274 if(current_pan >= edl->session->audio_channels) current_pan = 0;
280 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
281 pan_auto->values[current_pan] = 1.0;
283 BC_Pan::calculate_stick_position(edl->session->audio_channels,
284 edl->session->achannel_positions,
293 Track* Tracks::add_video_track(int above, Track *dst_track)
295 VTrack* new_track = new VTrack(edl, this);
297 dst_track = (above ? first : last);
299 insert_before(dst_track, (Track*)new_track);
301 insert_after(dst_track, (Track*)new_track);
303 for(Track *track = last; track && track != new_track; track = track->previous)
304 change_modules(number_of(track) - 1, number_of(track), 0);
306 new_track->create_objects();
307 new_track->set_default_title();
312 Track* Tracks::add_subttl_track(int above, Track *dst_track)
314 STrack* new_track = new STrack(edl, this);
316 dst_track = (above ? first : last);
319 insert_before(dst_track, (Track*)new_track);
321 insert_after(dst_track, (Track*)new_track);
323 for(Track *track = last; track && track != new_track; track = track->previous)
324 change_modules(number_of(track) - 1, number_of(track), 0);
326 new_track->create_objects();
327 new_track->set_default_title();
328 // new_track->paste_silence(0,total_length(),0);
333 int Tracks::delete_track(Track *track)
338 int old_location = number_of(track);
339 detach_shared_effects(old_location);
341 // Shift effects referencing effects below the deleted track
342 for(Track *current = track;
346 change_modules(number_of(current), number_of(current) - 1, 0);
348 if(track) delete track;
353 int Tracks::detach_shared_effects(int module)
355 for(Track *current = first; current; current = NEXT)
357 current->detach_shared_effects(module);
363 int Tracks::total_of(int type)
367 for(Track *current = first; current; current = NEXT)
369 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
370 Auto *mute_keyframe = 0;
371 current->automation->autos[AUTOMATION_MUTE]->
372 get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
373 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
376 (current->play && type == PLAY) ||
377 (current->record && type == RECORD) ||
378 (current->gang && type == GANG) ||
379 (current->draw && type == DRAW) ||
380 (mute_auto->value && type == MUTE) ||
381 (current->expand_view && type == EXPAND);
386 int Tracks::recordable_audio_tracks()
389 for(Track *current = first; current; current = NEXT)
390 if(current->data_type == TRACK_AUDIO && current->record) result++;
394 int Tracks::recordable_video_tracks()
397 for(Track *current = first; current; current = NEXT)
399 if(current->data_type == TRACK_VIDEO && current->record) result++;
405 int Tracks::playable_audio_tracks()
409 for(Track *current = first; current; current = NEXT)
411 if(current->data_type == TRACK_AUDIO && current->play)
420 int Tracks::playable_video_tracks()
424 for(Track *current = first; current; current = NEXT)
426 if(current->data_type == TRACK_VIDEO && current->play)
434 int Tracks::total_audio_tracks()
437 for(Track *current = first; current; current = NEXT)
438 if(current->data_type == TRACK_AUDIO) result++;
442 int Tracks::total_video_tracks()
445 for(Track *current = first; current; current = NEXT)
446 if(current->data_type == TRACK_VIDEO) result++;
450 double Tracks::total_playable_length()
453 for(Track *current = first; current; current = NEXT)
457 double length = current->get_length();
458 if(length > total) total = length;
464 double Tracks::total_recordable_length()
467 for(Track *current = first; current; current = NEXT)
471 double length = current->get_length();
472 if(length > total) total = length;
478 double Tracks::total_length()
481 for(Track *current = first; current; current = NEXT)
483 double length = current->get_length();
484 if(length > total) total = length;
489 double Tracks::total_audio_length()
492 for(Track *current = first; current; current = NEXT)
494 if(current->data_type == TRACK_AUDIO &&
495 current->get_length() > total) total = current->get_length();
500 double Tracks::total_video_length()
503 for(Track *current = first; current; current = NEXT)
505 if(current->data_type == TRACK_VIDEO &&
506 current->get_length() > total) total = current->get_length();
511 double Tracks::total_length_framealigned(double fps)
513 if (total_audio_tracks() && total_video_tracks())
514 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
516 if (total_audio_tracks())
517 return floor(total_audio_length() * fps) / fps;
519 if (total_video_tracks())
520 return floor(total_video_length() * fps) / fps;
525 void Tracks::translate_projector(float offset_x, float offset_y)
527 for(Track *current = first; current; current = NEXT)
529 if(current->data_type == TRACK_VIDEO)
531 ((VTrack*)current)->translate(offset_x, offset_y, 0);
536 void Tracks::update_y_pixels(Theme *theme)
538 // int y = -edl->local_session->track_start;
540 for(Track *current = first; current; current = NEXT)
542 //printf("Tracks::update_y_pixels %d\n", y);
543 current->y_pixel = y;
544 y += current->vertical_span(theme);
548 int Tracks::dump(FILE *fp)
550 for(Track* current = first; current; current = NEXT)
552 fprintf(fp," Track: %p\n", current);
559 void Tracks::select_all(int type,
562 for(Track* current = first; current; current = NEXT)
564 double position = edl->local_session->get_selectionstart(1);
566 if(type == PLAY) current->play = value;
567 if(type == RECORD) current->record = value;
568 if(type == GANG) current->gang = value;
569 if(type == DRAW) current->draw = value;
573 ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
576 if(type == EXPAND) current->expand_view = value;
580 // ===================================== file operations
582 int Tracks::popup_transition(int cursor_x, int cursor_y)
585 for(Track* current = first; current && !result; current = NEXT)
587 result = current->popup_transition(cursor_x, cursor_y);
593 int Tracks::change_channels(int oldchannels, int newchannels)
595 for(Track *current = first; current; current = NEXT)
596 { current->change_channels(oldchannels, newchannels); }
602 int Tracks::totalpixels()
605 for(Track* current = first; current; current = NEXT)
607 result += edl->local_session->zoom_track;
612 int Tracks::number_of(Track *track)
615 for(Track *current = first; current && current != track; current = NEXT)
622 Track* Tracks::number(int number)
626 for(current = first; current && i < number; current = NEXT)
633 Track* Tracks::get_track_by_id(int id)
635 Track *track = edl->tracks->first;
636 while( track && track->get_id() != id ) track = track->next;
640 int Tracks::total_playable_vtracks()
643 for(Track *current = first; current; current = NEXT)
645 if(current->data_type == TRACK_VIDEO && current->play) result++;
650 int Tracks::plugin_exists(Plugin *plugin)
652 for(Track *track = first; track; track = track->next)
654 if(track->plugin_exists(plugin)) return 1;
659 int Tracks::track_exists(Track *track)
661 for(Track *current = first; current; current = NEXT)
663 if(current == track) return 1;
668 int Tracks::new_group(int id)
671 for( Track *track=first; track; track=track->next ) {
672 if( !track->record ) continue;
673 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
674 if( edit->group_id > 0 ) continue;
675 if( !edit->is_selected ) continue;
683 int Tracks::set_group_selected(int id, int v)
686 for( Track *track=first; track; track=track->next ) {
687 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
688 if( edit->group_id != id ) continue;
689 edit->is_selected = v >= 0 ? v : !edit->is_selected ? 1 : 0;
696 int Tracks::del_group(int id)
699 for( Track *track=first; track; track=track->next ) {
700 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
701 if( edit->group_id != id ) continue;
702 edit->is_selected = 1;
710 Track *Tracks::get(int idx, int data_type)
712 for(Track *current = first; current; current = NEXT)
714 if( current->data_type != data_type ) continue;
715 if( --idx < 0 ) return current;