diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/mq_editor/editor.js | 2 | ||||
| -rw-r--r-- | tools/mq_editor/index.html | 30 | ||||
| -rw-r--r-- | tools/mq_editor/mq_synth.js | 6 |
3 files changed, 34 insertions, 4 deletions
diff --git a/tools/mq_editor/editor.js b/tools/mq_editor/editor.js index f57e177..97d8a7a 100644 --- a/tools/mq_editor/editor.js +++ b/tools/mq_editor/editor.js @@ -219,7 +219,7 @@ class PartialEditor { const resObj = partial.resonator || {}; const resParams = [ - { key: 'r', label: 'r (pole)', step: '0.001', min: '0', max: '0.9999', + { key: 'r', label: 'r (pole)', step: '0.001', min: '0.75', max: '0.9999', title: 'Pole radius. r→1 = narrow bandwidth / long ring. r→0 = wide / fast decay.' }, { key: 'gainComp', label: 'gain', step: '0.01', min: '0', max: '100', title: 'Output gain multiplier (gainNorm=√(1-r²) normalises power; use this to trim level).' }, diff --git a/tools/mq_editor/index.html b/tools/mq_editor/index.html index b37eaaf..c663c69 100644 --- a/tools/mq_editor/index.html +++ b/tools/mq_editor/index.html @@ -349,6 +349,19 @@ <label><input type="checkbox" id="disableJitter"> Disable jitter</label> <label><input type="checkbox" id="disableSpread"> Disable spread</label> <label title="Test mode: force resonator synthesis for all partials (ignores per-partial mode setting)"><input type="checkbox" id="forceResonator"> Resonator (all)</label> + <div id="globalResParams" style="display:none;margin-top:4px;padding:4px 0 2px 12px;border-left:2px solid #555;"> + <label style="display:flex;align-items:center;gap:6px;" title="Global pole radius r in (0,1). Applied to all partials in resonator mode."> + r (pole) + <input type="range" id="globalR" min="0.75" max="0.9999" step="0.0001" value="0.995" style="flex:1;min-width:0;"> + <span id="globalRVal" style="width:44px;text-align:right;">0.9950</span> + </label> + <label style="display:flex;align-items:center;gap:6px;" title="Global gain compensation applied to all partials in resonator mode."> + gain + <input type="range" id="globalGain" min="0.0" max="4.0" step="0.01" value="1.0" style="flex:1;min-width:0;"> + <span id="globalGainVal" style="width:44px;text-align:right;">1.00</span> + </label> + <label title="Override per-partial r/gain with global values during playback"><input type="checkbox" id="forceRGain"> force r/gain</label> + </div> <div style="margin-top:6px;"> <label style="display:flex;align-items:center;gap:6px;" title="LP filter coefficient k1 in (0,1]. 1.0 = bypass."> LP k1 @@ -403,6 +416,17 @@ const f = k2ToHz(k, getSR()); document.getElementById('hpK2Val').textContent = k >= 1.0 ? 'bypass' : fmtHz(f); }); + + // Show/hide global resonator params when forceResonator toggled + document.getElementById('forceResonator').addEventListener('change', function() { + document.getElementById('globalResParams').style.display = this.checked ? '' : 'none'; + }); + document.getElementById('globalR').addEventListener('input', function() { + document.getElementById('globalRVal').textContent = parseFloat(this.value).toFixed(4); + }); + document.getElementById('globalGain').addEventListener('input', function() { + document.getElementById('globalGainVal').textContent = parseFloat(this.value).toFixed(2); + }); let audioBuffer = null; let viewer = null; let audioContext = null; @@ -676,8 +700,12 @@ const hpK2Raw = parseFloat(document.getElementById('hpK2').value); const k1 = lpK1Raw < 1.0 ? lpK1Raw : null; const k2 = hpK2Raw < 1.0 ? hpK2Raw : null; + const forceRGain = forceResonator && document.getElementById('forceRGain').checked; + const globalR = parseFloat(document.getElementById('globalR').value); + const globalGain = parseFloat(document.getElementById('globalGain').value); const pcm = synthesizeMQ(partialsToUse, audioBuffer.sampleRate, audioBuffer.duration, - integratePhase, {disableJitter, disableSpread, forceResonator, k1, k2}); + integratePhase, {disableJitter, disableSpread, forceResonator, + forceRGain, globalR, globalGain, k1, k2}); if (viewer) { viewer.setSynthStftCache(new STFTCache(pcm, audioBuffer.sampleRate, fftSize, parseInt(hopSize.value))); diff --git a/tools/mq_editor/mq_synth.js b/tools/mq_editor/mq_synth.js index d85c890..2d4cf1b 100644 --- a/tools/mq_editor/mq_synth.js +++ b/tools/mq_editor/mq_synth.js @@ -56,8 +56,10 @@ function synthesizeMQ(partials, sampleRate, duration, integratePhase = true, opt // r controls pole radius (bandwidth): r→1 = narrow, r→0 = wide. // gainNorm = sqrt(1 - r²) normalises steady-state output power to ~A. const res = partial.resonator || {}; - const r = res.r != null ? Math.min(0.9999, Math.max(0, res.r)) : 0.995; - const gainComp = res.gainComp != null ? res.gainComp : 1.0; + const r = options.forceRGain ? Math.min(0.9999, Math.max(0, options.globalR)) + : (res.r != null ? Math.min(0.9999, Math.max(0, res.r)) : 0.995); + const gainComp = options.forceRGain ? options.globalGain + : (res.gainComp != null ? res.gainComp : 1.0); const gainNorm = Math.sqrt(Math.max(0, 1.0 - r * r)); configs.push({ mode: 'resonator', |
