Commit: 9aa82b0bf44a8992d4fa5000a8f597a65ab4ed90 Author: Richard Antalik Date: Fri Oct 21 20:59:19 2022 +0200 Branches: temp-vse-retiming-tool https://developer.blender.org/rB9aa82b0bf44a8992d4fa5000a8f597a65ab4ed90
Implement meta strip retiming for sound =================================================================== M extern/audaspace/src/sequence/SequenceHandle.cpp M source/blender/editors/space_sequencer/sequencer_draw.c M source/blender/sequencer/SEQ_time.h M source/blender/sequencer/intern/effects.c M source/blender/sequencer/intern/image_cache.c M source/blender/sequencer/intern/proxy.c M source/blender/sequencer/intern/render.c M source/blender/sequencer/intern/strip_retiming.cc M source/blender/sequencer/intern/strip_time.c M source/blender/sequencer/intern/strip_time.h =================================================================== diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp index 6021ce0ee59..236e828963a 100644 --- a/extern/audaspace/src/sequence/SequenceHandle.cpp +++ b/extern/audaspace/src/sequence/SequenceHandle.cpp @@ -250,7 +250,7 @@ bool SequenceHandle::seek(double position) float target_frame = 0; - // XXX this can be optimized if there is only 1 point + // XXX this can be optimized for constant interpolation if (pitch_property != nullptr){ for (int i = 0; i < seek_frame; i++){ float pitch; diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index a6916f9d031..3a95475c1cc 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -413,7 +413,6 @@ static void draw_seq_waveform_overlay( const float frames_per_pixel = BLI_rctf_size_x(®ion->v2d.cur) / region->winx; const float samples_per_frame = SOUND_WAVE_SAMPLES_PER_SECOND / FPS; - float samples_per_pixel = samples_per_frame * frames_per_pixel; /* Align strip start with nearest pixel to prevent waveform flickering. */ const float x1_aligned = align_frame_with_pixel(x1, frames_per_pixel); @@ -439,15 +438,16 @@ static void draw_seq_waveform_overlay( size_t wave_data_len = 0; /* Offset must be also aligned, otherwise waveform flickers when moving left handle. */ - const float strip_offset = align_frame_with_pixel(seq->startofs + seq->anim_startofs, - frames_per_pixel); - float start_sample = strip_offset * samples_per_frame; - start_sample += seq->sound->offset_time * SOUND_WAVE_SAMPLES_PER_SECOND; + float start_frame = SEQ_time_left_handle_frame_get(scene, seq); + /* Add off-screen part of strip to offset. */ - start_sample += (frame_start - x1_aligned) * samples_per_frame; + start_frame += (frame_start - x1_aligned); + start_frame += seq->sound->offset_time / FPS; for (int i = 0; i < pixels_to_draw; i++) { - float sample = start_sample + i * samples_per_pixel; + float timeline_frame = start_frame + i * frames_per_pixel; + float frame_index = SEQ_give_frame_index(scene, seq, timeline_frame); + float sample = frame_index * samples_per_frame; int sample_index = round_fl_to_int(sample); if (sample_index < 0) { @@ -468,6 +468,8 @@ static void draw_seq_waveform_overlay( value_min = (1.0f - f) * value_min + f * waveform->data[sample_index * 3 + 3]; value_max = (1.0f - f) * value_max + f * waveform->data[sample_index * 3 + 4]; rms = (1.0f - f) * rms + f * waveform->data[sample_index * 3 + 5]; + + float samples_per_pixel = samples_per_frame * frames_per_pixel; if (samples_per_pixel > 1.0f) { /* We need to sum up the values we skip over until the next step. */ float next_pos = sample + samples_per_pixel; diff --git a/source/blender/sequencer/SEQ_time.h b/source/blender/sequencer/SEQ_time.h index 49277cd28f7..31c645518d7 100644 --- a/source/blender/sequencer/SEQ_time.h +++ b/source/blender/sequencer/SEQ_time.h @@ -74,6 +74,11 @@ int SEQ_time_find_next_prev_edit(struct Scene *scene, bool SEQ_time_strip_intersects_frame(const struct Scene *scene, const struct Sequence *seq, int timeline_frame); +/** + * Returns true if strip has frames without content to render. + */ +float SEQ_give_frame_index(const struct Scene *scene, struct Sequence *seq, float timeline_frame); + /** * Returns true if strip has frames without content to render. */ diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index 8469876ba25..8c99fcc0713 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -2617,7 +2617,7 @@ float seq_speed_effect_target_frame_get(Scene *scene, } SEQ_effect_handle_get(seq_speed); /* Ensure, that data are initialized. */ - int frame_index = seq_give_frame_index(scene, seq_speed, timeline_frame); + int frame_index = SEQ_give_frame_index(scene, seq_speed, timeline_frame); SpeedControlVars *s = (SpeedControlVars *)seq_speed->effectdata; const Sequence *source = seq_speed->seq1; diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c index 87da2017296..e0208f17636 100644 --- a/source/blender/sequencer/intern/image_cache.c +++ b/source/blender/sequencer/intern/image_cache.c @@ -142,7 +142,7 @@ static float seq_cache_timeline_frame_to_frame_index(Scene *scene, * images or extended frame range of movies will only generate one cache entry. No special * treatment in converting frame index to timeline_frame is needed. */ if (ELEM(type, SEQ_CACHE_STORE_RAW, SEQ_CACHE_STORE_THUMBNAIL)) { - return seq_give_frame_index(scene, seq, timeline_frame); + return SEQ_give_frame_index(scene, seq, timeline_frame); } return timeline_frame - SEQ_time_start_frame_get(seq); diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c index fc1df4dc3ac..6256047c4f2 100644 --- a/source/blender/sequencer/intern/proxy.c +++ b/source/blender/sequencer/intern/proxy.c @@ -209,7 +209,7 @@ ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int timeline } if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { - int frameno = (int)seq_give_frame_index(context->scene, seq, timeline_frame) + + int frameno = (int)SEQ_give_frame_index(context->scene, seq, timeline_frame) + seq->anim_startofs; if (proxy->anim == NULL) { if (seq_proxy_get_fname( diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index e3fd9216842..2652f12aab3 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -238,7 +238,7 @@ StripElem *SEQ_render_give_stripelem(const Scene *scene, Sequence *seq, int time * all other strips don't use this... */ - int frame_index = (int)seq_give_frame_index(scene, seq, timeline_frame); + int frame_index = (int)SEQ_give_frame_index(scene, seq, timeline_frame); if (frame_index == -1 || se == NULL) { return NULL; @@ -1021,7 +1021,7 @@ static ImBuf *seq_render_movie_strip_custom_file_proxy(const SeqRenderData *cont } } - int frameno = (int)seq_give_frame_index(context->scene, seq, timeline_frame) + + int frameno = (int)SEQ_give_frame_index(context->scene, seq, timeline_frame) + seq->anim_startofs; return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE); } @@ -1637,7 +1637,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, bool *r_is_proxy_image) { ImBuf *ibuf = NULL; - float frame_index = seq_give_frame_index(context->scene, seq, timeline_frame); + float frame_index = SEQ_give_frame_index(context->scene, seq, timeline_frame); int type = (seq->type & SEQ_TYPE_EFFECT) ? SEQ_TYPE_EFFECT : seq->type; switch (type) { case SEQ_TYPE_META: { diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index 50d0511f17b..69c233b16d1 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -252,26 +252,123 @@ float SEQ_retiming_handle_speed_get(const Scene *scene, return speed; } -#include <BKE_sound.h> -void SEQ_retiming_sound_animation_data_set(const Scene *scene, const Sequence *seq) -{ - MutableSpan handles = SEQ_retiming_handles_get(seq); +using std::vector; + +class RetimingRange { + public: + int start, end ; + float speed; + + enum eIntersectType { + FULL, + PARTIAL_START, + PARTIAL_END, + INSIDE, + NONE, + }; + + RetimingRange(int start_frame, int end_frame, float speed): start(start_frame), end(end_frame), speed(speed) + { + } - //XXX hack to reset data - BKE_sound_set_scene_sound_pitch(seq->scene_sound, 1, 0); + const eIntersectType intersect_type(const RetimingRange& other) const + { + if (other.start <= start && other.end >= end) { + return FULL; + } + if (other.start > start && other.start < end && other.end > start && other.end < end) { + return INSIDE; + } + if (other.start > start && other.start < end){ + return PARTIAL_END; + } + if (other.end > start && other.end < end){ + return PARTIAL_START; + } + return NONE; + } +}; + +class RetimingRangeData { + public: + vector<RetimingRange> ranges; + RetimingRangeData(const Scene *scene, const Sequence *seq) + { + MutableSpan handles = SEQ_retiming_handles_get(seq); + for (const SeqRetimingHandle &handle : handles) { + if (handle.strip_frame_index == 0) { + continue; + } + const SeqRetimingHandle *handle_prev = &handle - 1; + float speed = SEQ_retiming_handle_speed_get(scene, seq, &handle); + int frame_start = SEQ_time_start_frame_get(seq) + handle_prev->strip_frame_index; + int frame_end = SEQ_time_start_frame_get(seq) + handle.strip_frame_index; + + RetimingRange range = RetimingRange(frame_start, frame_end, speed); + ranges.push_back(range); + } + } - for (const SeqRetimingHandle &handle : handles) { - if (handle.strip_frame_index == 0) { - continue; + RetimingRangeData& operator*=(const RetimingRangeData rhs) + { + for (int i = 0; i < ranges.size(); i++) { + RetimingRange& range = ranges[i]; + for (const RetimingRange& rhs_range : rhs.ranges) { + if (range.intersect_type(rhs_range) == range.NONE) { + continue; + } + else if (range.intersect_type(rhs_range) == range.FULL) { + range.speed *= rhs_range.speed; + } + else if (range.intersect_type(rhs_range) == range.PARTIAL_START) { + RetimingRange range_left = RetimingRange( + range.start, rhs_range.end, range.speed * rhs_range.speed); + range.start = rhs_range.end + 1; + ranges.insert( @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs