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::get_selected_edits(ArrayList<Edit*> *drag_edits)
118 drag_edits->remove_all();
119 for( Track *track=first; track; track=track->next ) {
120 if( !track->is_armed() ) continue;
121 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
122 if( !edit->is_selected ) continue;
123 drag_edits->append(edit);
128 void Tracks::get_automation_extents(float *min,
136 int coords_undefined = 1;
137 for(Track *current = first; current; current = NEXT)
139 if(current->is_armed())
141 current->automation->get_extents(min,
144 current->to_units(start, 0),
145 current->to_units(end, 1),
152 void Tracks::copy_from(Tracks *tracks)
154 Track *new_track = 0;
157 int solo_track_id = tracks->edl->local_session->solo_track_id;
159 for(Track *current = tracks->first; current; current = NEXT)
161 switch(current->data_type)
164 new_track = add_audio_track(0, 0);
167 new_track = add_video_track(0, 0);
170 new_track = add_subttl_track(0, 0);
175 new_track->copy_from(current);
177 if( current->get_id() == solo_track_id )
178 edl->local_session->solo_track_id = new_track->get_id();
182 Tracks& Tracks::operator=(Tracks &tracks)
184 printf("Tracks::operator= 1\n");
189 int Tracks::load(FileXML *xml,
193 // add the appropriate type of track
194 char string[BCTEXTLEN];
198 xml->tag.get_property("TYPE", string);
200 if((load_flags & LOAD_ALL) == LOAD_ALL ||
201 (load_flags & LOAD_EDITS)) {
202 if(!strcmp(string, "VIDEO")) {
203 track = add_video_track(0, 0);
205 else if(!strcmp(string, "SUBTTL")) {
206 track = add_subttl_track(0, 0);
209 track = add_audio_track(0, 0); // default to audio
213 track = get_item_number(track_offset++);
217 if( track ) track->load(xml, track_offset, load_flags);
222 Track* Tracks::add_audio_track(int above, Track *dst_track)
224 ATrack* new_track = new ATrack(edl, this);
227 dst_track = (above ? first : last);
232 insert_before(dst_track, (Track*)new_track);
236 insert_after(dst_track, (Track*)new_track);
237 // Shift effects referenced below the destination track
240 // Shift effects referenced below the new track
241 for(Track *track = last;
242 track && track != new_track;
243 track = track->previous)
245 change_modules(number_of(track) - 1, number_of(track), 0);
249 new_track->create_objects();
250 new_track->set_default_title();
253 for(Track *current = first;
254 current != (Track*)new_track;
257 if(current->data_type == TRACK_AUDIO) current_pan++;
258 if(current_pan >= edl->session->audio_channels) current_pan = 0;
264 (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
265 pan_auto->values[current_pan] = 1.0;
267 BC_Pan::calculate_stick_position(edl->session->audio_channels,
268 edl->session->achannel_positions,
277 Track* Tracks::add_video_track(int above, Track *dst_track)
279 VTrack* new_track = new VTrack(edl, this);
281 dst_track = (above ? first : last);
283 insert_before(dst_track, (Track*)new_track);
285 insert_after(dst_track, (Track*)new_track);
287 for(Track *track = last; track && track != new_track; track = track->previous)
288 change_modules(number_of(track) - 1, number_of(track), 0);
290 new_track->create_objects();
291 new_track->set_default_title();
296 Track* Tracks::add_subttl_track(int above, Track *dst_track)
298 STrack* new_track = new STrack(edl, this);
300 dst_track = (above ? first : last);
303 insert_before(dst_track, (Track*)new_track);
305 insert_after(dst_track, (Track*)new_track);
307 for(Track *track = last; track && track != new_track; track = track->previous)
308 change_modules(number_of(track) - 1, number_of(track), 0);
310 new_track->create_objects();
311 new_track->set_default_title();
312 // new_track->paste_silence(0,total_length(),0);
317 int Tracks::delete_track(Track *track)
319 if( !track ) return 0;
320 int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
321 Track *nxt = track->next;
323 while( track && !track->master && track->previous )
324 track = track->previous;
325 while( nxt && !nxt->master )
328 Track *current = track;
329 int old_location = number_of(current);
330 for( Track *next_track=0; current!=nxt; current=next_track ) {
331 next_track = current->next;
332 detach_shared_effects(old_location);
333 for( Track *curr=current; curr; curr=curr->next ) {
334 // Shift effects referencing effects below the deleted track
335 change_modules(number_of(curr), number_of(curr)-1, 0);
342 int Tracks::detach_shared_effects(int module)
344 for(Track *current = first; current; current = NEXT)
346 current->detach_shared_effects(module);
352 int Tracks::total_of(int type)
356 for(Track *current = first; current; current = NEXT)
358 long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
359 Auto *mute_keyframe = 0;
360 current->automation->autos[AUTOMATION_MUTE]->
361 get_prev_auto(unit_start, PLAY_FORWARD, mute_keyframe);
362 IntAuto *mute_auto = (IntAuto *)mute_keyframe;
365 (current->play && type == PLAY) ||
366 (current->is_armed() && type == RECORD) ||
367 (current->is_ganged() && type == GANG) ||
368 (current->draw && type == DRAW) ||
369 (mute_auto->value && type == MUTE) ||
370 (current->expand_view && type == EXPAND);
375 int Tracks::recordable_audio_tracks()
378 for(Track *current = first; current; current = NEXT)
379 if(current->data_type == TRACK_AUDIO && current->is_armed()) result++;
383 int Tracks::recordable_video_tracks()
386 for(Track *current = first; current; current = NEXT)
388 if(current->data_type == TRACK_VIDEO && current->is_armed()) result++;
394 int Tracks::playable_audio_tracks()
398 for(Track *current = first; current; current = NEXT)
400 if(current->data_type == TRACK_AUDIO && current->play)
409 int Tracks::playable_video_tracks()
413 for(Track *current = first; current; current = NEXT)
415 if(current->data_type == TRACK_VIDEO && current->play)
423 int Tracks::total_audio_tracks()
426 for(Track *current = first; current; current = NEXT)
427 if(current->data_type == TRACK_AUDIO) result++;
431 int Tracks::total_video_tracks()
434 for(Track *current = first; current; current = NEXT)
435 if(current->data_type == TRACK_VIDEO) result++;
439 double Tracks::total_playable_length()
442 for(Track *current = first; current; current = NEXT)
446 double length = current->get_length();
447 if(length > total) total = length;
453 double Tracks::total_recordable_length()
456 for(Track *current = first; current; current = NEXT)
458 if(current->is_armed())
460 double length = current->get_length();
461 if(length > total) total = length;
467 double Tracks::total_length()
470 for(Track *current = first; current; current = NEXT)
472 double length = current->get_length();
473 if(length > total) total = length;
478 double Tracks::total_audio_length()
481 for(Track *current = first; current; current = NEXT)
483 if(current->data_type == TRACK_AUDIO &&
484 current->get_length() > total) total = current->get_length();
489 double Tracks::total_video_length()
492 for(Track *current = first; current; current = NEXT)
494 if(current->data_type == TRACK_VIDEO &&
495 current->get_length() > total) total = current->get_length();
500 double Tracks::total_length_framealigned(double fps)
502 if (total_audio_tracks() && total_video_tracks())
503 return MIN(floor(total_audio_length() * fps), floor(total_video_length() * fps)) / fps;
505 if (total_audio_tracks())
506 return floor(total_audio_length() * fps) / fps;
508 if (total_video_tracks())
509 return floor(total_video_length() * fps) / fps;
514 void Tracks::translate_fauto_xy(int fauto, float dx, float dy, int all)
516 Track *track = first;
517 for( ; track; track=track->next ) {
518 if( !all && !track->is_armed() ) continue;
519 if( track->data_type != TRACK_VIDEO ) continue;
520 ((VTrack*)track)->translate(fauto, dx, dy, all);
524 void Tracks::translate_projector(float dx, float dy, int all)
526 translate_fauto_xy(AUTOMATION_PROJECTOR_X, dx, dy, all);
529 void Tracks::translate_camera(float dx, float dy, int all)
531 translate_fauto_xy(AUTOMATION_CAMERA_X, dx, dy, all);
534 void Tracks::crop_resize(float x, float y, float z)
536 float ctr_x = edl->session->output_w / 2.;
537 float ctr_y = edl->session->output_h / 2.;
538 Track *track = first;
539 for( ; track; track=track->next ) {
540 if( !track->is_armed() ) continue;
541 if( track->data_type != TRACK_VIDEO ) continue;
543 track->get_projector(px, py, pz);
544 float old_x = px + ctr_x;
545 float old_y = py + ctr_y;
546 float nx = (old_x - x) * z;
547 float ny = (old_y - y) * z;
548 track->set_projector(nx, ny, pz * z);
552 void Tracks::crop_shrink(float x, float y, float z)
554 float ctr_x = edl->session->output_w / 2.;
555 float ctr_y = edl->session->output_h / 2.;
556 Track *track = first;
557 for( ; track; track=track->next ) {
558 if( !track->is_armed() ) continue;
559 if( track->data_type != TRACK_VIDEO ) continue;
560 float cx, cy, cz, px, py, pz;
561 track->get_camera(cx, cy, cz);
562 track->get_projector(px, py, pz);
563 float dx = x - (px + ctr_x);
564 float dy = y - (py + ctr_y);
566 cx += dx / cz; cy += dy / cz;
567 track->set_camera(cx, cy, cz * z);
569 track->set_projector(px, py, 1 / z);
573 void Tracks::update_y_pixels(Theme *theme)
575 // int y = -edl->local_session->track_start;
577 for(Track *current = first; current; current = NEXT)
579 //printf("Tracks::update_y_pixels %d\n", y);
580 current->y_pixel = y;
581 if( current->is_hidden() ) continue;
582 y += current->vertical_span(theme);
586 int Tracks::dump(FILE *fp)
588 for(Track* current = first; current; current = NEXT)
590 fprintf(fp," Track: %p\n", current);
597 void Tracks::select_all(int type,
600 for(Track* current = first; current; current = NEXT)
602 double position = edl->local_session->get_selectionstart(1);
604 if(type == PLAY) current->play = value;
605 if(type == RECORD) current->armed = value;
606 if(type == GANG) current->ganged = value;
607 if(type == DRAW) current->draw = value;
611 ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
614 if(type == EXPAND) current->expand_view = value;
618 // ===================================== file operations
620 int Tracks::popup_transition(int cursor_x, int cursor_y)
623 for(Track* current = first; current && !result; current = NEXT)
625 result = current->popup_transition(cursor_x, cursor_y);
631 int Tracks::change_channels(int oldchannels, int newchannels)
633 for(Track *current = first; current; current = NEXT)
634 { current->change_channels(oldchannels, newchannels); }
640 int Tracks::totalpixels()
643 for(Track* current = first; current; current = NEXT)
645 result += current->data_h;
650 int Tracks::number_of(Track *track)
653 for(Track *current = first; current && current != track; current = NEXT)
660 Track* Tracks::number(int number)
664 for(current = first; current && i < number; current = NEXT)
671 Track* Tracks::get_track_by_id(int id)
673 Track *track = edl->tracks->first;
674 while( track && track->get_id() != id ) track = track->next;
678 int Tracks::total_playable_vtracks()
681 for(Track *current = first; current; current = NEXT)
683 if(current->data_type == TRACK_VIDEO && current->play) result++;
688 Plugin *Tracks::plugin_exists(int plugin_id)
690 if( plugin_id < 0 ) return 0;
692 for( Track *track=first; !plugin && track; track=track->next ) {
693 plugin = track->plugin_exists(plugin_id);
698 int Tracks::track_exists(Track *track)
700 for(Track *current = first; current; current = NEXT)
702 if(current == track) return 1;
707 int Tracks::new_group(int id)
710 for( Track *track=first; track; track=track->next ) {
711 if( !track->is_armed() ) continue;
712 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
713 if( edit->group_id > 0 ) continue;
714 if( !edit->is_selected ) continue;
722 int Tracks::set_group_selected(int id, int v)
725 int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
726 for( Track *track=first; track; track=track->next ) {
727 if( track->is_hidden() ) continue;
728 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
729 if( edit->group_id != id ) continue;
730 if( v < 0 ) v = !edit->is_selected ? 1 : 0;
731 edit->select_affected_edits(v, gang);
738 int Tracks::del_group(int id)
741 for( Track *track=first; track; track=track->next ) {
742 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
743 if( edit->group_id != id ) continue;
744 edit->is_selected = 1;
752 Track *Tracks::get(int idx, int data_type)
754 for(Track *current = first; current; current = NEXT)
756 if( current->data_type != data_type ) continue;
757 if( --idx < 0 ) return current;
762 void Tracks::move_tracks(Track *src, Track *dst, int n)
764 if( src == dst ) return;
765 while( --n >= 0 && src ) {
766 Track *nxt = src->next;
767 change_modules(number_of(src), total(), 0);
768 for( Track *track=nxt; track; track=track->next )
769 change_modules(number_of(track), number_of(track)-1, 0);
771 int ndst = dst ? number_of(dst) : total();
772 insert_before(dst, src);
773 for( Track *track=last; track && track!=src; track=track->previous )
774 change_modules(number_of(track)-1, number_of(track), 0);
775 change_modules(total(), ndst, 0);