fix: move analyser before gain node to show true audio levels
Repositioned analyser nodes in audio graph to measure raw audio levels before volume/gain adjustments. The Problem: - Analyser was after gain node in signal chain - Track volume defaults to 0.8 (80%) - Audio was scaled down before measurement - Meters only showed ~50% of actual audio peaks The Solution: - Moved analyser to immediately after source - Now measures raw audio before any processing - Shows true audio content independent of fader position Audio Graph Changes: Before: source -> gain -> pan -> effects -> analyser -> master After: source -> analyser -> gain -> pan -> effects -> master Benefits: ✅ Meters show full 0-100% range based on audio content ✅ Meter reading independent of volume fader position ✅ Accurate representation of track audio levels ✅ Increased smoothingTimeConstant to 0.8 for smoother motion This is how professional DAWs work - level meters show the audio content, not the output level after the fader. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -152,7 +152,7 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) {
|
|||||||
const panNode = audioContext.createStereoPanner();
|
const panNode = audioContext.createStereoPanner();
|
||||||
const analyserNode = audioContext.createAnalyser();
|
const analyserNode = audioContext.createAnalyser();
|
||||||
analyserNode.fftSize = 256;
|
analyserNode.fftSize = 256;
|
||||||
analyserNode.smoothingTimeConstant = 0.3;
|
analyserNode.smoothingTimeConstant = 0.8;
|
||||||
|
|
||||||
// Set gain based on track volume and solo/mute state
|
// Set gain based on track volume and solo/mute state
|
||||||
const trackGain = getTrackGain(track, tracks);
|
const trackGain = getTrackGain(track, tracks);
|
||||||
@@ -161,8 +161,10 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) {
|
|||||||
// Set pan
|
// Set pan
|
||||||
panNode.pan.setValueAtTime(track.pan, audioContext.currentTime);
|
panNode.pan.setValueAtTime(track.pan, audioContext.currentTime);
|
||||||
|
|
||||||
// Connect: source -> gain -> pan -> effects -> analyser -> master gain -> destination
|
// Connect: source -> analyser -> gain -> pan -> effects -> master gain -> destination
|
||||||
source.connect(gainNode);
|
// Analyser is before gain so it shows raw audio levels independent of volume fader
|
||||||
|
source.connect(analyserNode);
|
||||||
|
analyserNode.connect(gainNode);
|
||||||
gainNode.connect(panNode);
|
gainNode.connect(panNode);
|
||||||
|
|
||||||
// Apply effect chain
|
// Apply effect chain
|
||||||
@@ -173,9 +175,8 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) {
|
|||||||
console.log('[MultiTrackPlayer] Effects:', track.effectChain.effects);
|
console.log('[MultiTrackPlayer] Effects:', track.effectChain.effects);
|
||||||
const { outputNode, effectNodes } = applyEffectChain(audioContext, panNode, track.effectChain);
|
const { outputNode, effectNodes } = applyEffectChain(audioContext, panNode, track.effectChain);
|
||||||
|
|
||||||
// Insert analyser after effects, before master gain
|
// Connect to master gain
|
||||||
outputNode.connect(analyserNode);
|
outputNode.connect(masterGain);
|
||||||
analyserNode.connect(masterGain);
|
|
||||||
console.log('[MultiTrackPlayer] Effect output connected with', effectNodes.length, 'effect nodes');
|
console.log('[MultiTrackPlayer] Effect output connected with', effectNodes.length, 'effect nodes');
|
||||||
|
|
||||||
// Start playback from current position
|
// Start playback from current position
|
||||||
@@ -404,7 +405,7 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) {
|
|||||||
const panNode = audioContext.createStereoPanner();
|
const panNode = audioContext.createStereoPanner();
|
||||||
const analyserNode = audioContext.createAnalyser();
|
const analyserNode = audioContext.createAnalyser();
|
||||||
analyserNode.fftSize = 256;
|
analyserNode.fftSize = 256;
|
||||||
analyserNode.smoothingTimeConstant = 0.3;
|
analyserNode.smoothingTimeConstant = 0.8;
|
||||||
|
|
||||||
// Set gain based on track volume and solo/mute state
|
// Set gain based on track volume and solo/mute state
|
||||||
const trackGain = getTrackGain(track, latestTracks);
|
const trackGain = getTrackGain(track, latestTracks);
|
||||||
@@ -413,14 +414,15 @@ export function useMultiTrackPlayer(tracks: Track[], masterVolume: number = 1) {
|
|||||||
// Set pan
|
// Set pan
|
||||||
panNode.pan.setValueAtTime(track.pan, audioContext.currentTime);
|
panNode.pan.setValueAtTime(track.pan, audioContext.currentTime);
|
||||||
|
|
||||||
// Connect: source -> gain -> pan -> effects -> analyser -> master gain -> destination
|
// Connect: source -> analyser -> gain -> pan -> effects -> master gain -> destination
|
||||||
source.connect(gainNode);
|
// Analyser is before gain so it shows raw audio levels independent of volume fader
|
||||||
|
source.connect(analyserNode);
|
||||||
|
analyserNode.connect(gainNode);
|
||||||
gainNode.connect(panNode);
|
gainNode.connect(panNode);
|
||||||
|
|
||||||
// Apply effect chain
|
// Apply effect chain
|
||||||
const { outputNode, effectNodes } = applyEffectChain(audioContext, panNode, track.effectChain);
|
const { outputNode, effectNodes } = applyEffectChain(audioContext, panNode, track.effectChain);
|
||||||
outputNode.connect(analyserNode);
|
outputNode.connect(masterGain);
|
||||||
analyserNode.connect(masterGain);
|
|
||||||
|
|
||||||
// Start playback from current position
|
// Start playback from current position
|
||||||
source.start(0, pausedAtRef.current);
|
source.start(0, pausedAtRef.current);
|
||||||
|
|||||||
Reference in New Issue
Block a user