drum-sample-extractor / docs /IMMEDIATE_WAVEFORM_AND_REAL_PROGRESS.md
ChatGPT
feat: show uploaded waveform and real progress
7f1f066
|
Raw
History Blame Contribute Delete
3.35 kB

Immediate waveform and real progress visualization

Goal

The application should no longer feel like a blank control surface after a file is selected. Loading audio is now the first visible step: the browser decodes the uploaded file locally and draws its waveform before the backend extraction job starts.

During extraction, the waveform doubles as the progress surface. The completed portion of the pipeline is rendered over the left side of the uploaded waveform in the accent color; the remaining portion stays neutral.

Implementation

Browser-side uploaded waveform

web/app.js builds an overview directly from the selected File using Web Audio:

  1. read the file with File.arrayBuffer();
  2. decode with AudioContext.decodeAudioData();
  3. scan all decoded channels into a fixed-size peak envelope;
  4. render that envelope immediately on #waveform;
  5. keep the uploaded file as the Source transport target.

No backend round-trip is needed for this first waveform.

Real progress contract

Backend job payloads now include a top-level progress object:

{
  "fraction": 0.1875,
  "completed_steps": 1,
  "total_steps": 8,
  "completed_units": 12.0,
  "total_units": 64.0,
  "stage_key": "stem",
  "stage_label": "Stem extraction / source load",
  "stage_fraction": 0.5,
  "stage_work_done": 4,
  "stage_work_total": 8,
  "basis": "exact completed work units: Demucs chunks when available, otherwise stage boundary units; no time-based estimates"
}

The UI uses this object as-is. It does not animate guessed progress and does not estimate ETA.

Demucs/stem progress

sample_extractor.extract_stem() now accepts progress_cb. For separated-stem Demucs runs, the code computes the exact number of split chunks from model segment length, overlap, input length, and shift count. A small progress pool reports each completed chunk.

For stem=all or cache hits, stem progress is reported as a completed single unit because no chunked separation work is performed.

Stage progress

pipeline_runner.StageTiming now includes:

  • progress
  • work_done
  • work_total

Stages without internal chunk progress only update at exact boundaries: started and done. This is intentional. The app must show real state, not simulated activity.

Waveform progress rendering

drawWaveform() renders the same waveform in two colors during active jobs:

  • neutral waveform: work not yet completed;
  • accent waveform clipped from the left: exact backend progress fraction;
  • vertical accent boundary: current progress point.

After completion, the waveform returns to the normal extracted overview with onset markers.

UX flow

A new Start here panel in the left sidebar makes the flow explicit:

  1. Load audio.
  2. Set controls.
  3. Extract.
  4. Review/export.

The active step is updated from actual UI/job state.

Limitations

  • The global fraction is a deterministic work-unit fraction: Demucs chunks when available, otherwise one boundary unit per stage. It is not elapsed-time prediction.
  • Demucs progress is chunk-accurate for the internal split chunks used by the Python API path.
  • Non-Demucs stages currently expose exact boundary progress only; adding finer-grained progress to onset detection and clustering requires breaking those algorithms into explicit callback-reporting loops.