[Bf-blender-cvs] [9aa82b0bf44] temp-vse-retiming-tool: Implement meta strip retiming for sound
Richard Antalik
noreply at git.blender.org
Mon Nov 14 16:58:20 CET 2022
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. @@
More information about the Bf-blender-cvs
mailing list