From a95dd8438da1c98d91d3dd892182ebd9acfb3ce4 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Tue, 19 Dec 2023 18:52:38 +0100 Subject: [PATCH] VSE: add option to display half of audio waveform Default is "full" waveform display. Adds overlay option to display absolute value of the signal as upper half only. Part of design task #115274 Pull Request: https://projects.blender.org/blender/blender/pulls/116344 --- scripts/startup/bl_ui/space_sequencer.py | 2 ++ .../sequencer_timeline_draw.cc | 32 ++++++++++++++++--- source/blender/makesdna/DNA_space_types.h | 3 +- source/blender/makesrna/intern/rna_space.cc | 16 ++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/scripts/startup/bl_ui/space_sequencer.py b/scripts/startup/bl_ui/space_sequencer.py index 3e5492d684d..8559c33ee3a 100644 --- a/scripts/startup/bl_ui/space_sequencer.py +++ b/scripts/startup/bl_ui/space_sequencer.py @@ -324,6 +324,8 @@ class SEQUENCER_PT_sequencer_overlay(Panel): layout.label(text="Waveforms") layout.row().prop(overlay_settings, "waveform_display_type", expand=True) + layout.label(text="Waveform Style") + layout.row().prop(overlay_settings, "waveform_display_style", expand=True) class SEQUENCER_MT_view_cache(Menu): diff --git a/source/blender/editors/space_sequencer/sequencer_timeline_draw.cc b/source/blender/editors/space_sequencer/sequencer_timeline_draw.cc index 73632591c68..9a427736528 100644 --- a/source/blender/editors/space_sequencer/sequencer_timeline_draw.cc +++ b/source/blender/editors/space_sequencer/sequencer_timeline_draw.cc @@ -421,13 +421,18 @@ static void draw_seq_waveform_overlay(TimelineDrawContext *timeline_ctx, Scene *scene = timeline_ctx->scene; Sequence *seq = strip_ctx->seq; + const bool half_style = (timeline_ctx->sseq->timeline_overlay.flag & + SEQ_TIMELINE_WAVEFORMS_HALF) != 0; + const float frames_per_pixel = BLI_rctf_size_x(&v2d->cur) / timeline_ctx->region->winx; const float samples_per_frame = SOUND_WAVE_SAMPLES_PER_SECOND / FPS; const float samples_per_pixel = samples_per_frame * frames_per_pixel; - /* The y coordinate for the middle of the strip. */ - const float y_zero = (strip_ctx->bottom + strip_ctx->strip_content_top) / 2.0f; - /* The length from the middle of the strip to the top/bottom. */ - const float y_scale = (strip_ctx->strip_content_top - strip_ctx->bottom) / 2.0f; + /* The y coordinate of signal level zero. */ + const float y_zero = half_style ? strip_ctx->bottom : + (strip_ctx->bottom + strip_ctx->strip_content_top) / 2.0f; + /* The y range of unit signal level. */ + const float y_scale = half_style ? strip_ctx->strip_content_top - strip_ctx->bottom : + (strip_ctx->strip_content_top - strip_ctx->bottom) / 2.0f; /* Align strip start with nearest pixel to prevent waveform flickering. */ const float strip_start_aligned = align_frame_with_pixel(strip_ctx->left_handle, @@ -512,6 +517,25 @@ static void draw_seq_waveform_overlay(TimelineDrawContext *timeline_ctx, CLAMP_MIN(value_min, -1.0f); } + /* We are drawing only half ot the waveform, mirroring the lower part upwards. + * If both min and max are on the same side of zero line, we want to draw a bar + * between them. If min and max cross zero, we want to fill bar from zero to max + * of those. */ + if (half_style) { + bool pos_min = value_min > 0.0f; + bool pos_max = value_max > 0.0f; + float abs_min = std::abs(value_min); + float abs_max = std::abs(value_max); + if (pos_min == pos_max) { + value_min = std::min(abs_min, abs_max); + value_max = std::max(abs_min, abs_max); + } + else { + value_min = 0; + value_max = std::max(abs_min, abs_max); + } + } + float x1 = draw_start_frame + i * frames_per_pixel; float x2 = draw_start_frame + (i + 1) * frames_per_pixel; float y_min = y_zero + value_min * y_scale; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 7ba0483b6b0..f6f9677a157 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -623,6 +623,8 @@ typedef enum eSpaceSeq_SequencerTimelineOverlay_Flag { SEQ_TIMELINE_ALL_WAVEFORMS = (1 << 7), /** Draw no wave-forms. */ SEQ_TIMELINE_NO_WAVEFORMS = (1 << 8), + /** Draw only upper part of the waveform, showing absolute signal value. */ + SEQ_TIMELINE_WAVEFORMS_HALF = (1 << 9), SEQ_TIMELINE_SHOW_STRIP_NAME = (1 << 14), SEQ_TIMELINE_SHOW_STRIP_SOURCE = (1 << 15), SEQ_TIMELINE_SHOW_STRIP_DURATION = (1 << 16), @@ -712,7 +714,6 @@ typedef enum eSpaceSeq_Flag { SPACE_SEQ_FLAG_UNUSED_4 = (1 << 4), SPACE_SEQ_FLAG_UNUSED_5 = (1 << 5), SEQ_USE_ALPHA = (1 << 6), /* use RGBA display mode for preview */ - SPACE_SEQ_FLAG_UNUSED_9 = (1 << 9), SPACE_SEQ_FLAG_UNUSED_10 = (1 << 10), SEQ_SHOW_MARKERS = (1 << 11), /* show markers region */ SEQ_ZOOM_TO_FIT = (1 << 12), diff --git a/source/blender/makesrna/intern/rna_space.cc b/source/blender/makesrna/intern/rna_space.cc index 8856dbfd1db..26bea566a95 100644 --- a/source/blender/makesrna/intern/rna_space.cc +++ b/source/blender/makesrna/intern/rna_space.cc @@ -5787,6 +5787,22 @@ static void rna_def_space_sequencer_timeline_overlay(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Waveform Display", "How Waveforms are displayed"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, nullptr); + static const EnumPropertyItem waveform_style_display_items[] = { + {0, "FULL_WAVEFORMS", 0, "Full", "Display full waveform"}, + {SEQ_TIMELINE_WAVEFORMS_HALF, + "HALF_WAVEFORMS", + 0, + "Half", + "Display upper half of the absolute value waveform"}, + {0, nullptr, 0, nullptr, nullptr}, + }; + + prop = RNA_def_property(srna, "waveform_display_style", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, nullptr, "flag"); + RNA_def_property_enum_items(prop, waveform_style_display_items); + RNA_def_property_ui_text(prop, "Waveform Style", "How Waveforms are displayed"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, nullptr); + prop = RNA_def_property(srna, "show_fcurves", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", SEQ_TIMELINE_SHOW_FCURVES); RNA_def_property_ui_text(prop, "Show F-Curves", "Display strip opacity/volume curve");