diff options
Diffstat (limited to 'tools/mq_editor/README.md')
| -rw-r--r-- | tools/mq_editor/README.md | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/tools/mq_editor/README.md b/tools/mq_editor/README.md index 0ef2e72..78986bf 100644 --- a/tools/mq_editor/README.md +++ b/tools/mq_editor/README.md @@ -17,7 +17,7 @@ open tools/mq_editor/index.html - **Top bar:** title + loaded filename - **Toolbar:** file, extraction, playback controls and parameters - **Main view:** log-scale time-frequency spectrogram with partial trajectories -- **Right panel:** synthesis checkboxes (integrate phase, disable jitter, disable spread) +- **Right panel:** per-partial mode toggle (Sinusoid / Resonator), synth params, global checkboxes - **Mini-spectrum** (bottom-right overlay): FFT slice at mouse/playhead time - Blue/orange gradient: original spectrum; green/yellow: synthesized - Green bars: detected spectral peaks @@ -49,7 +49,7 @@ open tools/mq_editor/index.html - `editor.js` — Property panel and amplitude bezier editor for selected partials - `fft.js` — Cooley-Tukey radix-2 FFT + STFT cache - `mq_extract.js` — MQ algorithm: peak detection, forward tracking, backward expansion, bezier fitting -- `mq_synth.js` — Oscillator bank synthesis from extracted partials +- `mq_synth.js` — Oscillator bank + two-pole resonator synthesis from extracted partials - `viewer.js` — Visualization: coordinate API, spectrogram, partials, mini-spectrum, mouse/zoom ### viewer.js coordinate API @@ -65,6 +65,45 @@ open tools/mq_editor/index.html | `normalizeDB(db, maxDB)` | dB → intensity [0..1] over 80 dB range | | `partialColor(p)` | partial index → display color | +## Resonator Synthesis Mode + +Each partial has a **per-partial synthesis mode** selectable in the **Synth** tab: + +### Sinusoid (default) +Replica oscillator bank — direct additive sinusoids with optional spread/jitter/decay shaping. + +### Resonator +Two-pole IIR bandpass resonator driven by band-limited noise: + +``` +y[n] = 2r·cos(ω₀)·y[n-1] − r²·y[n-2] + A(t)·√(1−r²)·noise[n] +``` + +- **ω₀** = `2π·f₀(t)/SR` — recomputed each sample from the freq Bezier curve (handles glides/vibrato) +- **A(t)** — amp Bezier curve scales excitation continuously +- **√(1−r²)** — power normalization, keeps output level ≈ sinusoidal mode at `gainComp = 1` +- **noise[n]** — deterministic per-partial LCG (reproducible renders) + +**Parameters:** + +| Param | Default | Range | Meaning | +|-------|---------|-------|---------| +| `r (pole)` | 0.995 | [0, 0.9999] | Pole radius. r→1 = narrow BW / long ring. r→0 = wide / fast decay. | +| `gain` | 1.0 | [0, ∞) | Output multiplier on top of power normalization. | + +**Coefficient translation from spread:** +`r = exp(−π · BW / SR)` where `BW = f₀ · (spread_above + spread_below) / 2`. +For a partial at 440 Hz with `spread = 0.02`: `BW ≈ 8.8 Hz`, `r ≈ exp(−π·8.8/32000) ≈ 0.9991`. + +**When to use:** +- Metallic / percussive partials with natural exponential decay +- Wide spectral peaks (large spread) where a bandpass filter is more physically accurate +- Comparing resonator vs. sinusoidal timbre on the same partial + +**Note:** `RES` badge appears in the panel header when a partial is in resonator mode. + +--- + ## Algorithm 1. **STFT:** Overlapping Hann windows, radix-2 FFT @@ -93,6 +132,7 @@ open tools/mq_editor/index.html - [x] Synth params with jog sliders (decay, jitter, spread) - [x] Auto-spread detection per partial and global - [x] Mute / delete partials + - [x] Per-partial resonator synthesis mode (Synth tab toggle) - [ ] Phase 4: Export (.spec + C++ code generation) ## See Also |
