+++ /dev/null
-/*
- * CINELERRA
- * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "atrack.h"
-#include "automation.h"
-#include "cursor.h"
-#include "bchash.h"
-#include "edit.h"
-#include "edits.h"
-#include "edl.h"
-#include "edlsession.h"
-#include "file.h"
-#include "filexml.h"
-#include "intauto.h"
-#include "intautos.h"
-#include "localsession.h"
-#include "module.h"
-#include "panauto.h"
-#include "panautos.h"
-#include "patchbay.h"
-#include "mainsession.h"
-#include "strack.h"
-#include "theme.h"
-#include "track.h"
-#include "trackcanvas.h"
-#include "tracks.h"
-#include "transportque.inc"
-#include "vtrack.h"
-#include <string.h>
-
-Tracks::Tracks(EDL *edl)
- : List<Track>()
-{
- this->edl = edl;
-}
-
-Tracks::Tracks()
- : List<Track>()
-{
-}
-
-
-Tracks::~Tracks()
-{
- delete_all_tracks();
-}
-
-
-
-
-
-void Tracks::equivalent_output(Tracks *tracks, double *result)
-{
- if(total_playable_vtracks() != tracks->total_playable_vtracks())
- {
- *result = 0;
- }
- else
- {
- Track *current = first;
- Track *that_current = tracks->first;
- while(current || that_current)
- {
-// Get next video track
- while(current && current->data_type != TRACK_VIDEO)
- current = NEXT;
-
- while(that_current && that_current->data_type != TRACK_VIDEO)
- that_current = that_current->next;
-
-// One doesn't exist but the other does
- if((!current && that_current) ||
- (current && !that_current))
- {
- *result = 0;
- break;
- }
- else
-// Both exist
- if(current && that_current)
- {
- current->equivalent_output(that_current, result);
- current = NEXT;
- that_current = that_current->next;
- }
- }
- }
-}
-
-
-
-
-void Tracks::get_affected_edits(ArrayList<Edit*> *drag_edits, double position, Track *start_track)
-{
- drag_edits->remove_all();
-
- for(Track *track = start_track;
- track;
- track = track->next)
- {
-//printf("Tracks::get_affected_edits 1 %p %d %d\n", track, track->data_type, track->record);
- if(track->record)
- {
- for(Edit *edit = track->edits->first; edit; edit = edit->next)
- {
- double startproject = track->from_units(edit->startproject);
-//printf("Tracks::get_affected_edits 1 %d\n", edl->equivalent(startproject, position));
- if(edl->equivalent(startproject, position))
- {
- drag_edits->append(edit);
- break;
- }
- }
- }
- }
-
-}
-
-void Tracks::get_automation_extents(float *min,
- float *max,
- double start,
- double end)
-{
- *min = 0;
- *max = 0;
- int coords_undefined = 1;
- for(Track *current = first; current; current = NEXT)
- {
- if(current->record)
- {
- current->automation->get_extents(min,
- max,
- &coords_undefined,
- current->to_units(start, 1),
- current->to_units(end, 1));
- }
- }
-}
-
-
-void Tracks::copy_from(Tracks *tracks)
-{
- Track *new_track = 0;
-
- delete_all_tracks();
- for(Track *current = tracks->first; current; current = NEXT)
- {
- switch(current->data_type)
- {
- case TRACK_AUDIO:
- new_track = add_audio_track(0, 0);
- break;
- case TRACK_VIDEO:
- new_track = add_video_track(0, 0);
- break;
- case TRACK_SUBTITLE:
- new_track = add_subttl_track(0, 0);
- break;
- default:
- continue;
- }
- new_track->copy_from(current);
- }
-}
-
-Tracks& Tracks::operator=(Tracks &tracks)
-{
-printf("Tracks::operator= 1\n");
- copy_from(&tracks);
- return *this;
-}
-
-int Tracks::load(FileXML *xml,
- int &track_offset,
- uint32_t load_flags)
-{
-// add the appropriate type of track
- char string[BCTEXTLEN];
- Track *track = 0;
- string[0] = 0;
-
- xml->tag.get_property("TYPE", string);
-
- if((load_flags & LOAD_ALL) == LOAD_ALL ||
- (load_flags & LOAD_EDITS))
- {
- if(!strcmp(string, "VIDEO"))
- {
- add_video_track(0, 0);
- }
- else
- if(!strcmp(string, "SUBTTL"))
- {
- add_subttl_track(0, 0);
- }
- else
- {
- add_audio_track(0, 0); // default to audio
- }
- track = last;
- }
- else
- {
- track = get_item_number(track_offset);
- track_offset++;
- }
-
-// load it
- if(track) track->load(xml, track_offset, load_flags);
-
- return 0;
-}
-
-Track* Tracks::add_audio_track(int above, Track *dst_track)
-{
- ATrack* new_track = new ATrack(edl, this);
- if(!dst_track)
- {
- dst_track = (above ? first : last);
- }
-
- if(above)
- {
- insert_before(dst_track, (Track*)new_track);
- }
- else
- {
- insert_after(dst_track, (Track*)new_track);
-// Shift effects referenced below the destination track
- }
-
-// Shift effects referenced below the new track
- for(Track *track = last;
- track && track != new_track;
- track = track->previous)
- {
- change_modules(number_of(track) - 1, number_of(track), 0);
- }
-
-
- new_track->create_objects();
- new_track->set_default_title();
-
- int current_pan = 0;
- for(Track *current = first;
- current != (Track*)new_track;
- current = NEXT)
- {
- if(current->data_type == TRACK_AUDIO) current_pan++;
- if(current_pan >= edl->session->audio_channels) current_pan = 0;
- }
-
-
-
- PanAuto* pan_auto =
- (PanAuto*)new_track->automation->autos[AUTOMATION_PAN]->default_auto;
- pan_auto->values[current_pan] = 1.0;
-
- BC_Pan::calculate_stick_position(edl->session->audio_channels,
- edl->session->achannel_positions,
- pan_auto->values,
- MAX_PAN,
- PAN_RADIUS,
- pan_auto->handle_x,
- pan_auto->handle_y);
- return new_track;
-}
-
-Track* Tracks::add_video_track(int above, Track *dst_track)
-{
-const int debug = 0;
-if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
- VTrack* new_track = new VTrack(edl, this);
-if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
- if(!dst_track)
- dst_track = (above ? first : last);
-
-if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
- if(above)
- {
- insert_before(dst_track, (Track*)new_track);
- }
- else
- {
- insert_after(dst_track, (Track*)new_track);
- }
-if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
-
-
-
-// Shift effects referenced below the new track
- for(Track *track = last;
- track && track != new_track;
- track = track->previous)
- {
- change_modules(number_of(track) - 1, number_of(track), 0);
- }
-
-if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
-
-
- new_track->create_objects();
-if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
- new_track->set_default_title();
-if(debug) printf("Tracks::add_video_track %d\n", __LINE__);
- return new_track;
-}
-
-
-Track* Tracks::add_subttl_track(int above, Track *dst_track)
-{
-const int debug = 0;
-if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
- STrack* new_track = new STrack(edl, this);
-if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
- if(!dst_track)
- dst_track = (above ? first : last);
-
-if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
- if(above)
- {
- insert_before(dst_track, (Track*)new_track);
- }
- else
- {
- insert_after(dst_track, (Track*)new_track);
- }
-if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
-
-
-
-// Shift effects referenced below the new track
- for(Track *track = last;
- track && track != new_track;
- track = track->previous)
- {
- change_modules(number_of(track) - 1, number_of(track), 0);
- }
-
-if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
-
-
- new_track->create_objects();
-if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
- new_track->set_default_title();
-if(debug) printf("Tracks::add_subttl_track %d\n", __LINE__);
-
-// new_track->paste_silence(0,total_length(),0);
- return new_track;
-}
-
-
-int Tracks::delete_track(Track *track)
-{
- if (!track)
- return 0;
-
- int old_location = number_of(track);
- detach_shared_effects(old_location);
-
-// Shift effects referencing effects below the deleted track
- for(Track *current = track;
- current;
- current = NEXT)
- {
- change_modules(number_of(current), number_of(current) - 1, 0);
- }
- if(track) delete track;
-
- return 0;
-}
-
-int Tracks::detach_shared_effects(int module)
-{
- for(Track *current = first; current; current = NEXT)
- {
- current->detach_shared_effects(module);
- }
-
- return 0;
- }
-
-int Tracks::total_of(int type)
-{
- int result = 0;
- IntAuto *mute_keyframe = 0;
-
- for(Track *current = first; current; current = NEXT)
- {
- long unit_start = current->to_units(edl->local_session->get_selectionstart(1), 0);
- mute_keyframe =
- (IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_prev_auto(
- unit_start,
- PLAY_FORWARD,
- (Auto* &)mute_keyframe);
-
- result +=
- (current->play && type == PLAY) ||
- (current->record && type == RECORD) ||
- (current->gang && type == GANG) ||
- (current->draw && type == DRAW) ||
- (mute_keyframe->value && type == MUTE) ||
- (current->expand_view && type == EXPAND);
- }
- return result;
-}
-
-int Tracks::recordable_audio_tracks()
-{
- int result = 0;
- for(Track *current = first; current; current = NEXT)
- if(current->data_type == TRACK_AUDIO && current->record) result++;
- return result;
-}
-
-int Tracks::recordable_video_tracks()
-{
- int result = 0;
- for(Track *current = first; current; current = NEXT)
- {
- if(current->data_type == TRACK_VIDEO && current->record) result++;
- }
- return result;
-}
-
-
-int Tracks::playable_audio_tracks()
-{
- int result = 0;
-
- for(Track *current = first; current; current = NEXT)
- {
- if(current->data_type == TRACK_AUDIO && current->play)
- {
- result++;
- }
- }
-
- return result;
-}
-
-int Tracks::playable_video_tracks()
-{
- int result = 0;
-
- for(Track *current = first; current; current = NEXT)
- {
- if(current->data_type == TRACK_VIDEO && current->play)
- {
- result++;
- }
- }
- return result;
-}
-
-int Tracks::total_audio_tracks()
-{
- int result = 0;
- for(Track *current = first; current; current = NEXT)
- if(current->data_type == TRACK_AUDIO) result++;
- return result;
-}
-
-int Tracks::total_video_tracks()
-{
- int result = 0;
- for(Track *current = first; current; current = NEXT)
- if(current->data_type == TRACK_VIDEO) result++;
- return result;
-}
-
-double Tracks::total_playable_length()
-{
- double total = 0;
- for(Track *current = first; current; current = NEXT)
- {
- double length = current->get_length();
- if(length > total) total = length;
- }
- return total;
-}
-
-double Tracks::total_recordable_length()
-{
- double total = 0;
- for(Track *current = first; current; current = NEXT)
- {
- if(current->record)
- {
- double length = current->get_length();
- if(length > total) total = length;
- }
- }
- return total;
-}
-
-double Tracks::total_length()
-{
- double total = 0;
- for(Track *current = first; current; current = NEXT)
- {
- if(current->get_length() > total) total = current->get_length();
- }
- return total;
-}
-
-double Tracks::total_video_length()
-{
- double total = 0;
- for(Track *current = first; current; current = NEXT)
- {
- if(current->data_type == TRACK_VIDEO &&
- current->get_length() > total) total = current->get_length();
- }
- return total;
-}
-
-
-void Tracks::translate_camera(float offset_x, float offset_y)
-{
- for(Track *current = first; current; current = NEXT)
- {
- if(current->data_type == TRACK_VIDEO)
- {
- ((VTrack*)current)->translate(offset_x, offset_y, 1);
- }
- }
-}
-void Tracks::translate_projector(float offset_x, float offset_y)
-{
- for(Track *current = first; current; current = NEXT)
- {
- if(current->data_type == TRACK_VIDEO)
- {
- ((VTrack*)current)->translate(offset_x, offset_y, 0);
- }
- }
-}
-
-void Tracks::update_y_pixels(Theme *theme)
-{
-// int y = -edl->local_session->track_start;
- int y = 0;
- for(Track *current = first; current; current = NEXT)
- {
-//printf("Tracks::update_y_pixels %d\n", y);
- current->y_pixel = y;
- y += current->vertical_span(theme);
- }
-}
-
-int Tracks::dump(FILE *fp)
-{
- for(Track* current = first; current; current = NEXT)
- {
- fprintf(fp," Track: %p\n", current);
- current->dump(fp);
- fprintf(fp,"\n");
- }
- return 0;
-}
-
-void Tracks::select_all(int type,
- int value)
-{
- for(Track* current = first; current; current = NEXT)
- {
- double position = edl->local_session->get_selectionstart(1);
-
- if(type == PLAY) current->play = value;
- if(type == RECORD) current->record = value;
- if(type == GANG) current->gang = value;
- if(type == DRAW) current->draw = value;
-
- if(type == MUTE)
- {
- ((IntAuto*)current->automation->autos[AUTOMATION_MUTE]->get_auto_for_editing(position))->value = value;
- }
-
- if(type == EXPAND) current->expand_view = value;
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-// ===================================== file operations
-
-int Tracks::popup_transition(int cursor_x, int cursor_y)
-{
- int result = 0;
- for(Track* current = first; current && !result; current = NEXT)
- {
- result = current->popup_transition(cursor_x, cursor_y);
- }
- return result;
-}
-
-
-int Tracks::change_channels(int oldchannels, int newchannels)
-{
- for(Track *current = first; current; current = NEXT)
- { current->change_channels(oldchannels, newchannels); }
- return 0;
-}
-
-
-
-int Tracks::totalpixels()
-{
- int result = 0;
- for(Track* current = first; current; current = NEXT)
- {
- result += edl->local_session->zoom_track;
- }
- return result;
-}
-
-int Tracks::number_of(Track *track)
-{
- int i = 0;
- for(Track *current = first; current && current != track; current = NEXT)
- {
- i++;
- }
- return i;
-}
-
-Track* Tracks::number(int number)
-{
- Track *current;
- int i = 0;
- for(current = first; current && i < number; current = NEXT)
- {
- i++;
- }
- return current;
-}
-
-
-int Tracks::total_playable_vtracks()
-{
- int result = 0;
- for(Track *current = first; current; current = NEXT)
- {
- if(current->data_type == TRACK_VIDEO && current->play) result++;
- }
- return result;
-}
-
-int Tracks::plugin_exists(Plugin *plugin)
-{
- for(Track *track = first; track; track = track->next)
- {
- if(track->plugin_exists(plugin)) return 1;
- }
- return 0;
-}
-
-int Tracks::track_exists(Track *track)
-{
- for(Track *current = first; current; current = NEXT)
- {
- if(current == track) return 1;
- }
- return 0;
-}
-
-
-Track *Tracks::get(int idx, int data_type)
-{
- for(Track *current = first; current; current = NEXT)
- {
- if( current->data_type != data_type ) continue;
- if( --idx < 0 ) return current;
- }
- return 0;
-}
-
-
-
-