Skip to content

Per-bin spectral flux tracking + streaming WSOLA-PV hybrid overlay#2

Closed
robmorgan wants to merge 46 commits intomainfrom
persistent-hybrid-engine
Closed

Per-bin spectral flux tracking + streaming WSOLA-PV hybrid overlay#2
robmorgan wants to merge 46 commits intomainfrom
persistent-hybrid-engine

Conversation

@robmorgan
Copy link
Copy Markdown
Owner

@robmorgan robmorgan commented Mar 24, 2026

Summary

Major quality improvements to the streaming time-stretch engine through two key techniques:

  1. Per-bin spectral flux tracking in the phase vocoder — tracks frequency-domain changes per bin to drive a flux-adaptive resample blend (2-10%, modulated by impulsiveness), improving transient fidelity.

  2. Streaming WSOLA-PV hybrid overlay — runs WSOLA in parallel on transient input and crossfades it over the phase vocoder output, with full cross-chunk carry-over for continuity. This is the main driver of quality gains, especially for percussive and EDM content.

Tuning & refinements

  • 3-tier ratio-adaptive WSOLA overlay: pure WSOLA at extreme ratios (≥0.8 distance from unity), scaled blend at moderate/normal ratios
  • Per-overlay energy normalization: boost-only gain matching between PV and WSOLA paths
  • High-shelf filter on WSOLA overlay: corrects spectral centroid drift from time-domain stretching
  • HF energy-driven shelf: adaptive high-frequency correction gated by energy gain, with EMA smoothing
  • Mid-band bandpass boost (500-2000 Hz): centroid correction in the mid-range
  • Ratio-adaptive EMA alpha: faster smoothing at extreme stretch ratios (0.12 vs 0.05 near-unity)
  • Two-region gain factor: 50% shelf for near-unity energy gain, improving harmonic content preservation

Score improvements

  • Overall: ~954 → ~970 (+16 points)
  • EDM: ~967 → ~973 (+6 points)
  • Percussive: ~926 → ~957 (+31 points)
  • Harmonic: ~982 → ~983

Files changed

  • src/stream/processor.rs — WSOLA overlay engine with cross-chunk state, energy normalization, shelf filters
  • src/stretch/phase_vocoder.rs — per-bin spectral flux tracking and flux-adaptive blend
  • desktop/ — wider BPM stretch range in the desktop GUI

Test plan

  • cargo test --all-targets
  • cargo clippy --all-targets -- -D warnings
  • Run quality benchmark suite and verify score improvements hold
  • Test streaming playback in desktop app at various stretch ratios

🤖 Generated with Claude Code

…2-8%, modulated by impulsiveness). Percussive +0.8, overall +0.1.

Result: {"status":"keep","quality_score":953.9,"percussive_score":925.8,"edm_score":963.3,"harmonic_score":982}
… 926.0 (+0.2)

Result: {"status":"keep","quality_score":953.9,"percussive_score":926,"edm_score":963.2,"harmonic_score":982}
…1) with percussive held at 926.0

Result: {"status":"keep","quality_score":954,"percussive_score":926,"edm_score":963.3,"harmonic_score":982}
…et-rise boost for helper blend — overall 954.1 (+0.1), percussive 926.2

Result: {"status":"keep","quality_score":954.1,"percussive_score":926.2,"edm_score":963.3,"harmonic_score":982}
…sfade 85%→0% over PV output — 954.3 (+0.2), percussive 926.8

Result: {"status":"keep","metric":954.3,"percussive_score":926.8,"edm_score":963.3,"harmonic_score":982}
…954.5 (+0.2), percussive 927.3

Result: {"status":"keep","metric":954.5,"percussive_score":927.3,"edm_score":963.3,"harmonic_score":982}
…1 (+3.8)!

Result: {"status":"keep","metric":955.9,"percussive_score":927.3,"edm_score":967.1,"harmonic_score":982}
…eme ratios (>0.8 distance) — 956.2 (+0.3), percussive 927.9 (+0.6)

Result: {"status":"keep","quality_score":956.2,"percussive_score":927.9,"edm_score":967.1,"harmonic_score":982}
…56.4 (+0.5), EDM 967.6 (+0.5)

Result: {"status":"keep","quality_score":956.4,"percussive_score":927.9,"edm_score":967.6,"harmonic_score":982}
…ck) — 956.5 (+0.1), percussive 928.3 (+0.4)

Result: {"status":"keep","quality_score":956.5,"percussive_score":928.3,"edm_score":967.6,"harmonic_score":982}
…) — 956.8 (+0.3), percussive 929 (+0.7)

Result: {"status":"keep","quality_score":956.8,"percussive_score":929,"edm_score":967.6,"harmonic_score":982}
….1 (+0.3), percussive 929.9 (+0.9)

Result: {"status":"keep","quality_score":957.1,"percussive_score":929.9,"edm_score":967.6,"harmonic_score":982}
…mal — 957.4 (+0.3), percussive 930.7 (+0.8)

