diff --git a/lib/hooks/useMultiTrackPlayer.ts b/lib/hooks/useMultiTrackPlayer.ts index f92cfb0..64d8cf8 100644 --- a/lib/hooks/useMultiTrackPlayer.ts +++ b/lib/hooks/useMultiTrackPlayer.ts @@ -110,7 +110,7 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { tracks.forEach((track, index) => { // Apply volume automation const volumeLane = track.automation.lanes.find(lane => lane.parameterId === 'volume'); - if (volumeLane && volumeLane.points.length > 0 && volumeLane.mode !== 'read') { + if (volumeLane && volumeLane.points.length > 0) { const automatedValue = evaluateAutomationLinear(volumeLane.points, currentTime); if (automatedValue !== undefined && gainNodesRef.current[index]) { const trackGain = getTrackGain(track, tracks); @@ -124,7 +124,7 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { // Apply pan automation const panLane = track.automation.lanes.find(lane => lane.parameterId === 'pan'); - if (panLane && panLane.points.length > 0 && panLane.mode !== 'read') { + if (panLane && panLane.points.length > 0) { const automatedValue = evaluateAutomationLinear(panLane.points, currentTime); if (automatedValue !== undefined && panNodesRef.current[index]) { // Pan automation values are 0-1, but StereoPannerNode expects -1 to 1 @@ -136,7 +136,39 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) { } } - // TODO: Apply effect parameter automation + // Apply effect parameter automation + track.automation.lanes.forEach(lane => { + // Check if this is an effect parameter (format: effect.{effectId}.{parameterName}) + if (lane.parameterId.startsWith('effect.') && lane.points.length > 0) { + const parts = lane.parameterId.split('.'); + if (parts.length === 3) { + const effectId = parts[1]; + const paramName = parts[2]; + + // Find the effect in the track's effect chain + const effectIndex = track.effectChain.effects.findIndex(e => e.id === effectId); + if (effectIndex >= 0 && effectNodesRef.current[index] && effectNodesRef.current[index][effectIndex]) { + const automatedValue = evaluateAutomationLinear(lane.points, currentTime); + if (automatedValue !== undefined) { + const effectNodeInfo = effectNodesRef.current[index][effectIndex]; + + // Convert normalized 0-1 value to actual parameter range + const effect = track.effectChain.effects[effectIndex]; + const actualValue = lane.valueRange.min + (automatedValue * (lane.valueRange.max - lane.valueRange.min)); + + // Update the effect parameter + if (effect.parameters) { + const updatedParams = { ...effect.parameters, [paramName]: actualValue } as any; + updateEffectParameters(audioContextRef.current!, effectNodeInfo, { + ...effect, + parameters: updatedParams + }); + } + } + } + } + } + }); }); automationFrameRef.current = requestAnimationFrame(applyAutomation);