[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(&region->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