From a0a3b58b498a2eb47187339f36e3b91a107e68d0 Mon Sep 17 00:00:00 2001 From: Jose Luis Date: Sun, 22 Mar 2026 17:58:19 +0100 Subject: [PATCH] fix: envelope param animation reads source node instead of receiver Was reading the receiving module's gain.value (always 0 when CV connected) instead of the envelope's Tone.Envelope.value for live modulation display. Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/client/src/components/ModuleNode.jsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/client/src/components/ModuleNode.jsx b/packages/client/src/components/ModuleNode.jsx index 3f171e0..a5bdd03 100644 --- a/packages/client/src/components/ModuleNode.jsx +++ b/packages/client/src/components/ModuleNode.jsx @@ -107,11 +107,20 @@ export default function ModuleNode({ mod, zoom, onStartConnect, onPortPosition } newValues[paramName] = baseValue + lfoVal * scale; } else if (srcMod.type === 'envelope') { - // Envelope: read the actual audio node gain value for real-time display - const audioEntry = getAudioNode(mod.id); - if (audioEntry?.node?.gain) { - const currentGain = audioEntry.node.gain.value; - newValues[paramName] = currentGain; + // Envelope: read the envelope's current level (0-1) from the source module + const envEntry = getAudioNode(srcMod.id); + if (envEntry?.node) { + const envValue = typeof envEntry.node.value === 'number' ? envEntry.node.value : 0; + const baseValue = params[paramName]; + if (mod.type === 'vca' && paramName === 'gain') { + newValues[paramName] = envValue; // Envelope directly drives gain (0→1) + } else { + let scale; + if (mod.type === 'oscillator' && paramName === 'frequency') scale = baseValue * 0.5; + else if (mod.type === 'filter' && paramName === 'frequency') scale = baseValue; + else scale = baseValue || 1; + newValues[paramName] = baseValue + envValue * scale; + } } } }