diff --git a/native-bridge/src/audio/engine.rs b/native-bridge/src/audio/engine.rs index 8e212b28..ee581ce7 100644 --- a/native-bridge/src/audio/engine.rs +++ b/native-bridge/src/audio/engine.rs @@ -987,18 +987,26 @@ impl AudioEngine { false // Default to not muted - let audio through }; - // DRY monitoring: hardware bypass for zero-latency monitoring + // WET monitoring: apply effects chain for local monitoring let should_monitor = monitoring_enabled && !is_muted; if should_monitor { - if let Ok(state) = processing_state.try_read() { + if let Ok(mut state) = processing_state.try_write() { let gain = state.track_state.input_gain_linear(); let volume = state.track_state.volume; let (pan_left, pan_right) = state.track_state.pan_gains(); - // Apply gain, volume, and pan to stereo pairs + // Apply input gain first + for sample in stereo_buffer.iter_mut() { + *sample *= gain; + } + + // Process through effects chain (if any effects are enabled) + state.effects_chain.process(stereo_buffer); + + // Apply volume, pan, and monitoring volume to stereo pairs for chunk in stereo_buffer.chunks_exact_mut(2) { - let base_gain = gain * volume * mon_vol; + let base_gain = volume * mon_vol; chunk[0] *= base_gain * pan_left; chunk[1] *= base_gain * pan_right; } diff --git a/native-bridge/src/effects/types.rs b/native-bridge/src/effects/types.rs index c9716f05..6594d24b 100644 --- a/native-bridge/src/effects/types.rs +++ b/native-bridge/src/effects/types.rs @@ -6,21 +6,36 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct EffectsSettings { - // Base effects (15) + // Base effects (15) - all have defaults so partial updates work + #[serde(default)] pub wah: WahSettings, + #[serde(default)] pub overdrive: OverdriveSettings, + #[serde(default)] pub distortion: DistortionSettings, + #[serde(default)] pub amp: AmpSettings, + #[serde(default)] pub cabinet: CabinetSettings, + #[serde(default)] pub noise_gate: NoiseGateSettings, + #[serde(default)] pub eq: EqSettings, + #[serde(default)] pub compressor: CompressorSettings, + #[serde(default)] pub chorus: ChorusSettings, + #[serde(default)] pub flanger: FlangerSettings, + #[serde(default)] pub phaser: PhaserSettings, + #[serde(default)] pub delay: DelaySettings, + #[serde(default)] pub tremolo: TremoloSettings, + #[serde(default)] pub reverb: ReverbSettings, + #[serde(default)] pub limiter: LimiterSettings, // Extended effects (20) #[serde(default)] diff --git a/src/components/daw/native-bridge-gate.tsx b/src/components/daw/native-bridge-gate.tsx index b15ab693..965d5d0e 100644 --- a/src/components/daw/native-bridge-gate.tsx +++ b/src/components/daw/native-bridge-gate.tsx @@ -72,16 +72,8 @@ export function NativeBridgeGate({ } }; - // If already connected and running, auto-proceed - useEffect(() => { - if (isConnected && isRunning) { - // Small delay to show the success state - const timer = setTimeout(() => { - onJoinAsPerformer(); - }, 500); - return () => clearTimeout(timer); - } - }, [isConnected, isRunning, onJoinAsPerformer]); + // Note: We don't auto-proceed anymore - user should explicitly click "Join as Performer" + // Audio starts AFTER joining, so isRunning will be false on this screen return (
@@ -229,21 +221,21 @@ export function NativeBridgeGate({ {/* Join Options */}
- {/* Performer option */} + {/* Performer option - only requires connection, audio starts after joining */}