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"
39 #include "mainsession.h"
43 #include "trackcanvas.h"
45 #include "transportque.inc"
49 Tracks::Tracks(EDL *edl)
70 void Tracks::equivalent_output(Tracks *tracks, double *result)
72 if(total_playable_vtracks() != tracks->total_playable_vtracks())
78 Track *current = first;
79 Track *that_current = tracks->first;
80 while(current || that_current)
82 // Get next video track
83 while(current && current->data_type != TRACK_VIDEO)
86 while(that_current && that_current->data_type != TRACK_VIDEO)
87 that_current = that_current->next;
89 // One doesn't exist but the other does
90 if((!current && that_current) ||
91 (current && !that_current))
98 if(current && that_current)
100 current->equivalent_output(that_current, result);
102 that_current = that_current->next;
109 void Tracks::clear_selected_edits()
111 for( Track *track=first; track; track=track->next ) {
112 for( Edit *edit=track->edits->first; edit; edit=edit->next )
113 edit->is_selected = 0;
117 void Tracks::get_selected_edits(ArrayList<Edit*> *drag_edits)
119 drag_edits->remove_all();
120 for( Track *track=first; track; track=track->next ) {
121 if( !track->is_armed() ) continue;
122 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
123 if( !edit->is_selected ) continue;
124 drag_edits->append(edit);
129 void Tracks::select_edits(double start, double end, int v)
131 for( Track *track=first; track; track=track->next ) {
132 if( !track->is_armed() ) continue;
133 int64_t start_pos = track->to_units(start, 0);
134 int64_t end_pos = track->to_units(end, 0);
135 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
136 if( start_pos >= edit->startproject+edit->length ) continue;
137 if( edit->startproject >= end_pos ) continue;
138 edit->is_selected = v > 1 ? 1 : v < 0 ? 0 : !edit->is_selected ;
143 void Tracks::get_automation_extents(float *min,
151 int coords_undefined = 1;
152 for(Track *current = first; current; current = NEXT)
154 if(current->is_armed())
156 current->automation->get_extents(min,
159 current->to_units(start, 0),
160 current->to_units(end, 1),
167 void Tracks::copy_from(Tracks *tracks)
169 Track *new_track = 0;
172 int solo_track_id = tracks->edl->local_session->solo_track_id;
174 for(Track *current = tracks->first; current; current = NEXT)
176 switch(current->data_type)
179 new_track = add_audio_track(0, 0);
182 new_track = add_video_track(0, 0);
185 new_track = add_subttl_track(0, 0);
190 new_track->copy_from(current);
192 if( current->get_id() == solo_track_id )
193 edl->local_session->solo_track_id = new_track->get_id();
197 Tracks& Tracks::operator=(Tracks &tracks)
199 printf("Tracks::operator= 1\n");
204 int Tracks::load(FileXML *xml,
208 // add the appropriate type of track
209 char string[BCTEXTLEN];
213 xml->tag.get_property("TYPE", string);
215 if((load_flags & LOAD_ALL) == LOAD_ALL ||
216 (load_flags & LOAD_EDITS)) {
217 if(!strcmp(string, "VIDEO")) {
218 track = add_video_track(0, 0);
220 else if(!strcmp(string, "SUBTTL")) {
221 track = add_subttl_track(0, 0);
224 track = add_audio_track(0, 0); // default to audio
228 track = get_item_number(track_offset++);
232 if( track ) track->load(xml, track_offset, load_flags);
237 Track* Tracks::add_audio_track(int above, Track *dst_track)
239 ATrack* new_track = new ATrack(edl, this);
242 dst_track = (above ? first : last);
247 insert_before(dst_track, (Track*)new_track);
251 insert_after(dst_track, (Track*)new_track);
252 // Shift effects referenced below the destination track
255 // Shift effects referenced below the new track
256 for(Track *track = last;
257 track && track != new_track;
258 track = track->previous)
260 change_modules(number_of(track) - 1, number_of(track), 0);
264 new_track->create_objects();
265 new_track->set_default_title();
268 for(Track *current = first;
269 current != (Track*)new_track;
272 if(current->data_type == TRACK_AUDIO) current_pan++;
273 if(current_pan >= edl->session->audio_channels) current_pan = 0;
279 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
280 pan_auto->values[current_pan] = 1.0;
282 BC_Pan::calculate_stick_position(edl->session->audio_channels,
283 edl->session->achannel_positions,
292 Track* Tracks::add_video_track(int above, Track *dst_track)
294 VTrack* new_track = new VTrack(edl, this);
296 dst_track = (above ? first : last);
298 insert_before(dst_track, (Track*)new_track);
300 insert_after(dst_track, (Track*)new_track);
302 for(Track *track = last; track && track != new_track; track = track->previous)
303 change_modules(number_of(track) - 1, number_of(track), 0);
305 new_track->create_objects();
306 new_track->set_default_title();
311 Track* Tracks::add_subttl_track(int above, Track *dst_track)
313 STrack* new_track = new STrack(edl, this);
315 dst_track = (above ? first : last);
318 insert_before(dst_track, (Track*)new_track);
320 insert_after(dst_track, (Track*)new_track);
322 for(Track *track = last; track && track != new_track; track = track->previous)
323 change_modules(number_of(track) - 1, number_of(track), 0);
325 new_track->create_objects();
326 new_track->set_default_title();
327 // new_track->paste_silence(0,total_length(),0);
332 int Tracks::delete_track(Track *track, int gang)
334 if( !track ) return 0;
336 gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
337 Track *nxt = track->next;
339 track = track->gang_master();
340 while( nxt && !nxt->master )
343 Track *current = track;
344 int old_location = number_of(current);
345 for( Track *next_track=0; current!=nxt; current=next_track ) {
346 next_track = current->next;
347 detach_shared_effects(old_location);
348 for( Track *curr=current; curr; curr=curr->next ) {
349 // Shift effects referencing effects below the deleted track
350 change_modules(number_of(curr), number_of(curr)-1, 0);
357 int Tracks::detach_shared_effects(int module)
359 for( Track *current=first; current; current=NEXT ) {
360 current->detach_shared_effects(module);
364 int Tracks::detach_ganged_effects(Plugin *plugin)
366 if( edl->session->gang_tracks == GANG_NONE ) return 1;
367 for( Track *current=first; current; current=NEXT ) {
368 if( current == plugin->track ) continue;
369 if( !current->armed_gang(plugin->track) ) continue;
370 current->detach_ganged_effects(plugin);
375 int Tracks::total_of(int type)
379 for(Track *current = first; current; current = NEXT)
381 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
382 Auto *mute_keyframe = 0;
383 current->automation->autos[AUTOMATION_MUTE]->
384 get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
385 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
388 (current->play && type == PLAY) ||
389 (current->is_armed() && type == RECORD) ||
390 (current->is_ganged() && type == GANG) ||
391 (current->draw && type == DRAW) ||
392 (mute_auto->value && type == MUTE) ||
393 (current->expand_view && type == EXPAND);
398 int Tracks::recordable_audio_tracks()
401 for(Track *current = first; current; current = NEXT)
402 if(current->data_type == TRACK_AUDIO && current->is_armed()) result++;
406 int Tracks::recordable_video_tracks()
409 for(Track *current = first; current; current = NEXT)
411 if(current->data_type == TRACK_VIDEO && current->is_armed()) result++;
417 int Tracks::playable_audio_tracks()
421 for(Track *current = first; current; current = NEXT)
423 if(current->data_type == TRACK_AUDIO && current->play)
432 int Tracks::playable_video_tracks()
436 for(Track *current = first; current; current = NEXT)
438 if(current->data_type == TRACK_VIDEO && current->play)
446 int Tracks::total_audio_tracks()
449 for(Track *current = first; current; current = NEXT)
450 if(current->data_type == TRACK_AUDIO) result++;
454 int Tracks::total_video_tracks()
457 for(Track *current = first; current; current = NEXT)
458 if(current->data_type == TRACK_VIDEO) result++;
462 double Tracks::total_playable_length()
465 for(Track *current = first; current; current = NEXT)
469 double length = current->get_length();
470 if(length > total) total = length;
476 double Tracks::total_recordable_length()
479 for(Track *current = first; current; current = NEXT)
481 if(current->is_armed())
483 double length = current->get_length();
484 if(length > total) total = length;
490 double Tracks::total_length()
493 for(Track *current = first; current; current = NEXT)
495 double length = current->get_length();
496 if(length > total) total = length;
501 double Tracks::total_audio_length()
504 for(Track *current = first; current; current = NEXT)
506 if(current->data_type == TRACK_AUDIO &&
507 current->get_length() > total) total = current->get_length();
512 double Tracks::total_video_length()
515 for(Track *current = first; current; current = NEXT)
517 if(current->data_type == TRACK_VIDEO &&
518 current->get_length() > total) total = current->get_length();
523 double Tracks::total_length_framealigned(double fps)
525 if (total_audio_tracks() && total_video_tracks())
526 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
528 if (total_audio_tracks())
529 return floor(total_audio_length() * fps) / fps;
531 if (total_video_tracks())
532 return floor(total_video_length() * fps) / fps;
537 void Tracks::translate_fauto_xy(int fauto, float dx, float dy, int all)
539 Track *track = first;
540 for( ; track; track=track->next ) {
541 if( !all && !track->is_armed() ) continue;
542 if( track->data_type != TRACK_VIDEO ) continue;
543 ((VTrack*)track)->translate(fauto, dx, dy, all);
547 void Tracks::translate_projector(float dx, float dy, int all)
549 translate_fauto_xy(AUTOMATION_PROJECTOR_X, dx, dy, all);
552 void Tracks::translate_camera(float dx, float dy, int all)
554 translate_fauto_xy(AUTOMATION_CAMERA_X, dx, dy, all);
557 void Tracks::crop_resize(float x, float y, float z)
559 float ctr_x = edl->session->output_w / 2.;
560 float ctr_y = edl->session->output_h / 2.;
561 Track *track = first;
562 for( ; track; track=track->next ) {
563 if( !track->is_armed() ) continue;
564 if( track->data_type != TRACK_VIDEO ) continue;
566 track->get_projector(px, py, pz);
567 float old_x = px + ctr_x;
568 float old_y = py + ctr_y;
569 float nx = (old_x - x) * z;
570 float ny = (old_y - y) * z;
571 track->set_projector(nx, ny, pz * z);
575 void Tracks::crop_shrink(float x, float y, float z)
577 float ctr_x = edl->session->output_w / 2.;
578 float ctr_y = edl->session->output_h / 2.;
579 Track *track = first;
580 for( ; track; track=track->next ) {
581 if( !track->is_armed() ) continue;
582 if( track->data_type != TRACK_VIDEO ) continue;
583 float cx, cy, cz, px, py, pz;
584 track->get_camera(cx, cy, cz);
585 track->get_projector(px, py, pz);
586 float dx = x - (px + ctr_x);
587 float dy = y - (py + ctr_y);
589 cx += dx / cz; cy += dy / cz;
590 track->set_camera(cx, cy, cz * z);
592 track->set_projector(px, py, 1 / z);
596 void Tracks::update_y_pixels(Theme *theme)
598 // int y = -edl->local_session->track_start;
600 for(Track *current = first; current; current = NEXT)
602 //printf("Tracks::update_y_pixels %d\n", y);
603 current->y_pixel = y;
604 if( current->is_hidden() ) continue;
605 y += current->vertical_span(theme);
609 int Tracks::dump(FILE *fp)
611 for(Track* current = first; current; current = NEXT)
613 fprintf(fp," Track: %p\n", current);
620 void Tracks::select_all(int type,
623 for(Track* current = first; current; current = NEXT)
625 double position = edl->local_session->get_selectionstart(1);
627 if(type == PLAY) current->play = value;
628 if(type == RECORD) current->armed = value;
629 if(type == GANG) current->ganged = value;
630 if(type == DRAW) current->draw = value;
634 ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
637 if(type == EXPAND) current->expand_view = value;
641 // ===================================== file operations
643 int Tracks::popup_transition(int cursor_x, int cursor_y)
646 for(Track* current = first; current && !result; current = NEXT)
648 result = current->popup_transition(cursor_x, cursor_y);
654 int Tracks::change_channels(int oldchannels, int newchannels)
656 for(Track *current = first; current; current = NEXT)
657 { current->change_channels(oldchannels, newchannels); }
663 int Tracks::totalpixels()
666 for(Track* current = first; current; current = NEXT)
668 result += current->data_h;
673 int Tracks::number_of(Track *track)
676 for(Track *current = first; current && current != track; current = NEXT)
683 Track* Tracks::number(int number)
687 for(current = first; current && i < number; current = NEXT)
694 Track* Tracks::get_track_by_id(int id)
696 Track *track = edl->tracks->first;
697 while( track && track->get_id() != id ) track = track->next;
701 int Tracks::total_playable_vtracks()
704 for(Track *current = first; current; current = NEXT)
706 if(current->data_type == TRACK_VIDEO && current->play) result++;
711 Plugin *Tracks::plugin_exists(int plugin_id)
713 if( plugin_id < 0 ) return 0;
715 for( Track *track=first; !plugin && track; track=track->next ) {
716 plugin = track->plugin_exists(plugin_id);
721 int Tracks::track_exists(Track *track)
723 for(Track *current = first; current; current = NEXT)
725 if(current == track) return 1;
730 int Tracks::new_group(int id)
733 for( Track *track=first; track; track=track->next ) {
734 if( !track->is_armed() ) continue;
735 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
736 if( edit->group_id > 0 ) continue;
737 if( !edit->is_selected ) continue;
745 int Tracks::set_group_selected(int id, int v)
748 int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
749 for( Track *track=first; track; track=track->next ) {
750 if( track->is_hidden() ) continue;
751 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
752 if( edit->group_id != id ) continue;
753 if( v < 0 ) v = !edit->is_selected ? 1 : 0;
754 edit->select_affected_edits(v, gang);
761 int Tracks::del_group(int id)
764 for( Track *track=first; track; track=track->next ) {
765 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
766 if( edit->group_id != id ) continue;
767 edit->is_selected = 1;
775 Track *Tracks::get(int idx, int data_type)
777 for(Track *current = first; current; current = NEXT)
779 if( current->data_type != data_type ) continue;
780 if( --idx < 0 ) return current;
785 void Tracks::roll_tracks(Track *src, Track *dst, int n)
787 if( src == dst ) return;
788 while( --n >= 0 && src ) {
789 Track *nxt = src->next;
790 change_modules(number_of(src), total(), 0);
791 for( Track *track=nxt; track; track=track->next )
792 change_modules(number_of(track), number_of(track)-1, 0);
794 int ndst = dst ? number_of(dst) : total();
795 insert_before(dst, src);
796 for( Track *track=last; track && track!=src; track=track->previous )
797 change_modules(number_of(track)-1, number_of(track), 0);
798 change_modules(total(), ndst, 0);
803 double Tracks::align_timecodes()
806 for( Track *track=first; track; track=track->next ) {
807 if( !track->is_armed() ) continue;
808 double early_offset = track->edits->early_timecode();
809 if( offset < 0 || offset > early_offset )
810 offset = early_offset;
813 for( Track *track=first; track; track=track->next ) {
814 if( !track->is_armed() ) continue;
815 track->edits->align_timecodes(offset);
821 void Tracks::update_idxbl_length(int id, double dt)
823 for( Track *track=first; track; track=track->next ) {
824 if( !track->is_armed() ) continue;
825 int64_t du = track->to_units(dt,0);
826 track->edits->update_idxbl_length(id, du);
831 void Tracks::create_keyframes(double position, int mask, int mode)
833 for( Track *track=first; track; track=track->next ) {
834 if( !track->is_armed() ) continue;
835 track->create_keyframes(position, mask, mode);