Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion native-bridge/src/audio/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,13 +928,17 @@ impl AudioEngine {
// NO LOGGING IN THIS FUNCTION - logging allocates memory which kills ASIO

// Get channel config
// CRITICAL: Default to mono (is_stereo=false) if config cannot be read
// This ensures mono input sounds centered rather than panned left/right
let (left_ch, right_ch, is_stereo) = if let Ok(state) = processing_state.try_read() {
let left = state.channel_config.left_channel as usize;
let right = state.channel_config.right_channel.unwrap_or(1) as usize;
let stereo = state.channel_config.channel_count == 2;
(left, right, stereo)
} else {
(0, 1, true)
// Default to mono mode (channel 0 duplicated to both L/R = centered)
// This is safer than stereo which could cause panning issues
(0, 0, false)
};

// Clear and reuse the pre-allocated stereo buffer (no allocation!)
Expand Down
2 changes: 1 addition & 1 deletion native-bridge/src/effects/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl Eq {

let filter_type = match band_settings.band_type {
EqBandType::Lowshelf => BiquadType::LowShelf,
EqBandType::Peak => BiquadType::Peak,
EqBandType::Peak | EqBandType::Peaking => BiquadType::Peak,
EqBandType::Highshelf => BiquadType::HighShelf,
};

Expand Down
2 changes: 1 addition & 1 deletion native-bridge/src/effects/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1509,7 +1509,7 @@ pub struct MultibandCompressorSettings {
fn default_mb_low() -> f32 { 200.0 }
fn default_mb_high() -> f32 { 2000.0 }

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CompressorBand {
#[serde(default = "default_true")]
Expand Down
53 changes: 53 additions & 0 deletions src/hooks/useNativeBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ export function useNativeBridge() {
// Use refs to track initialization
const initialized = useRef(false);

// Ref to hold startAudio function for auto-start
const startAudioRef = useRef<(() => Promise<void>) | null>(null);

// Single useEffect for setup - runs once on mount
useEffect(() => {
if (initialized.current) return;
Expand Down Expand Up @@ -247,6 +250,49 @@ export function useNativeBridge() {
};
}, []); // Empty dependency array - run once

// Auto-start native bridge when room is connected and bridge is preferred
// This ensures users don't have to manually start audio after joining a room
useEffect(() => {
// Subscribe to room store for connection changes
const unsubscribeRoom = useRoomStore.subscribe((roomState) => {
const bridgeState = useBridgeAudioStore.getState();

// Check if we should auto-start: room connected + bridge connected + bridge preferred + not already running
if (
roomState.isConnected &&
bridgeState.isConnected &&
bridgeState.preferNativeBridge &&
!bridgeState.isRunning
) {
console.log('[useNativeBridge] Room connected with bridge preferred, auto-starting audio...');
// Use a small delay to ensure all other initialization has completed
setTimeout(async () => {
// Re-check conditions in case they changed
const latestBridge = useBridgeAudioStore.getState();
const latestRoom = useRoomStore.getState();
if (
latestRoom.isConnected &&
latestBridge.isConnected &&
latestBridge.preferNativeBridge &&
!latestBridge.isRunning &&
startAudioRef.current
) {
console.log('[useNativeBridge] Executing auto-start via ref...');
try {
await startAudioRef.current();
} catch (err) {
console.error('[useNativeBridge] Auto-start failed:', err);
}
}
}, 500);
}
});

return () => {
unsubscribeRoom();
};
}, []);

// Connect to bridge
const connect = useCallback(async () => {
console.log('[useNativeBridge] Manual connect requested');
Expand Down Expand Up @@ -460,6 +506,7 @@ export function useNativeBridge() {
isMuted: track.isMuted,
isSolo: track.isSolo,
volume: track.volume,
pan: track.pan ?? 0,
inputGainDb: track.audioSettings.inputGain || 0,
monitoringEnabled: directMonitoring,
monitoringVolume: track.audioSettings.monitoringVolume ?? 1,
Expand All @@ -470,6 +517,11 @@ export function useNativeBridge() {
}
}, []);

// Update ref whenever startAudio changes (for auto-start feature)
useEffect(() => {
startAudioRef.current = startAudio;
}, [startAudio]);

// Stop audio
const stopAudio = useCallback(() => {
const state = useBridgeAudioStore.getState();
Expand Down Expand Up @@ -591,6 +643,7 @@ export function useNativeBridge() {
isMuted: track.isMuted,
isSolo: track.isSolo,
volume: track.volume,
pan: track.pan ?? 0,
inputGainDb: track.audioSettings.inputGain || 0,
monitoringEnabled: track.audioSettings.directMonitoring ?? true,
monitoringVolume: track.audioSettings.monitoringVolume ?? 1,
Expand Down
Loading