From 30b56abb01be224f76e75105e87561de961bc6e2 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 22 Feb 2023 13:55:50 +0100 Subject: [PATCH 01/13] VSE: Add sound strip retiming support This patch contains changes needed for retiming sound strips. This is a part of blender/blender#104544 ---- Deviation from blender/blender#100337 is, that changes in audaspace are not separated. Versioning for old files is not present, because resulting data is unusable (whole animation is baked, so changing retiming is basically impossible). Versioning also results in precision issues which results in non uniform sound pitch in some cases. And finally calculating strip offset correction is non-trivial (that is least of an issue, but worth mentioning still). So I would advocate to not convert old data to current implementation. I think, that supporting smooth speed transitions would allow for more efficient versioning code. --- extern/audaspace/bindings/C/AUD_Sequence.cpp | 6 + extern/audaspace/bindings/C/AUD_Sequence.h | 10 ++ .../include/sequence/AnimateableProperty.h | 8 ++ .../include/sequence/SequenceEntry.h | 5 +- .../src/sequence/AnimateableProperty.cpp | 13 ++ .../audaspace/src/sequence/SequenceData.cpp | 2 +- .../audaspace/src/sequence/SequenceEntry.cpp | 3 +- .../audaspace/src/sequence/SequenceHandle.cpp | 28 +++- source/blender/blenkernel/BKE_sound.h | 5 + source/blender/blenkernel/intern/sound.c | 9 ++ .../editors/space_sequencer/sequencer_draw.c | 17 ++- source/blender/sequencer/SEQ_retiming.h | 3 + source/blender/sequencer/SEQ_time.h | 2 + source/blender/sequencer/intern/effects.c | 2 +- source/blender/sequencer/intern/image_cache.c | 2 +- source/blender/sequencer/intern/proxy.c | 2 +- source/blender/sequencer/intern/render.c | 6 +- source/blender/sequencer/intern/sequencer.c | 4 +- source/blender/sequencer/intern/strip_add.c | 1 + .../sequencer/intern/strip_retiming.cc | 133 +++++++++++++++++- source/blender/sequencer/intern/strip_time.c | 2 +- source/blender/sequencer/intern/strip_time.h | 3 +- 22 files changed, 238 insertions(+), 28 deletions(-) diff --git a/extern/audaspace/bindings/C/AUD_Sequence.cpp b/extern/audaspace/bindings/C/AUD_Sequence.cpp index e3f88629657..ae887c381aa 100644 --- a/extern/audaspace/bindings/C/AUD_Sequence.cpp +++ b/extern/audaspace/bindings/C/AUD_Sequence.cpp @@ -165,6 +165,12 @@ AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, double begin, doub (*entry)->move(begin, end, skip); } +AUD_API void AUD_SequenceEntry_setAnimationData_constant_range(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data) +{ + AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast(type)); + prop->write_range(data, frame_start, frame_end); +} + AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated) { AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast(type)); diff --git a/extern/audaspace/bindings/C/AUD_Sequence.h b/extern/audaspace/bindings/C/AUD_Sequence.h index bdf1a61a2de..11b9206e5cb 100644 --- a/extern/audaspace/bindings/C/AUD_Sequence.h +++ b/extern/audaspace/bindings/C/AUD_Sequence.h @@ -68,6 +68,16 @@ extern AUD_API void AUD_Sequence_remove(AUD_Sound* sequence, AUD_SequenceEntry* * Writes animation data to a sequence. * \param sequence The sound scene. * \param type The type of animation data. + * \param frame_start Start of the frame range. + * \param frame_end End of the frame range. + * \param data The data to write. + */ +AUD_API void AUD_SequenceEntry_setAnimationData_constant_range(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data); + +/** + * Writes animation data to a sequenced entry. + * \param entry The sequenced entry. + * \param type The type of animation data. * \param frame The frame this data is for. * \param data The data to write. * \param animated Whether the attribute is animated. diff --git a/extern/audaspace/include/sequence/AnimateableProperty.h b/extern/audaspace/include/sequence/AnimateableProperty.h index 2c3fcf23f8b..3bd574781fc 100644 --- a/extern/audaspace/include/sequence/AnimateableProperty.h +++ b/extern/audaspace/include/sequence/AnimateableProperty.h @@ -112,6 +112,14 @@ public: */ void write(const float* data, int position, int count); + /** + * Fills the properties frame range with constant value and marks it animated. + * \param data The new value. + * \param position_start The start position in the animation in frames. + * \param position_end The end position in the animation in frames. + */ + void write_range(const float* data, int position_start, int position_end); + /** * Reads the properties value. * \param position The position in the animation in frames. diff --git a/extern/audaspace/include/sequence/SequenceEntry.h b/extern/audaspace/include/sequence/SequenceEntry.h index b8e9f116ee4..5146a4b4b68 100644 --- a/extern/audaspace/include/sequence/SequenceEntry.h +++ b/extern/audaspace/include/sequence/SequenceEntry.h @@ -63,6 +63,9 @@ private: /// How many seconds are skipped at the beginning. double m_skip; + /// The FPS of the scene. + float m_fps; + /// Whether the entry is muted. bool m_muted; @@ -124,7 +127,7 @@ public: * \param skip How much seconds should be skipped at the beginning. * \param id The ID of the entry. */ - SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, int id); + SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, float fps, int id); virtual ~SequenceEntry(); /** diff --git a/extern/audaspace/src/sequence/AnimateableProperty.cpp b/extern/audaspace/src/sequence/AnimateableProperty.cpp index 306ba8e07f5..fffc27aa346 100644 --- a/extern/audaspace/src/sequence/AnimateableProperty.cpp +++ b/extern/audaspace/src/sequence/AnimateableProperty.cpp @@ -65,6 +65,19 @@ void AnimateableProperty::write(const float* data) std::memcpy(getBuffer(), data, m_count * sizeof(float)); } +void AnimateableProperty::write_range(const float* data, int position_start, int position_end) +{ + assureSize(position_end * m_count * sizeof(float), true); + float* buf = getBuffer(); + + for(int i = position_start; i < position_end; i++) + { + std::memcpy(buf + i * m_count, data, m_count * sizeof(float)); + } + m_isAnimated = true; +} + + void AnimateableProperty::write(const float* data, int position, int count) { std::lock_guard lock(m_mutex); diff --git a/extern/audaspace/src/sequence/SequenceData.cpp b/extern/audaspace/src/sequence/SequenceData.cpp index 288f0bd225d..d569df40878 100644 --- a/extern/audaspace/src/sequence/SequenceData.cpp +++ b/extern/audaspace/src/sequence/SequenceData.cpp @@ -153,7 +153,7 @@ std::shared_ptr SequenceData::add(std::shared_ptr sound, { std::lock_guard lock(m_mutex); - std::shared_ptr entry = std::shared_ptr(new SequenceEntry(sound, begin, end, skip, m_id++)); + std::shared_ptr entry = std::shared_ptr(new SequenceEntry(sound, begin, end, skip, m_fps, m_id++)); m_entries.push_back(entry); m_entry_status++; diff --git a/extern/audaspace/src/sequence/SequenceEntry.cpp b/extern/audaspace/src/sequence/SequenceEntry.cpp index b63bdd2ffca..6c25eeb2e7b 100644 --- a/extern/audaspace/src/sequence/SequenceEntry.cpp +++ b/extern/audaspace/src/sequence/SequenceEntry.cpp @@ -22,7 +22,7 @@ AUD_NAMESPACE_BEGIN -SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, int id) : +SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, float fps, int id) : m_status(0), m_pos_status(1), m_sound_status(0), @@ -31,6 +31,7 @@ SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double m_begin(begin), m_end(end), m_skip(skip), + m_fps(fps), m_muted(false), m_relative(true), m_volume_max(1.0f), diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp index fca4e805df2..8c6e06f7c74 100644 --- a/extern/audaspace/src/sequence/SequenceHandle.cpp +++ b/extern/audaspace/src/sequence/SequenceHandle.cpp @@ -241,10 +241,30 @@ bool SequenceHandle::seek(double position) return false; std::lock_guard lock(*m_entry); - double seekpos = position - m_entry->m_begin; - if(seekpos < 0) - seekpos = 0; - seekpos += m_entry->m_skip; + float seek_frame = (position - m_entry->m_begin) * m_entry->m_fps; + if(seek_frame < 0) + seek_frame = 0; + seek_frame += m_entry->m_skip * m_entry->m_fps; + + AnimateableProperty* pitch_property = m_entry->getAnimProperty(AP_PITCH); + + float target_frame = 0; + if(pitch_property != nullptr) + { + for(int i = 0; i < seek_frame; i++) + { + float pitch; + pitch_property->read(i, &pitch); + target_frame += pitch; + } + } + else + { + target_frame = seek_frame; + } + + double seekpos = target_frame / m_entry->m_fps; + m_handle->setPitch(1.0f); m_handle->seek(seekpos); diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index f0bb530e32b..e644a0f93cc 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -154,6 +154,11 @@ void BKE_sound_set_scene_sound_volume(void *handle, float volume, char animated) void BKE_sound_set_scene_sound_pitch(void *handle, float pitch, char animated); +void BKE_sound_set_scene_sound_pitch_constant_range(void *handle, + int frame_start, + int frame_end, + float pitch); + void BKE_sound_set_scene_sound_pan(void *handle, float pan, char animated); void BKE_sound_update_sequencer(struct Main *main, struct bSound *sound); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 96e4fb941af..923859ae5e7 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -819,6 +819,15 @@ void BKE_sound_set_scene_sound_pitch(void *handle, float pitch, char animated) AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PITCH, sound_cfra, &pitch, animated); } +void BKE_sound_set_scene_sound_pitch_constant_range(void *handle, + int frame_start, + int frame_end, + float pitch) +{ + AUD_SequenceEntry_setAnimationData_constant_range( + handle, AUD_AP_PITCH, frame_start, frame_end, &pitch); +} + void BKE_sound_set_scene_sound_pan(void *handle, float pan, char animated) { AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PANNING, sound_cfra, &pan, animated); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 0216224738b..5e999f1cf35 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,17 @@ 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; + /* TODO: Use linear interpolation between frames to avoid bad drawing quality. */ + 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 +469,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_retiming.h b/source/blender/sequencer/SEQ_retiming.h index 84254fda0ea..2b49b4eac06 100644 --- a/source/blender/sequencer/SEQ_retiming.h +++ b/source/blender/sequencer/SEQ_retiming.h @@ -38,6 +38,9 @@ float SEQ_retiming_handle_speed_get(const struct Scene *scene, const struct SeqRetimingHandle *handle); int SEQ_retiming_handle_index_get(const struct Sequence *seq, const struct SeqRetimingHandle *handle); +int SEQ_retiming_handle_index_get(const struct Sequence *seq, + const struct SeqRetimingHandle *handle); +void SEQ_retiming_sound_animation_data_set(const struct Scene *scene, const struct Sequence *seq); #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/SEQ_time.h b/source/blender/sequencer/SEQ_time.h index 45ec3bbc8ae..e547699c33b 100644 --- a/source/blender/sequencer/SEQ_time.h +++ b/source/blender/sequencer/SEQ_time.h @@ -73,6 +73,8 @@ 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); +/* Convert timeline frame so strip frame index. */ +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 3e3fe85ed39..cd0c4dc6203 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -2620,7 +2620,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 21ce2cbdf9a..a49b2c07a5f 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 eaea310f423..33b49ddd436 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 65ba8bf48fe..f9b94cf2fc2 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; @@ -1042,7 +1042,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); } @@ -1658,7 +1658,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/sequencer.c b/source/blender/sequencer/intern/sequencer.c index 478b3acda6a..a47aa2c9f15 100644 --- a/source/blender/sequencer/intern/sequencer.c +++ b/source/blender/sequencer/intern/sequencer.c @@ -990,9 +990,7 @@ static bool seq_update_seq_cb(Sequence *seq, void *user_data) } BKE_sound_set_scene_sound_volume( seq->scene_sound, seq->volume, (seq->flag & SEQ_AUDIO_VOLUME_ANIMATED) != 0); - BKE_sound_set_scene_sound_pitch(seq->scene_sound, - SEQ_sound_pitch_get(scene, seq), - (seq->flag & SEQ_AUDIO_PITCH_ANIMATED) != 0); + SEQ_retiming_sound_animation_data_set(scene, seq); BKE_sound_set_scene_sound_pan( seq->scene_sound, seq->pan, (seq->flag & SEQ_AUDIO_PAN_ANIMATED) != 0); } diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c index 89da6bb1769..639cadbcdd3 100644 --- a/source/blender/sequencer/intern/strip_add.c +++ b/source/blender/sequencer/intern/strip_add.c @@ -433,6 +433,7 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL if (load_data->flags & SEQ_LOAD_MOVIE_SYNC_FPS) { scene->r.frs_sec = fps_denom; scene->r.frs_sec_base = fps_num; + DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_FPS | ID_RECALC_SEQUENCER_STRIPS); } load_data->r_video_stream_start = IMD_anim_get_offset(anim_arr[0]); diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index b3da8ad3f47..e6cbb2fba26 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -118,6 +118,7 @@ bool SEQ_retiming_is_active(const Sequence *seq) bool SEQ_retiming_is_allowed(const Sequence *seq) { return ELEM(seq->type, + SEQ_TYPE_SOUND_RAM, SEQ_TYPE_IMAGE, SEQ_TYPE_META, SEQ_TYPE_SCENE, @@ -126,7 +127,7 @@ bool SEQ_retiming_is_allowed(const Sequence *seq) SEQ_TYPE_MASK); } -float seq_retiming_evaluate(const Sequence *seq, const int frame_index) +float seq_retiming_evaluate(const Sequence *seq, const float frame_index) { const SeqRetimingHandle *previous_handle = retiming_find_segment_start_handle(seq, frame_index); const SeqRetimingHandle *next_handle = previous_handle + 1; @@ -140,7 +141,7 @@ float seq_retiming_evaluate(const Sequence *seq, const int frame_index) } const int segment_length = next_handle->strip_frame_index - previous_handle->strip_frame_index; - const int segment_frame_index = frame_index - previous_handle->strip_frame_index; + const float segment_frame_index = frame_index - previous_handle->strip_frame_index; const float segment_fac = segment_frame_index / (float)segment_length; const float target_diff = next_handle->retiming_factor - previous_handle->retiming_factor; @@ -245,3 +246,131 @@ float SEQ_retiming_handle_speed_get(const Scene *scene, const float speed = (float)fragment_length_retimed / (float)fragment_length_original; return speed; } + +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) + { + } + + 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 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); + } + } + + RetimingRangeData &operator*=(const RetimingRangeData rhs) + { + if (ranges.size() == 0) { + for (const RetimingRange &rhs_range : rhs.ranges) { + RetimingRange range = RetimingRange(rhs_range.start, rhs_range.end, rhs_range.speed); + ranges.push_back(range); + } + } + else { + 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(ranges.begin() + i, range_left); + } + else if (range.intersect_type(rhs_range) == range.PARTIAL_END) { + RetimingRange range_left = RetimingRange( + range.start, rhs_range.start - 1, range.speed); + range.start = rhs_range.start; + ranges.insert(ranges.begin() + i, range_left); + } + else if (range.intersect_type(rhs_range) == range.INSIDE) { + RetimingRange range_left = RetimingRange( + range.start, rhs_range.start - 1, range.speed); + RetimingRange range_mid = RetimingRange( + rhs_range.start, rhs_range.start, rhs_range.speed * range.speed); + range.start = rhs_range.end + 1; + ranges.insert(ranges.begin() + i, range_left); + ranges.insert(ranges.begin() + i, range_mid); + break; + } + } + } + } + return *this; + } +}; + +static RetimingRangeData seq_retiming_range_data_get(const Scene *scene, const Sequence *seq) +{ + RetimingRangeData strip_retiming_data = RetimingRangeData(scene, seq); + + const Sequence *meta_parent = seq_sequence_lookup_meta_by_seq(scene, seq); + if (meta_parent == nullptr) { + return strip_retiming_data; + } + + RetimingRangeData meta_retiming_data = RetimingRangeData(scene, meta_parent); + strip_retiming_data *= meta_retiming_data; + return strip_retiming_data; +} + +void SEQ_retiming_sound_animation_data_set(const Scene *scene, const Sequence *seq) +{ + RetimingRangeData retiming_data = seq_retiming_range_data_get(scene, seq); + for (const RetimingRange &range : retiming_data.ranges) { + BKE_sound_set_scene_sound_pitch_constant_range( + seq->scene_sound, range.start, range.end, range.speed); + } +} diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index 84f01df8db8..c7715862b58 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -62,7 +62,7 @@ int seq_time_strip_original_content_length_get(const Scene *scene, const Sequenc return seq->len / seq_time_media_playback_rate_factor_get(scene, seq); } -float seq_give_frame_index(const Scene *scene, Sequence *seq, float timeline_frame) +float SEQ_give_frame_index(const Scene *scene, Sequence *seq, float timeline_frame) { float frame_index; float sta = SEQ_time_start_frame_get(seq); diff --git a/source/blender/sequencer/intern/strip_time.h b/source/blender/sequencer/intern/strip_time.h index fbd35dc6adf..6b6c5b5adad 100644 --- a/source/blender/sequencer/intern/strip_time.h +++ b/source/blender/sequencer/intern/strip_time.h @@ -16,7 +16,6 @@ struct Scene; struct Sequence; struct SeqCollection; -float seq_give_frame_index(const struct Scene *scene, struct Sequence *seq, float timeline_frame); void seq_update_sound_bounds_recursive(const struct Scene *scene, struct Sequence *metaseq); /* Describes gap between strips in timeline. */ @@ -45,7 +44,7 @@ float seq_time_media_playback_rate_factor_get(const struct Scene *scene, const struct Sequence *seq); int seq_time_strip_original_content_length_get(const struct Scene *scene, const struct Sequence *seq); -float seq_retiming_evaluate(const struct Sequence *seq, const int frame_index); +float seq_retiming_evaluate(const struct Sequence *seq, const float frame_index); #ifdef __cplusplus } -- 2.30.2 From 4793a0e540b5f2e677fd128f7ae357c52bf2e01c Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 21 Mar 2023 17:43:20 +0100 Subject: [PATCH 02/13] clang-format --- extern/audaspace/bindings/C/AUD_Sequence.cpp | 4 ++-- .../include/sequence/AnimateableProperty.h | 14 +++++++------- extern/audaspace/include/sequence/SequenceEntry.h | 4 ++-- .../src/sequence/AnimateableProperty.cpp | 15 +++++++-------- extern/audaspace/src/sequence/SequenceHandle.cpp | 2 +- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/extern/audaspace/bindings/C/AUD_Sequence.cpp b/extern/audaspace/bindings/C/AUD_Sequence.cpp index ae887c381aa..93e4558c7b7 100644 --- a/extern/audaspace/bindings/C/AUD_Sequence.cpp +++ b/extern/audaspace/bindings/C/AUD_Sequence.cpp @@ -167,8 +167,8 @@ AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, double begin, doub AUD_API void AUD_SequenceEntry_setAnimationData_constant_range(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data) { - AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast(type)); - prop->write_range(data, frame_start, frame_end); + AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast(type)); + prop->write_range(data, frame_start, frame_end); } AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated) diff --git a/extern/audaspace/include/sequence/AnimateableProperty.h b/extern/audaspace/include/sequence/AnimateableProperty.h index 3bd574781fc..4c5183972de 100644 --- a/extern/audaspace/include/sequence/AnimateableProperty.h +++ b/extern/audaspace/include/sequence/AnimateableProperty.h @@ -112,13 +112,13 @@ public: */ void write(const float* data, int position, int count); - /** - * Fills the properties frame range with constant value and marks it animated. - * \param data The new value. - * \param position_start The start position in the animation in frames. - * \param position_end The end position in the animation in frames. - */ - void write_range(const float* data, int position_start, int position_end); + /** + * Fills the properties frame range with constant value and marks it animated. + * \param data The new value. + * \param position_start The start position in the animation in frames. + * \param position_end The end position in the animation in frames. + */ + void write_range(const float* data, int position_start, int position_end); /** * Reads the properties value. diff --git a/extern/audaspace/include/sequence/SequenceEntry.h b/extern/audaspace/include/sequence/SequenceEntry.h index 5146a4b4b68..fc4cbc54924 100644 --- a/extern/audaspace/include/sequence/SequenceEntry.h +++ b/extern/audaspace/include/sequence/SequenceEntry.h @@ -63,8 +63,8 @@ private: /// How many seconds are skipped at the beginning. double m_skip; - /// The FPS of the scene. - float m_fps; + /// The FPS of the scene. + float m_fps; /// Whether the entry is muted. bool m_muted; diff --git a/extern/audaspace/src/sequence/AnimateableProperty.cpp b/extern/audaspace/src/sequence/AnimateableProperty.cpp index fffc27aa346..633fca14cc7 100644 --- a/extern/audaspace/src/sequence/AnimateableProperty.cpp +++ b/extern/audaspace/src/sequence/AnimateableProperty.cpp @@ -67,17 +67,16 @@ void AnimateableProperty::write(const float* data) void AnimateableProperty::write_range(const float* data, int position_start, int position_end) { - assureSize(position_end * m_count * sizeof(float), true); - float* buf = getBuffer(); + assureSize(position_end * m_count * sizeof(float), true); + float* buf = getBuffer(); - for(int i = position_start; i < position_end; i++) - { - std::memcpy(buf + i * m_count, data, m_count * sizeof(float)); - } - m_isAnimated = true; + for(int i = position_start; i < position_end; i++) + { + std::memcpy(buf + i * m_count, data, m_count * sizeof(float)); + } + m_isAnimated = true; } - void AnimateableProperty::write(const float* data, int position, int count) { std::lock_guard lock(m_mutex); diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp index 8c6e06f7c74..817fc45badf 100644 --- a/extern/audaspace/src/sequence/SequenceHandle.cpp +++ b/extern/audaspace/src/sequence/SequenceHandle.cpp @@ -264,7 +264,7 @@ bool SequenceHandle::seek(double position) } double seekpos = target_frame / m_entry->m_fps; - + m_handle->setPitch(1.0f); m_handle->seek(seekpos); -- 2.30.2 From 07debd92136a17852de45c10689b4a28a1b2fd99 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 21 Mar 2023 18:41:45 +0100 Subject: [PATCH 03/13] - Pass `SequenceData` reference to `SequenceEntry` instead of fps, - Apply pitch to subframe seek offset --- extern/audaspace/bindings/C/AUD_Sequence.cpp | 2 +- .../include/sequence/AnimateableProperty.h | 2 +- .../audaspace/include/sequence/SequenceEntry.h | 7 ++++--- .../src/sequence/AnimateableProperty.cpp | 2 +- extern/audaspace/src/sequence/SequenceData.cpp | 2 +- extern/audaspace/src/sequence/SequenceEntry.cpp | 4 ++-- extern/audaspace/src/sequence/SequenceHandle.cpp | 16 ++++++++++------ 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/extern/audaspace/bindings/C/AUD_Sequence.cpp b/extern/audaspace/bindings/C/AUD_Sequence.cpp index 93e4558c7b7..d4ac05a4bae 100644 --- a/extern/audaspace/bindings/C/AUD_Sequence.cpp +++ b/extern/audaspace/bindings/C/AUD_Sequence.cpp @@ -168,7 +168,7 @@ AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, double begin, doub AUD_API void AUD_SequenceEntry_setAnimationData_constant_range(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data) { AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast(type)); - prop->write_range(data, frame_start, frame_end); + prop->write_constant_range(data, frame_start, frame_end); } AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated) diff --git a/extern/audaspace/include/sequence/AnimateableProperty.h b/extern/audaspace/include/sequence/AnimateableProperty.h index 4c5183972de..6ee7bac9f31 100644 --- a/extern/audaspace/include/sequence/AnimateableProperty.h +++ b/extern/audaspace/include/sequence/AnimateableProperty.h @@ -118,7 +118,7 @@ public: * \param position_start The start position in the animation in frames. * \param position_end The end position in the animation in frames. */ - void write_range(const float* data, int position_start, int position_end); + void write_constant_range(const float* data, int position_start, int position_end); /** * Reads the properties value. diff --git a/extern/audaspace/include/sequence/SequenceEntry.h b/extern/audaspace/include/sequence/SequenceEntry.h index fc4cbc54924..e02b25aafaf 100644 --- a/extern/audaspace/include/sequence/SequenceEntry.h +++ b/extern/audaspace/include/sequence/SequenceEntry.h @@ -23,6 +23,7 @@ */ #include "sequence/AnimateableProperty.h" +#include "sequence/SequenceData.h" #include "util/ILockable.h" #include @@ -63,8 +64,8 @@ private: /// How many seconds are skipped at the beginning. double m_skip; - /// The FPS of the scene. - float m_fps; + /// reference to sequence_data. Mainly needed to get the FPS of the scene. + std::shared_ptr m_sequence_data; /// Whether the entry is muted. bool m_muted; @@ -127,7 +128,7 @@ public: * \param skip How much seconds should be skipped at the beginning. * \param id The ID of the entry. */ - SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, float fps, int id); + SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, std::shared_ptr m_sequence_data, int id); virtual ~SequenceEntry(); /** diff --git a/extern/audaspace/src/sequence/AnimateableProperty.cpp b/extern/audaspace/src/sequence/AnimateableProperty.cpp index 633fca14cc7..d67b2d7bf82 100644 --- a/extern/audaspace/src/sequence/AnimateableProperty.cpp +++ b/extern/audaspace/src/sequence/AnimateableProperty.cpp @@ -65,7 +65,7 @@ void AnimateableProperty::write(const float* data) std::memcpy(getBuffer(), data, m_count * sizeof(float)); } -void AnimateableProperty::write_range(const float* data, int position_start, int position_end) +void AnimateableProperty::write_constant_range(const float* data, int position_start, int position_end) { assureSize(position_end * m_count * sizeof(float), true); float* buf = getBuffer(); diff --git a/extern/audaspace/src/sequence/SequenceData.cpp b/extern/audaspace/src/sequence/SequenceData.cpp index d569df40878..71138340c9a 100644 --- a/extern/audaspace/src/sequence/SequenceData.cpp +++ b/extern/audaspace/src/sequence/SequenceData.cpp @@ -153,7 +153,7 @@ std::shared_ptr SequenceData::add(std::shared_ptr sound, { std::lock_guard lock(m_mutex); - std::shared_ptr entry = std::shared_ptr(new SequenceEntry(sound, begin, end, skip, m_fps, m_id++)); + std::shared_ptr entry = std::shared_ptr(new SequenceEntry(sound, begin, end, skip, std::shared_ptr(this), m_id++)); m_entries.push_back(entry); m_entry_status++; diff --git a/extern/audaspace/src/sequence/SequenceEntry.cpp b/extern/audaspace/src/sequence/SequenceEntry.cpp index 6c25eeb2e7b..0fbab21cfc8 100644 --- a/extern/audaspace/src/sequence/SequenceEntry.cpp +++ b/extern/audaspace/src/sequence/SequenceEntry.cpp @@ -22,7 +22,7 @@ AUD_NAMESPACE_BEGIN -SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, float fps, int id) : +SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, std::shared_ptr sequence_data, int id) : m_status(0), m_pos_status(1), m_sound_status(0), @@ -31,7 +31,7 @@ SequenceEntry::SequenceEntry(std::shared_ptr sound, double begin, double m_begin(begin), m_end(end), m_skip(skip), - m_fps(fps), + m_sequence_data(sequence_data), m_muted(false), m_relative(true), m_volume_max(1.0f), diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp index 817fc45badf..b256f474234 100644 --- a/extern/audaspace/src/sequence/SequenceHandle.cpp +++ b/extern/audaspace/src/sequence/SequenceHandle.cpp @@ -241,21 +241,25 @@ bool SequenceHandle::seek(double position) return false; std::lock_guard lock(*m_entry); - float seek_frame = (position - m_entry->m_begin) * m_entry->m_fps; + double seek_frame = (position - m_entry->m_begin) * m_entry->m_sequence_data->getFPS(); if(seek_frame < 0) seek_frame = 0; - seek_frame += m_entry->m_skip * m_entry->m_fps; + seek_frame += m_entry->m_skip * m_entry->m_sequence_data->getFPS(); AnimateableProperty* pitch_property = m_entry->getAnimProperty(AP_PITCH); - float target_frame = 0; + double target_frame = 0; if(pitch_property != nullptr) { - for(int i = 0; i < seek_frame; i++) + int i = 0; + while(seek_frame > 0) { float pitch; pitch_property->read(i, &pitch); - target_frame += pitch; + const double factor = seek_frame > 1.0 ? 1.0 : seek_frame; + target_frame += pitch * factor; + seek_frame--; + i++; } } else @@ -263,7 +267,7 @@ bool SequenceHandle::seek(double position) target_frame = seek_frame; } - double seekpos = target_frame / m_entry->m_fps; + double seekpos = target_frame / m_entry->m_sequence_data->getFPS(); m_handle->setPitch(1.0f); m_handle->seek(seekpos); -- 2.30.2 From 238d60e9620de7cc62d2b6e6f1020479da54884f Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 4 Apr 2023 23:13:22 +0200 Subject: [PATCH 04/13] Remove unnecessary `using` kw --- source/blender/sequencer/intern/strip_retiming.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index bcf6977f25c..f42bee2051c 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -292,7 +292,7 @@ class RetimingRangeData { continue; } const SeqRetimingHandle *handle_prev = &handle - 1; - float speed = SEQ_retiming_handle_speed_get(scene, seq, &handle); + float speed = SEQ_retiming_handle_speed_get(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; -- 2.30.2 From a2d25e46f6547d4c15b29dba8d93819b32d7778b Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 5 Apr 2023 01:28:29 +0200 Subject: [PATCH 05/13] Fix incorrect seeking when strip doesn't start at frame 1 --- extern/audaspace/src/sequence/SequenceHandle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp index b256f474234..2f3bdba8cb5 100644 --- a/extern/audaspace/src/sequence/SequenceHandle.cpp +++ b/extern/audaspace/src/sequence/SequenceHandle.cpp @@ -251,11 +251,12 @@ bool SequenceHandle::seek(double position) double target_frame = 0; if(pitch_property != nullptr) { + int frame_start = m_entry->m_begin * m_entry->m_sequence_data->getFPS(); int i = 0; while(seek_frame > 0) { float pitch; - pitch_property->read(i, &pitch); + pitch_property->read(frame_start + i, &pitch); const double factor = seek_frame > 1.0 ? 1.0 : seek_frame; target_frame += pitch * factor; seek_frame--; -- 2.30.2 From 78d8b02a158e96943f84283aad8c512d00a8a410 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 5 Apr 2023 19:23:57 +0200 Subject: [PATCH 06/13] Fix use after free. Still don't quite understand how std::shared_ptr is supposed to be used, but I think this is corect way. --- extern/audaspace/include/sequence/SequenceData.h | 3 ++- extern/audaspace/include/sequence/SequenceEntry.h | 3 ++- extern/audaspace/src/sequence/Sequence.cpp | 2 +- extern/audaspace/src/sequence/SequenceData.cpp | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/extern/audaspace/include/sequence/SequenceData.h b/extern/audaspace/include/sequence/SequenceData.h index c3380e66924..c19c82c090e 100644 --- a/extern/audaspace/include/sequence/SequenceData.h +++ b/extern/audaspace/include/sequence/SequenceData.h @@ -198,12 +198,13 @@ public: /** * Adds a new entry to the scene. * \param sound The sound this entry should play. + * \param sequence_data Reference to sequence_data. Mainly needed to get the FPS of the scene. * \param begin The start time. * \param end The end time or a negative value if determined by the sound. * \param skip How much seconds should be skipped at the beginning. * \return The entry added. */ - std::shared_ptr add(std::shared_ptr sound, double begin, double end, double skip); + std::shared_ptr add(std::shared_ptr sound, std::shared_ptr sequence_data, double begin, double end, double skip); /** * Removes an entry from the scene. diff --git a/extern/audaspace/include/sequence/SequenceEntry.h b/extern/audaspace/include/sequence/SequenceEntry.h index e02b25aafaf..47b900405d9 100644 --- a/extern/audaspace/include/sequence/SequenceEntry.h +++ b/extern/audaspace/include/sequence/SequenceEntry.h @@ -126,9 +126,10 @@ public: * \param begin The start time. * \param end The end time or a negative value if determined by the sound. * \param skip How much seconds should be skipped at the beginning. + * \param sequence_data Reference to sequence_data. Mainly needed to get the FPS of the scene. * \param id The ID of the entry. */ - SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, std::shared_ptr m_sequence_data, int id); + SequenceEntry(std::shared_ptr sound, double begin, double end, double skip, std::shared_ptr sequence_data, int id); virtual ~SequenceEntry(); /** diff --git a/extern/audaspace/src/sequence/Sequence.cpp b/extern/audaspace/src/sequence/Sequence.cpp index ab7e6e77857..3beb225d4ee 100644 --- a/extern/audaspace/src/sequence/Sequence.cpp +++ b/extern/audaspace/src/sequence/Sequence.cpp @@ -92,7 +92,7 @@ AnimateableProperty* Sequence::getAnimProperty(AnimateablePropertyType type) std::shared_ptr Sequence::add(std::shared_ptr sound, double begin, double end, double skip) { - return m_sequence->add(sound, begin, end, skip); + return m_sequence->add(sound, m_sequence, begin, end, skip); } void Sequence::remove(std::shared_ptr entry) diff --git a/extern/audaspace/src/sequence/SequenceData.cpp b/extern/audaspace/src/sequence/SequenceData.cpp index 71138340c9a..47d57da3b92 100644 --- a/extern/audaspace/src/sequence/SequenceData.cpp +++ b/extern/audaspace/src/sequence/SequenceData.cpp @@ -149,11 +149,11 @@ AnimateableProperty* SequenceData::getAnimProperty(AnimateablePropertyType type) } } -std::shared_ptr SequenceData::add(std::shared_ptr sound, double begin, double end, double skip) +std::shared_ptr SequenceData::add(std::shared_ptr sound, std::shared_ptr sequence_data, double begin, double end, double skip) { std::lock_guard lock(m_mutex); - std::shared_ptr entry = std::shared_ptr(new SequenceEntry(sound, begin, end, skip, std::shared_ptr(this), m_id++)); + std::shared_ptr entry = std::shared_ptr(new SequenceEntry(sound, begin, end, skip, sequence_data, m_id++)); m_entries.push_back(entry); m_entry_status++; -- 2.30.2 From d475fb0cea625b240b7fd5d86ea46a357877c7f4 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 5 Apr 2023 23:54:44 +0200 Subject: [PATCH 07/13] Fix incorrect seeking when strip has start offset --- extern/audaspace/src/sequence/SequenceHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp index 2f3bdba8cb5..16f241e742a 100644 --- a/extern/audaspace/src/sequence/SequenceHandle.cpp +++ b/extern/audaspace/src/sequence/SequenceHandle.cpp @@ -251,7 +251,7 @@ bool SequenceHandle::seek(double position) double target_frame = 0; if(pitch_property != nullptr) { - int frame_start = m_entry->m_begin * m_entry->m_sequence_data->getFPS(); + int frame_start = (m_entry->m_begin + m_entry->m_skip) * m_entry->m_sequence_data->getFPS(); int i = 0; while(seek_frame > 0) { -- 2.30.2 From cf00b351a8d522fa35d8b4625d190f973dbc2d19 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Thu, 6 Apr 2023 22:26:56 +0200 Subject: [PATCH 08/13] Rename functions as suggested --- extern/audaspace/bindings/C/AUD_Sequence.cpp | 4 ++-- extern/audaspace/bindings/C/AUD_Sequence.h | 2 +- extern/audaspace/include/sequence/AnimateableProperty.h | 2 +- extern/audaspace/src/sequence/AnimateableProperty.cpp | 2 +- source/blender/blenkernel/intern/sound.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extern/audaspace/bindings/C/AUD_Sequence.cpp b/extern/audaspace/bindings/C/AUD_Sequence.cpp index d4ac05a4bae..4e60a2902f2 100644 --- a/extern/audaspace/bindings/C/AUD_Sequence.cpp +++ b/extern/audaspace/bindings/C/AUD_Sequence.cpp @@ -165,10 +165,10 @@ AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, double begin, doub (*entry)->move(begin, end, skip); } -AUD_API void AUD_SequenceEntry_setAnimationData_constant_range(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data) +AUD_API void AUD_SequenceEntry_setConstantRangeAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data) { AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast(type)); - prop->write_constant_range(data, frame_start, frame_end); + prop->writeConstantRange(data, frame_start, frame_end); } AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated) diff --git a/extern/audaspace/bindings/C/AUD_Sequence.h b/extern/audaspace/bindings/C/AUD_Sequence.h index 11b9206e5cb..57075f3a1cb 100644 --- a/extern/audaspace/bindings/C/AUD_Sequence.h +++ b/extern/audaspace/bindings/C/AUD_Sequence.h @@ -72,7 +72,7 @@ extern AUD_API void AUD_Sequence_remove(AUD_Sound* sequence, AUD_SequenceEntry* * \param frame_end End of the frame range. * \param data The data to write. */ -AUD_API void AUD_SequenceEntry_setAnimationData_constant_range(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data); +AUD_API void AUD_SequenceEntry_setConstantRangeAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame_start, int frame_end, float* data); /** * Writes animation data to a sequenced entry. diff --git a/extern/audaspace/include/sequence/AnimateableProperty.h b/extern/audaspace/include/sequence/AnimateableProperty.h index 6ee7bac9f31..d14990b6867 100644 --- a/extern/audaspace/include/sequence/AnimateableProperty.h +++ b/extern/audaspace/include/sequence/AnimateableProperty.h @@ -118,7 +118,7 @@ public: * \param position_start The start position in the animation in frames. * \param position_end The end position in the animation in frames. */ - void write_constant_range(const float* data, int position_start, int position_end); + void writeConstantRange(const float* data, int position_start, int position_end); /** * Reads the properties value. diff --git a/extern/audaspace/src/sequence/AnimateableProperty.cpp b/extern/audaspace/src/sequence/AnimateableProperty.cpp index d67b2d7bf82..26c50f9c815 100644 --- a/extern/audaspace/src/sequence/AnimateableProperty.cpp +++ b/extern/audaspace/src/sequence/AnimateableProperty.cpp @@ -65,7 +65,7 @@ void AnimateableProperty::write(const float* data) std::memcpy(getBuffer(), data, m_count * sizeof(float)); } -void AnimateableProperty::write_constant_range(const float* data, int position_start, int position_end) +void AnimateableProperty::writeConstantRange(const float* data, int position_start, int position_end) { assureSize(position_end * m_count * sizeof(float), true); float* buf = getBuffer(); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index ce1f8bf17af..9cfba38bc97 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -824,7 +824,7 @@ void BKE_sound_set_scene_sound_pitch_constant_range(void *handle, int frame_end, float pitch) { - AUD_SequenceEntry_setAnimationData_constant_range( + AUD_SequenceEntry_setConstantRangeAnimationData( handle, AUD_AP_PITCH, frame_start, frame_end, &pitch); } -- 2.30.2 From 788512fb0266440a0fd1b6cd234a4a20bd1cfafe Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Thu, 6 Apr 2023 23:32:24 +0200 Subject: [PATCH 09/13] Fix incorrect seeking when retimed sound is outside of strip boundary. --- extern/audaspace/src/sequence/SequenceHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/audaspace/src/sequence/SequenceHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp index 16f241e742a..e5f1e1d6f8d 100644 --- a/extern/audaspace/src/sequence/SequenceHandle.cpp +++ b/extern/audaspace/src/sequence/SequenceHandle.cpp @@ -251,7 +251,7 @@ bool SequenceHandle::seek(double position) double target_frame = 0; if(pitch_property != nullptr) { - int frame_start = (m_entry->m_begin + m_entry->m_skip) * m_entry->m_sequence_data->getFPS(); + int frame_start = (m_entry->m_begin - m_entry->m_skip) * m_entry->m_sequence_data->getFPS(); int i = 0; while(seek_frame > 0) { -- 2.30.2 From 2c03048513d58f0e391c035061a02737cf2fed92 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Fri, 7 Apr 2023 00:09:19 +0200 Subject: [PATCH 10/13] remove unused argument --- source/blender/sequencer/intern/strip_retiming.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index f42bee2051c..023ef0a3dbf 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -284,7 +284,7 @@ class RetimingRange { class RetimingRangeData { public: std::vector ranges; - RetimingRangeData(const Scene *scene, const Sequence *seq) + RetimingRangeData(const Sequence *seq) { MutableSpan handles = SEQ_retiming_handles_get(seq); for (const SeqRetimingHandle &handle : handles) { @@ -350,14 +350,14 @@ class RetimingRangeData { static RetimingRangeData seq_retiming_range_data_get(const Scene *scene, const Sequence *seq) { - RetimingRangeData strip_retiming_data = RetimingRangeData(scene, seq); + RetimingRangeData strip_retiming_data = RetimingRangeData(seq); const Sequence *meta_parent = seq_sequence_lookup_meta_by_seq(scene, seq); if (meta_parent == nullptr) { return strip_retiming_data; } - RetimingRangeData meta_retiming_data = RetimingRangeData(scene, meta_parent); + RetimingRangeData meta_retiming_data = RetimingRangeData(meta_parent); strip_retiming_data *= meta_retiming_data; return strip_retiming_data; } -- 2.30.2 From e696b2f86d18bf6cdc793f1df34fd98e593221c0 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 19 Apr 2023 15:58:04 +0200 Subject: [PATCH 11/13] Address feedback --- .../sequencer/intern/strip_retiming.cc | 71 +++++++++---------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index 023ef0a3dbf..8e2ca1dbf34 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -13,6 +13,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_span.hh" +#include "BLI_vector.hh" #include "BKE_fcurve.h" #include "BKE_movieclip.h" @@ -283,7 +284,7 @@ class RetimingRange { class RetimingRangeData { public: - std::vector ranges; + blender::Vector ranges; RetimingRangeData(const Sequence *seq) { MutableSpan handles = SEQ_retiming_handles_get(seq); @@ -297,50 +298,48 @@ class RetimingRangeData { 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); + ranges.append(range); } } RetimingRangeData &operator*=(const RetimingRangeData rhs) { - if (ranges.size() == 0) { + if (ranges.is_empty()) { for (const RetimingRange &rhs_range : rhs.ranges) { RetimingRange range = RetimingRange(rhs_range.start, rhs_range.end, rhs_range.speed); - ranges.push_back(range); + ranges.append(range); + return *this; } } - else { - 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(ranges.begin() + i, range_left); - } - else if (range.intersect_type(rhs_range) == range.PARTIAL_END) { - RetimingRange range_left = RetimingRange( - range.start, rhs_range.start - 1, range.speed); - range.start = rhs_range.start; - ranges.insert(ranges.begin() + i, range_left); - } - else if (range.intersect_type(rhs_range) == range.INSIDE) { - RetimingRange range_left = RetimingRange( - range.start, rhs_range.start - 1, range.speed); - RetimingRange range_mid = RetimingRange( - rhs_range.start, rhs_range.start, rhs_range.speed * range.speed); - range.start = rhs_range.end + 1; - ranges.insert(ranges.begin() + i, range_left); - ranges.insert(ranges.begin() + i, range_mid); - break; - } + + 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(i, range_left); + } + else if (range.intersect_type(rhs_range) == range.PARTIAL_END) { + RetimingRange range_left = RetimingRange(range.start, rhs_range.start - 1, range.speed); + range.start = rhs_range.start; + ranges.insert(i, range_left); + } + else if (range.intersect_type(rhs_range) == range.INSIDE) { + RetimingRange range_left = RetimingRange(range.start, rhs_range.start - 1, range.speed); + RetimingRange range_mid = RetimingRange( + rhs_range.start, rhs_range.start, rhs_range.speed * range.speed); + range.start = rhs_range.end + 1; + ranges.insert(i, range_left); + ranges.insert(i, range_mid); + break; } } } -- 2.30.2 From b92d912f59e243d11c12a20c9cead3eac56a1010 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 19 Apr 2023 16:30:54 +0200 Subject: [PATCH 12/13] Fix mistake in last commit --- source/blender/sequencer/intern/strip_retiming.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index 8e2ca1dbf34..0c9c859f6ad 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -308,8 +308,8 @@ class RetimingRangeData { for (const RetimingRange &rhs_range : rhs.ranges) { RetimingRange range = RetimingRange(rhs_range.start, rhs_range.end, rhs_range.speed); ranges.append(range); - return *this; } + return *this; } for (int i = 0; i < ranges.size(); i++) { -- 2.30.2 From 89512d71284d2038587573e3a6fd7260bf4f0067 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 19 Apr 2023 18:29:46 +0200 Subject: [PATCH 13/13] Fix sound strip length not changing --- source/blender/sequencer/intern/strip_time.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index a983e87dc31..a78bdc33cf5 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -503,10 +503,6 @@ bool SEQ_time_has_still_frames(const Scene *scene, const Sequence *seq) int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq) { - if (seq->type == SEQ_TYPE_SOUND_RAM) { - return seq->len; - } - if (SEQ_retiming_is_active(seq)) { SeqRetimingHandle *handle_start = seq->retiming_handles; SeqRetimingHandle *handle_end = seq->retiming_handles + (SEQ_retiming_handles_count(seq) - 1); -- 2.30.2