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::get_automation_extents(float *min,
137 int coords_undefined = 1;
138 for(Track *current = first; current; current = NEXT)
140 if(current->is_armed())
142 current->automation->get_extents(min,
145 current->to_units(start, 0),
146 current->to_units(end, 1),
153 void Tracks::copy_from(Tracks *tracks)
155 Track *new_track = 0;
158 int solo_track_id = tracks->edl->local_session->solo_track_id;
160 for(Track *current = tracks->first; current; current = NEXT)
162 switch(current->data_type)
165 new_track = add_audio_track(0, 0);
168 new_track = add_video_track(0, 0);
171 new_track = add_subttl_track(0, 0);
176 new_track->copy_from(current);
178 if( current->get_id() == solo_track_id )
179 edl->local_session->solo_track_id = new_track->get_id();
183 Tracks& Tracks::operator=(Tracks &tracks)
185 printf("Tracks::operator= 1\n");
190 int Tracks::load(FileXML *xml,
194 // add the appropriate type of track
195 char string[BCTEXTLEN];
199 xml->tag.get_property("TYPE", string);
201 if((load_flags & LOAD_ALL) == LOAD_ALL ||
202 (load_flags & LOAD_EDITS)) {
203 if(!strcmp(string, "VIDEO")) {
204 track = add_video_track(0, 0);
206 else if(!strcmp(string, "SUBTTL")) {
207 track = add_subttl_track(0, 0);
210 track = add_audio_track(0, 0); // default to audio
214 track = get_item_number(track_offset++);
218 if( track ) track->load(xml, track_offset, load_flags);
223 Track* Tracks::add_audio_track(int above, Track *dst_track)
225 ATrack* new_track = new ATrack(edl, this);
228 dst_track = (above ? first : last);
233 insert_before(dst_track, (Track*)new_track);
237 insert_after(dst_track, (Track*)new_track);
238 // Shift effects referenced below the destination track
241 // Shift effects referenced below the new track
242 for(Track *track = last;
243 track && track != new_track;
244 track = track->previous)
246 change_modules(number_of(track) - 1, number_of(track), 0);
250 new_track->create_objects();
251 new_track->set_default_title();
254 for(Track *current = first;
255 current != (Track*)new_track;
258 if(current->data_type == TRACK_AUDIO) current_pan++;
259 if(current_pan >= edl->session->audio_channels) current_pan = 0;
265 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
266 pan_auto->values[current_pan] = 1.0;
268 BC_Pan::calculate_stick_position(edl->session->audio_channels,
269 edl->session->achannel_positions,
278 Track* Tracks::add_video_track(int above, Track *dst_track)
280 VTrack* new_track = new VTrack(edl, this);
282 dst_track = (above ? first : last);
284 insert_before(dst_track, (Track*)new_track);
286 insert_after(dst_track, (Track*)new_track);
288 for(Track *track = last; track && track != new_track; track = track->previous)
289 change_modules(number_of(track) - 1, number_of(track), 0);
291 new_track->create_objects();
292 new_track->set_default_title();
297 Track* Tracks::add_subttl_track(int above, Track *dst_track)
299 STrack* new_track = new STrack(edl, this);
301 dst_track = (above ? first : last);
304 insert_before(dst_track, (Track*)new_track);
306 insert_after(dst_track, (Track*)new_track);
308 for(Track *track = last; track && track != new_track; track = track->previous)
309 change_modules(number_of(track) - 1, number_of(track), 0);
311 new_track->create_objects();
312 new_track->set_default_title();
313 // new_track->paste_silence(0,total_length(),0);
318 int Tracks::delete_track(Track *track, int gang)
320 if( !track ) return 0;
322 gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
323 Track *nxt = track->next;
325 while( track && !track->master && track->previous )
326 track = track->previous;
327 while( nxt && !nxt->master )
330 Track *current = track;
331 int old_location = number_of(current);
332 for( Track *next_track=0; current!=nxt; current=next_track ) {
333 next_track = current->next;
334 detach_shared_effects(old_location);
335 for( Track *curr=current; curr; curr=curr->next ) {
336 // Shift effects referencing effects below the deleted track
337 change_modules(number_of(curr), number_of(curr)-1, 0);
344 int Tracks::detach_shared_effects(int module)
346 for( Track *current=first; current; current=NEXT ) {
347 current->detach_shared_effects(module);
351 int Tracks::detach_ganged_effects(Plugin *plugin)
353 if( edl->session->gang_tracks == GANG_NONE ) return 1;
354 for( Track *current=first; current; current=NEXT ) {
355 if( current == plugin->track ) continue;
356 if( !current->armed_gang(plugin->track) ) continue;
357 current->detach_ganged_effects(plugin);
362 int Tracks::total_of(int type)
366 for(Track *current = first; current; current = NEXT)
368 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
369 Auto *mute_keyframe = 0;
370 current->automation->autos[AUTOMATION_MUTE]->
371 get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
372 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
375 (current->play && type == PLAY) ||
376 (current->is_armed() && type == RECORD) ||
377 (current->is_ganged() && type == GANG) ||
378 (current->draw && type == DRAW) ||
379 (mute_auto->value && type == MUTE) ||
380 (current->expand_view && type == EXPAND);
385 int Tracks::recordable_audio_tracks()
388 for(Track *current = first; current; current = NEXT)
389 if(current->data_type == TRACK_AUDIO && current->is_armed()) result++;
393 int Tracks::recordable_video_tracks()
396 for(Track *current = first; current; current = NEXT)
398 if(current->data_type == TRACK_VIDEO && current->is_armed()) result++;
404 int Tracks::playable_audio_tracks()
408 for(Track *current = first; current; current = NEXT)
410 if(current->data_type == TRACK_AUDIO && current->play)
419 int Tracks::playable_video_tracks()
423 for(Track *current = first; current; current = NEXT)
425 if(current->data_type == TRACK_VIDEO && current->play)
433 int Tracks::total_audio_tracks()
436 for(Track *current = first; current; current = NEXT)
437 if(current->data_type == TRACK_AUDIO) result++;
441 int Tracks::total_video_tracks()
444 for(Track *current = first; current; current = NEXT)
445 if(current->data_type == TRACK_VIDEO) result++;
449 double Tracks::total_playable_length()
452 for(Track *current = first; current; current = NEXT)
456 double length = current->get_length();
457 if(length > total) total = length;
463 double Tracks::total_recordable_length()
466 for(Track *current = first; current; current = NEXT)
468 if(current->is_armed())
470 double length = current->get_length();
471 if(length > total) total = length;
477 double Tracks::total_length()
480 for(Track *current = first; current; current = NEXT)
482 double length = current->get_length();
483 if(length > total) total = length;
488 double Tracks::total_audio_length()
491 for(Track *current = first; current; current = NEXT)
493 if(current->data_type == TRACK_AUDIO &&
494 current->get_length() > total) total = current->get_length();
499 double Tracks::total_video_length()
502 for(Track *current = first; current; current = NEXT)
504 if(current->data_type == TRACK_VIDEO &&
505 current->get_length() > total) total = current->get_length();
510 double Tracks::total_length_framealigned(double fps)
512 if (total_audio_tracks() && total_video_tracks())
513 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
515 if (total_audio_tracks())
516 return floor(total_audio_length() * fps) / fps;
518 if (total_video_tracks())
519 return floor(total_video_length() * fps) / fps;
524 void Tracks::translate_fauto_xy(int fauto, float dx, float dy, int all)
526 Track *track = first;
527 for( ; track; track=track->next ) {
528 if( !all && !track->is_armed() ) continue;
529 if( track->data_type != TRACK_VIDEO ) continue;
530 ((VTrack*)track)->translate(fauto, dx, dy, all);
534 void Tracks::translate_projector(float dx, float dy, int all)
536 translate_fauto_xy(AUTOMATION_PROJECTOR_X, dx, dy, all);
539 void Tracks::translate_camera(float dx, float dy, int all)
541 translate_fauto_xy(AUTOMATION_CAMERA_X, dx, dy, all);
544 void Tracks::crop_resize(float x, float y, float z)
546 float ctr_x = edl->session->output_w / 2.;
547 float ctr_y = edl->session->output_h / 2.;
548 Track *track = first;
549 for( ; track; track=track->next ) {
550 if( !track->is_armed() ) continue;
551 if( track->data_type != TRACK_VIDEO ) continue;
553 track->get_projector(px, py, pz);
554 float old_x = px + ctr_x;
555 float old_y = py + ctr_y;
556 float nx = (old_x - x) * z;
557 float ny = (old_y - y) * z;
558 track->set_projector(nx, ny, pz * z);
562 void Tracks::crop_shrink(float x, float y, float z)
564 float ctr_x = edl->session->output_w / 2.;
565 float ctr_y = edl->session->output_h / 2.;
566 Track *track = first;
567 for( ; track; track=track->next ) {
568 if( !track->is_armed() ) continue;
569 if( track->data_type != TRACK_VIDEO ) continue;
570 float cx, cy, cz, px, py, pz;
571 track->get_camera(cx, cy, cz);
572 track->get_projector(px, py, pz);
573 float dx = x - (px + ctr_x);
574 float dy = y - (py + ctr_y);
576 cx += dx / cz; cy += dy / cz;
577 track->set_camera(cx, cy, cz * z);
579 track->set_projector(px, py, 1 / z);
583 void Tracks::update_y_pixels(Theme *theme)
585 // int y = -edl->local_session->track_start;
587 for(Track *current = first; current; current = NEXT)
589 //printf("Tracks::update_y_pixels %d\n", y);
590 current->y_pixel = y;
591 if( current->is_hidden() ) continue;
592 y += current->vertical_span(theme);
596 int Tracks::dump(FILE *fp)
598 for(Track* current = first; current; current = NEXT)
600 fprintf(fp," Track: %p\n", current);
607 void Tracks::select_all(int type,
610 for(Track* current = first; current; current = NEXT)
612 double position = edl->local_session->get_selectionstart(1);
614 if(type == PLAY) current->play = value;
615 if(type == RECORD) current->armed = value;
616 if(type == GANG) current->ganged = value;
617 if(type == DRAW) current->draw = value;
621 ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
624 if(type == EXPAND) current->expand_view = value;
628 // ===================================== file operations
630 int Tracks::popup_transition(int cursor_x, int cursor_y)
633 for(Track* current = first; current && !result; current = NEXT)
635 result = current->popup_transition(cursor_x, cursor_y);
641 int Tracks::change_channels(int oldchannels, int newchannels)
643 for(Track *current = first; current; current = NEXT)
644 { current->change_channels(oldchannels, newchannels); }
650 int Tracks::totalpixels()
653 for(Track* current = first; current; current = NEXT)
655 result += current->data_h;
660 int Tracks::number_of(Track *track)
663 for(Track *current = first; current && current != track; current = NEXT)
670 Track* Tracks::number(int number)
674 for(current = first; current && i < number; current = NEXT)
681 Track* Tracks::get_track_by_id(int id)
683 Track *track = edl->tracks->first;
684 while( track && track->get_id() != id ) track = track->next;
688 int Tracks::total_playable_vtracks()
691 for(Track *current = first; current; current = NEXT)
693 if(current->data_type == TRACK_VIDEO && current->play) result++;
698 Plugin *Tracks::plugin_exists(int plugin_id)
700 if( plugin_id < 0 ) return 0;
702 for( Track *track=first; !plugin && track; track=track->next ) {
703 plugin = track->plugin_exists(plugin_id);
708 int Tracks::track_exists(Track *track)
710 for(Track *current = first; current; current = NEXT)
712 if(current == track) return 1;
717 int Tracks::new_group(int id)
720 for( Track *track=first; track; track=track->next ) {
721 if( !track->is_armed() ) continue;
722 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
723 if( edit->group_id > 0 ) continue;
724 if( !edit->is_selected ) continue;
732 int Tracks::set_group_selected(int id, int v)
735 int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
736 for( Track *track=first; track; track=track->next ) {
737 if( track->is_hidden() ) continue;
738 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
739 if( edit->group_id != id ) continue;
740 if( v < 0 ) v = !edit->is_selected ? 1 : 0;
741 edit->select_affected_edits(v, gang);
748 int Tracks::del_group(int id)
751 for( Track *track=first; track; track=track->next ) {
752 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
753 if( edit->group_id != id ) continue;
754 edit->is_selected = 1;
762 Track *Tracks::get(int idx, int data_type)
764 for(Track *current = first; current; current = NEXT)
766 if( current->data_type != data_type ) continue;
767 if( --idx < 0 ) return current;
772 void Tracks::move_tracks(Track *src, Track *dst, int n)
774 if( src == dst ) return;
775 while( --n >= 0 && src ) {
776 Track *nxt = src->next;
777 change_modules(number_of(src), total(), 0);
778 for( Track *track=nxt; track; track=track->next )
779 change_modules(number_of(track), number_of(track)-1, 0);
781 int ndst = dst ? number_of(dst) : total();
782 insert_before(dst, src);
783 for( Track *track=last; track && track!=src; track=track->previous )
784 change_modules(number_of(track)-1, number_of(track), 0);
785 change_modules(total(), ndst, 0);
790 double Tracks::align_timecodes()
793 for( Track *track=first; track; track=track->next ) {
794 if( !track->is_armed() ) continue;
795 double early_offset = track->edits->early_timecode();
796 if( offset < 0 || offset > early_offset )
797 offset = early_offset;
800 for( Track *track=first; track; track=track->next ) {
801 if( !track->is_armed() ) continue;
802 track->edits->align_timecodes(offset);
808 void Tracks::update_idxbl_length(int id, double dt)
810 for( Track *track=first; track; track=track->next ) {
811 if( !track->is_armed() ) continue;
812 int64_t du = track->to_units(dt,0);
813 track->edits->update_idxbl_length(id, du);
818 void Tracks::create_keyframes(double position, int mask, int mode)
820 for( Track *track=first; track; track=track->next ) {
821 if( !track->is_armed() ) continue;
822 track->create_keyframes(position, mask, mode);