X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fedl.C;h=604dff51890a767335bae43b3d2b65a77cbf23f8;hp=4cea20f53576bc1415164d4d586a381d9053773b;hb=f27f3030943396a02f563f3767d400939b70fbd8;hpb=c6016b2d08ac0fdda37ee6e1f59dadcfd4335388 diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index 4cea20f5..604dff51 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -49,6 +49,7 @@ #include "playbackconfig.h" #include "playabletracks.h" #include "plugin.h" +#include "pluginset.h" #include "preferences.h" #include "recordconfig.h" #include "recordlabel.h" @@ -794,6 +795,121 @@ int EDL::clear(double start, double end, return 0; } +void EDL::delete_edits(ArrayList *edits, int collapse) +{ + if( session->labels_follow_edits ) + delete_edit_labels(edits, collapse); + typedef struct { Track *track; int64_t start, end; } Zone; + ArrayList zones; + for( int i=0; isize(); ++i ) { + Edit *edit = edits->get(i); + Track *track = edit->track; + int64_t start = edit->startproject; + int64_t end = start + edit->length; + Zone &zone = zones.append(); + zone.track = track; zone.start = start; zone.end = end; + if( session->autos_follow_edits ) { + track->automation->clear(start, end, 0, collapse); + } + if( session->plugins_follow_edits ) { + for( int k=0; kplugin_set.size(); ++k ) { + PluginSet *plugin_set = track->plugin_set[k]; + plugin_set->clear(start, end, 1); + if( !collapse ) + plugin_set->paste_silence(start, end); + } + } + track->optimize(); + } + for( int i=0; iedits->clear(start, end); + if( !collapse ) + track->edits->paste_silence(start, end); + track->optimize(); + } + optimize(); +} + +class Range { +public: + static int cmp(Range *ap, Range *bp); + double start, end; + bool operator ==(Range &that) { return this->start == that.start; } + bool operator >(Range &that) { return this->start > that.start; } +}; +int Range::cmp(Range *ap, Range *bp) { + return ap->start < bp->start ? -1 : ap->start == bp->start ? 0 : 1; +} + +static void get_edit_regions(ArrayList *edits, ArrayList ®ions) +{ +// move edit inclusive labels by regions + for( int i=0; isize(); ++i ) { + Edit *edit = edits->get(i); + double pos = edit->track->from_units(edit->startproject); + double end = edit->track->from_units(edit->startproject + edit->length); + int n = regions.size(), k = n; + while( --k >= 0 ) { + Range &range = regions[k]; + if( pos >= range.end ) continue; + if( range.start >= end ) continue; + int expand = 0; + if( range.start > pos ) { range.start = pos; expand = 1; } + if( range.end < end ) { range.end = end; expand = 1; } + if( !expand ) break; + k = n; + } + if( k < 0 ) { + Range &range = regions.append(); + range.start = pos; range.end = end; + } + } + regions.sort(Range::cmp); +} + +void EDL::delete_edit_labels(ArrayList *edits, int collapse) +{ + ArrayList regions; + get_edit_regions(edits, regions); + int n = regions.size(), k = n; + while( --k >= 0 ) { + Range &range = regions[k]; + labels->clear(range.start, range.end, collapse); + } +} + +void EDL::move_edit_labels(ArrayList *edits, double dist) +{ + ArrayList regions; + get_edit_regions(edits, regions); + int n = regions.size(), k = n; + Labels moved(this, 0); + while( --k >= 0 ) { + Range &range = regions[k]; + Label *label = labels->label_of(range.start); + for( Label *next=0; label && label->position <= range.end; label=next ) { + next = label->next; + labels->remove_pointer(label); + label->position += dist; + moved.append(label); + } + Label *current = labels->first; + while( (label=moved.first) ) { + moved.remove_pointer(label); + while( current && current->position < label->position ) + current = current->next; + if( current && current->position == label->position ) { + delete label; continue; + } + labels->insert_before(current, label); + } + } +} + + void EDL::modify_edithandles(double oldposition, double newposition, int currentend, @@ -1179,13 +1295,15 @@ void EDL::get_shared_tracks(Track *track, } } -// aligned frame time +// aligned frame time, account for sample truncation double EDL::frame_align(double position, int round) { - double frame_pos = position * session->frame_rate; - frame_pos = (int64_t)(frame_pos + (round ? 0.5 : 1e-6)); - position = frame_pos / session->frame_rate; - return position; + if( !round && session->sample_rate > 0 ) { + int64_t sample_pos = position * session->sample_rate; + position = (sample_pos+2.) / session->sample_rate; + } + int64_t frame_pos = (position * session->frame_rate + (round ? 0.5 : 1e-6)); + return frame_pos / session->frame_rate; } // Convert position to frames if alignment is enabled. @@ -1656,6 +1774,11 @@ double EDL::get_cursor_position(int cursor_x, int pane_no) (double)local_session->view_start[pane_no] * local_session->zoom_sample / session->sample_rate; } +int64_t EDL::get_position_cursorx(double position, int pane_no) +{ + return (int64_t)(position * session->sample_rate / local_session->zoom_sample) + - local_session->view_start[pane_no]; +} int EDL::in_use(Indexable *indexable) { @@ -1676,3 +1799,27 @@ int EDL::in_use(Indexable *indexable) return 0; } +int EDL::regroup(int next_id) +{ + ArrayList new_groups; + for( Track *track=tracks->first; track; track=track->next ) { + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + if( !edit->group_id ) continue; + int k = new_groups.size(); + while( --k >= 0 && new_groups[k] != edit->group_id ); + if( k >= 0 ) continue; + new_groups.append(edit->group_id); + } + } + for( Track *track=tracks->first; track; track=track->next ) { + for( Edit *edit=track->edits->first; edit; edit=edit->next ) { + if( !edit->group_id ) continue; + int k = new_groups.size(); + while( --k >= 0 && new_groups[k] != edit->group_id ); + if( k < 0 ) continue; + edit->group_id = k + next_id; + } + } + return new_groups.size(); +} +