X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ftracks.C;h=36dc79cc5d4c1ab9ccd5628337c66237ae5dc565;hp=bab0b6b47679be66ca9b5b267e25a73c29be64fb;hb=HEAD;hpb=ee1879b1a1850e1d4e19c034d4a9c5459274bbb6 diff --git a/cinelerra-5.1/cinelerra/tracks.C b/cinelerra-5.1/cinelerra/tracks.C index bab0b6b4..dc6bfc81 100644 --- a/cinelerra-5.1/cinelerra/tracks.C +++ b/cinelerra-5.1/cinelerra/tracks.C @@ -1,6 +1,7 @@ /* * CINELERRA * Copyright (C) 2010 Adam Williams + * Copyright (C) 2003-2016 Cinelerra CV contributors * * 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 @@ -35,6 +36,7 @@ #include "panauto.h" #include "panautos.h" #include "patchbay.h" +#include "plugin.h" #include "mainsession.h" #include "strack.h" #include "theme.h" @@ -113,27 +115,28 @@ void Tracks::clear_selected_edits() } } -void Tracks::select_affected_edits(double position, Track *start_track) +void Tracks::get_selected_edits(ArrayList *drag_edits) { - for( Track *track=start_track; track; track=track->next ) { - if( !track->record ) continue; + drag_edits->remove_all(); + for( Track *track=first; track; track=track->next ) { + if( !track->is_armed() ) continue; for( Edit *edit=track->edits->first; edit; edit=edit->next ) { - double startproject = track->from_units(edit->startproject); - if( edl->equivalent(startproject, position) ) { - edit->is_selected = 1; - break; - } + if( !edit->is_selected ) continue; + drag_edits->append(edit); } } } -void Tracks::get_selected_edits(ArrayList *drag_edits) +void Tracks::select_edits(double start, double end, int v) { - drag_edits->remove_all(); for( Track *track=first; track; track=track->next ) { + if( !track->is_armed() ) continue; + int64_t start_pos = track->to_units(start, 0); + int64_t end_pos = track->to_units(end, 0); for( Edit *edit=track->edits->first; edit; edit=edit->next ) { - if( !edit->is_selected ) continue; - drag_edits->append(edit); + if( start_pos >= edit->startproject+edit->length ) continue; + if( edit->startproject >= end_pos ) continue; + edit->is_selected = v > 1 ? 1 : v < 0 ? 0 : !edit->is_selected ; } } } @@ -149,7 +152,7 @@ void Tracks::get_automation_extents(float *min, int coords_undefined = 1; for(Track *current = first; current; current = NEXT) { - if(current->record) + if(current->is_armed()) { current->automation->get_extents(min, max, @@ -167,6 +170,8 @@ void Tracks::copy_from(Tracks *tracks) Track *new_track = 0; delete_all_tracks(); + int solo_track_id = tracks->edl->local_session->solo_track_id; + for(Track *current = tracks->first; current; current = NEXT) { switch(current->data_type) @@ -184,6 +189,9 @@ void Tracks::copy_from(Tracks *tracks) continue; } new_track->copy_from(current); + + if( current->get_id() == solo_track_id ) + edl->local_session->solo_track_id = new_track->get_id(); } } @@ -322,35 +330,48 @@ Track* Tracks::add_subttl_track(int above, Track *dst_track) } -int Tracks::delete_track(Track *track) +int Tracks::delete_track(Track *track, int gang) { - if (!track) - return 0; - - int old_location = number_of(track); - detach_shared_effects(old_location); - + if( !track ) return 0; + if( gang < 0 ) + gang = edl->local_session->gang_tracks != GANG_NONE ? 1 : 0; + Track *nxt = track->next; + if( gang ) { + track = track->gang_master(); + while( nxt && !nxt->master ) + nxt = nxt->next; + } + Track *current = track; + int old_location = number_of(current); + for( Track *next_track=0; current!=nxt; current=next_track ) { + next_track = current->next; + detach_shared_effects(old_location); + for( Track *curr=current; curr; curr=curr->next ) { // 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); + change_modules(number_of(curr), number_of(curr)-1, 0); + } + delete current; } - if(track) delete track; - return 0; } int Tracks::detach_shared_effects(int module) { - for(Track *current = first; current; current = NEXT) - { + for( Track *current=first; current; current=NEXT ) { current->detach_shared_effects(module); } - return 0; - } +} +int Tracks::detach_ganged_effects(Plugin *plugin) +{ + if( edl->local_session->gang_tracks == GANG_NONE ) return 1; + for( Track *current=first; current; current=NEXT ) { + if( current == plugin->track ) continue; + if( !current->armed_gang(plugin->track) ) continue; + current->detach_ganged_effects(plugin); + } + return 0; +} int Tracks::total_of(int type) { @@ -365,9 +386,9 @@ int Tracks::total_of(int type) IntAuto *mute_auto = (IntAuto *)mute_keyframe; result += - (current->play && type == PLAY) || - (current->record && type == RECORD) || - (current->gang && type == GANG) || + (current->plays() && type == PLAY) || + (current->is_armed() && type == RECORD) || + (current->is_ganged() && type == GANG) || (current->draw && type == DRAW) || (mute_auto->value && type == MUTE) || (current->expand_view && type == EXPAND); @@ -379,7 +400,7 @@ int Tracks::recordable_audio_tracks() { int result = 0; for(Track *current = first; current; current = NEXT) - if(current->data_type == TRACK_AUDIO && current->record) result++; + if(current->data_type == TRACK_AUDIO && current->is_armed()) result++; return result; } @@ -388,7 +409,7 @@ int Tracks::recordable_video_tracks() int result = 0; for(Track *current = first; current; current = NEXT) { - if(current->data_type == TRACK_VIDEO && current->record) result++; + if(current->data_type == TRACK_VIDEO && current->is_armed()) result++; } return result; } @@ -400,7 +421,7 @@ int Tracks::playable_audio_tracks() for(Track *current = first; current; current = NEXT) { - if(current->data_type == TRACK_AUDIO && current->play) + if(current->data_type == TRACK_AUDIO && current->plays()) { result++; } @@ -415,7 +436,7 @@ int Tracks::playable_video_tracks() for(Track *current = first; current; current = NEXT) { - if(current->data_type == TRACK_VIDEO && current->play) + if(current->data_type == TRACK_VIDEO && current->plays()) { result++; } @@ -444,7 +465,7 @@ double Tracks::total_playable_length() double total = 0; for(Track *current = first; current; current = NEXT) { - if( current->play ) + if( current->plays() ) { double length = current->get_length(); if(length > total) total = length; @@ -458,7 +479,7 @@ double Tracks::total_recordable_length() double total = -1; for(Track *current = first; current; current = NEXT) { - if(current->record) + if(current->is_armed()) { double length = current->get_length(); if(length > total) total = length; @@ -514,14 +535,62 @@ double Tracks::total_length_framealigned(double fps) return 0; } -void Tracks::translate_projector(float offset_x, float offset_y) +void Tracks::translate_fauto_xy(int fauto, float dx, float dy, int all) { - for(Track *current = first; current; current = NEXT) - { - if(current->data_type == TRACK_VIDEO) - { - ((VTrack*)current)->translate(offset_x, offset_y, 0); - } + Track *track = first; + for( ; track; track=track->next ) { + if( !all && !track->is_armed() ) continue; + if( track->data_type != TRACK_VIDEO ) continue; + ((VTrack*)track)->translate(fauto, dx, dy, all); + } +} + +void Tracks::translate_projector(float dx, float dy, int all) +{ + translate_fauto_xy(AUTOMATION_PROJECTOR_X, dx, dy, all); +} + +void Tracks::translate_camera(float dx, float dy, int all) +{ + translate_fauto_xy(AUTOMATION_CAMERA_X, dx, dy, all); +} + +void Tracks::crop_resize(float x, float y, float z) +{ + float ctr_x = edl->session->output_w / 2.; + float ctr_y = edl->session->output_h / 2.; + Track *track = first; + for( ; track; track=track->next ) { + if( !track->is_armed() ) continue; + if( track->data_type != TRACK_VIDEO ) continue; + float px, py, pz; + track->get_projector(px, py, pz); + float old_x = px + ctr_x; + float old_y = py + ctr_y; + float nx = (old_x - x) * z; + float ny = (old_y - y) * z; + track->set_projector(nx, ny, pz * z); + } +} + +void Tracks::crop_shrink(float x, float y, float z) +{ + float ctr_x = edl->session->output_w / 2.; + float ctr_y = edl->session->output_h / 2.; + Track *track = first; + for( ; track; track=track->next ) { + if( !track->is_armed() ) continue; + if( track->data_type != TRACK_VIDEO ) continue; + float cx, cy, cz, px, py, pz; + track->get_camera(cx, cy, cz); + track->get_projector(px, py, pz); + float dx = x - (px + ctr_x); + float dy = y - (py + ctr_y); + cz *= pz; + cx += dx / cz; cy += dy / cz; + track->set_camera(cx, cy, cz * z); + px += dx; py += dy; + track->set_projector(px, py, 1 / z); } } @@ -533,6 +602,7 @@ void Tracks::update_y_pixels(Theme *theme) { //printf("Tracks::update_y_pixels %d\n", y); current->y_pixel = y; + if( current->is_hidden() ) continue; y += current->vertical_span(theme); } } @@ -556,8 +626,8 @@ void Tracks::select_all(int type, 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 == RECORD) current->armed = value; + if(type == GANG) current->ganged = value; if(type == DRAW) current->draw = value; if(type == MUTE) @@ -596,7 +666,7 @@ int Tracks::totalpixels() int result = 0; for(Track* current = first; current; current = NEXT) { - result += edl->local_session->zoom_track; + result += current->data_h; } return result; } @@ -622,6 +692,12 @@ Track* Tracks::number(int number) return current; } +Track* Tracks::get_track_by_id(int id) +{ + Track *track = edl->tracks->first; + while( track && track->get_id() != id ) track = track->next; + return track; +} int Tracks::total_playable_vtracks() { @@ -633,13 +709,14 @@ int Tracks::total_playable_vtracks() return result; } -int Tracks::plugin_exists(Plugin *plugin) +Plugin *Tracks::plugin_exists(int plugin_id) { - for(Track *track = first; track; track = track->next) - { - if(track->plugin_exists(plugin)) return 1; + if( plugin_id < 0 ) return 0; + Plugin *plugin = 0; + for( Track *track=first; !plugin && track; track=track->next ) { + plugin = track->plugin_exists(plugin_id); } - return 0; + return plugin; } int Tracks::track_exists(Track *track) @@ -651,6 +728,50 @@ int Tracks::track_exists(Track *track) return 0; } +int Tracks::new_group(int id) +{ + int count = 0; + for( Track *track=first; track; track=track->next ) { + if( !track->is_armed() ) continue; + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + if( edit->group_id > 0 ) continue; + if( !edit->is_selected ) continue; + edit->group_id = id; + ++count; + } + } + return count; +} + +int Tracks::set_group_selected(int id, int v) +{ + int count = 0; + int gang = edl->local_session->gang_tracks != GANG_NONE ? 1 : 0; + for( Track *track=first; track; track=track->next ) { + if( track->is_hidden() ) continue; + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + if( edit->group_id != id ) continue; + if( v < 0 ) v = !edit->is_selected ? 1 : 0; + edit->select_affected_edits(v, gang); + ++count; + } + } + return count; +} + +int Tracks::del_group(int id) +{ + int count = 0; + for( Track *track=first; track; track=track->next ) { + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + if( edit->group_id != id ) continue; + edit->is_selected = 1; + edit->group_id = 0; + ++count; + } + } + return count; +} Track *Tracks::get(int idx, int data_type) { @@ -662,4 +783,57 @@ Track *Tracks::get(int idx, int data_type) return 0; } +void Tracks::roll_tracks(Track *src, Track *dst, int n) +{ + if( src == dst ) return; + while( --n >= 0 && src ) { + Track *nxt = src->next; + change_modules(number_of(src), total(), 0); + for( Track *track=nxt; track; track=track->next ) + change_modules(number_of(track), number_of(track)-1, 0); + remove_pointer(src); + int ndst = dst ? number_of(dst) : total(); + insert_before(dst, src); + for( Track *track=last; track && track!=src; track=track->previous ) + change_modules(number_of(track)-1, number_of(track), 0); + change_modules(total(), ndst, 0); + src = nxt; + } +} + +double Tracks::align_timecodes() +{ + double offset = -1; + for( Track *track=first; track; track=track->next ) { + if( !track->is_armed() ) continue; + double early_offset = track->edits->early_timecode(); + if( offset < 0 || offset > early_offset ) + offset = early_offset; + } + if( offset >= 0 ) { + for( Track *track=first; track; track=track->next ) { + if( !track->is_armed() ) continue; + track->edits->align_timecodes(offset); + } + } + return offset; +} + +void Tracks::update_idxbl_length(int id, double dt) +{ + for( Track *track=first; track; track=track->next ) { + if( !track->is_armed() ) continue; + int64_t du = track->to_units(dt,0); + track->edits->update_idxbl_length(id, du); + track->optimize(); + } +} + +void Tracks::create_keyframes(double position, int mask, int mode) +{ + for( Track *track=first; track; track=track->next ) { + if( !track->is_armed() ) continue; + track->create_keyframes(position, mask, mode); + } +}