Result: {"status":"keep","quality_score":957.4,"percussive_score":930.7,"edm_score":967.6,"harmonic_score":982}
…+1.1)

Result: {"status":"keep","quality_score":957.8,"percussive_score":931.8,"edm_score":967.6,"harmonic_score":982}
Result: {"status":"keep","quality_score":958.2,"percussive_score":933,"edm_score":967.6,"harmonic_score":982}
…ussive 933.4, freq_pres 0.79

Result: {"status":"keep","quality_score":958.4,"percussive_score":933.4,"edm_score":967.6,"harmonic_score":982}
… from recovering 1.5x regression

Result: {"status":"keep","quality_score":958.5,"percussive_score":933.8,"edm_score":967.6,"harmonic_score":982}
…— 963.3 (+4.8!), percussive 946.5 (+12.7)

Result: {"status":"keep","quality_score":963.3,"percussive_score":946.5,"edm_score":967.6,"harmonic_score":982}
….8), percussive 948 (+1.5), EDM 968.3 (+0.7)

Result: {"status":"keep","quality_score":964.1,"percussive_score":948,"edm_score":968.3,"harmonic_score":982}
…0.7), EDM 968.6 (+0.3)

Result: {"status":"keep","quality_score":964.5,"percussive_score":948.7,"edm_score":968.6,"harmonic_score":982}
…e 953.7 (+5.0)

Result: {"status":"keep","quality_score":966.1,"percussive_score":953.7,"edm_score":968,"harmonic_score":982}
…8.4 (+0.4) from fixing over-amplification

Result: {"status":"keep","quality_score":966.3,"percussive_score":953.7,"edm_score":968.4,"harmonic_score":982}
…66.6 (+0.3), EDM 968.9 from centroid fix

Result: {"status":"keep","quality_score":966.6,"percussive_score":954,"edm_score":968.9,"harmonic_score":982}
…+0.4), percussive 955 (+1.0), harmonic 981.4 (-0.6)

Result: {"status":"keep","quality_score":967,"percussive_score":955,"edm_score":969.3,"harmonic_score":981.4}
…7), all categories improved

Result: {"status":"keep","quality_score":967.7,"percussive_score":956.6,"edm_score":969.4,"harmonic_score":981.9}
…percussive 957 (+0.4)

Result: {"status":"keep","quality_score":967.9,"percussive_score":957,"edm_score":969.5,"harmonic_score":982}
Result: {"status":"keep","quality_score":968,"percussive_score":957.3,"edm_score":969.4,"harmonic_score":982}
…2), harmonic 983.4 (+1.4!)

Result: {"status":"keep","quality_score":968.2,"percussive_score":957.3,"edm_score":969,"harmonic_score":983.4}
…stent shelf reduction for harmonic

Result: {"status":"keep","quality_score":968.3,"percussive_score":957.3,"edm_score":969.1,"harmonic_score":983.4}
…from better centroid correction

Result: {"status":"keep","quality_score":968.9,"percussive_score":957.3,"edm_score":970.8,"harmonic_score":983.4}
Result: {"status":"keep","quality_score":969.1,"percussive_score":957.3,"edm_score":971.3,"harmonic_score":983.4}
Result: {"status":"keep","quality_score":969.3,"percussive_score":957.3,"edm_score":971.8,"harmonic_score":983.4}
Result: {"status":"keep","quality_score":969.5,"percussive_score":957.3,"edm_score":972.3,"harmonic_score":983.4}
Result: {"status":"keep","quality_score":969.6,"percussive_score":957.3,"edm_score":972.8,"harmonic_score":983.4}
Result: {"status":"keep","quality_score":969.7,"percussive_score":957.3,"edm_score":972.9,"harmonic_score":983.4}
Result: {"status":"keep","quality_score":969.7,"percussive_score":957.3,"edm_score":973,"harmonic_score":983.4}
Result: {"status":"keep","quality_score":969.7,"percussive_score":957.3,"edm_score":973.1,"harmonic_score":983.4}
…orrection in mid-range

Result: {"status":"keep","quality_score":969.8,"percussive_score":957.3,"edm_score":973.2,"harmonic_score":983.4}
Add internal-only module scaffolding for the new persistent streaming
hybrid engine: analyzer, router, render, and mixer. All types use
absolute timeline positions instead of chunk-relative indices.

No runtime behavior changes. Existing StreamProcessor and engines
are untouched.

New types:
- StreamAnalyzer, AnalysisEvent
- HybridRouter, RoutedHybridOp, RenderPath
- PersistentTonalRenderer, PersistentTransientRenderer, ScheduledPatch
- TimelineMixer

Includes docs/persistent-streaming-hybrid-design.md describing the
migration strategy from the legacy rolling-window re-render path.
@robmorgan robmorgan changed the title Scaffold persistent streaming hybrid engine modules Per-bin spectral flux tracking + streaming WSOLA-PV hybrid overlay Mar 24, 2026
@robmorgan robmorgan closed this Mar 24, 2026
@robmorgan robmorgan deleted the persistent-hybrid-engine branch March 24, 2026 22:43
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.

1 participant