Skip to content

Add Waveform overview widget with playhead and loop region - #514

Merged
matt-edmondson merged 2 commits into
mainfrom
claude/project-thread-ik2011
Sep 29, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
claude/project-thread-ik2011

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Requested by Matt · project thread

Before: ktsu.ImGui.Widgets could plot one short audio block (Scope), but it had nothing for showing a whole clip with a playhead and a loop region.

After: ImGuiWidgets.Waveform draws a waveform overview of a whole clip. Click or drag to seek, drag either loop edge to move it, and Shift-drag to draw a new loop. The return value is a WaveformChange flag that says whether the playhead or the loop moved.

The widget takes a min/max peak overview rather than the samples themselves, the same way Histogram takes bins, so a full scan of the audio never runs on the render thread. ImGuiWidgets.ComputeWaveformPeaks builds the overview from samples.

How. WaveformState holds the gestures (scrub, loop-edge drag, loop creation) with no ImGui dependency. It passes the loop edges to HandleTrackState, so they stay ordered, inside the timeline and at least minLoopLength apart by the same rules as a HandleTrack. When the overview has more columns than the box has pixels, each pixel draws every column it covers, so a spike narrower than a pixel still shows. A loop whose start equals its end counts as no loop: it isn't drawn, its edges can't be grabbed, and a press there seeks.

Also in this PR:

  • 17 unit tests for the state class and the peak reduction.
  • 9 isolation UI tests in tests/ImGui.Widgets.UITests/WaveformTests.cs.
  • A demo section with play, loop and clear-loop controls, plus one test in the widgets demo suite.
  • CLAUDE.md and both READMEs list the new widget.

Refs #504. Zoom and scroll across long clips, with a peak cache per zoom level, aren't in this PR. This PR only shows the whole clip at once, so #504 stays open for that follow-up.

🤖 Generated with Claude Code

https://claude.ai/code/session_018eaHgBMKfrdgMk4HbgrL22


Generated by Claude Code

Draws a caller-supplied min/max peak overview, reduced to the box's pixel
width without dropping peaks. Click or drag seeks the playhead, loop edges
drag through HandleTrackState, and Shift-drag draws a new loop.
ComputeWaveformPeaks builds the overview from samples.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018eaHgBMKfrdgMk4HbgrL22
@matt-edmondson matt-edmondson self-assigned this Sep 29, 2026
Comment thread ImGui.Widgets/WaveformState.cs Fixed
Comment thread ImGui.Widgets/WaveformState.cs Fixed
Comment thread ImGui.Widgets/WaveformState.cs Fixed
Comment thread ImGui.Widgets/WaveformState.cs Fixed
Comment thread ImGui.Widgets/WaveformState.cs Fixed
Replaces the exact == checks flagged by code quality with a helper that
compares against float.Epsilon, keeping the same exact-change behaviour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018eaHgBMKfrdgMk4HbgrL22
@sonarqubecloud

Copy link
Copy Markdown

1 similar comment
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants