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
28 changes: 26 additions & 2 deletions native-bridge/src/audio/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,22 @@ impl AudioEngine {
return Ok(());
}

info!("Setting channel config: {:?}", config);
self.config.channel_config = config.clone();
if let Ok(mut state) = self.processing_state.write() {
state.channel_config = config;

// CRITICAL: Must update processing_state - this is what the audio callback reads
// Use blocking write to ensure the config is applied
match self.processing_state.write() {
Ok(mut state) => {
state.channel_config = config;
info!("Channel config updated in processing_state");
}
Err(e) => {
// This should never happen in practice, but log if it does
tracing::error!("Failed to acquire write lock for channel config: {:?}", e);
}
}

if self.is_running.load(Ordering::SeqCst) {
self.stop()?;
self.start()?;
Expand Down Expand Up @@ -589,6 +601,18 @@ impl AudioEngine {
return Ok(());
}

// CRITICAL: Sync channel config from self.config to processing_state before starting
// This ensures the audio callback uses the correct config from the first frame
if let Ok(mut state) = self.processing_state.write() {
if state.channel_config != self.config.channel_config {
info!(
"Syncing channel config at start: {:?} -> {:?}",
state.channel_config, self.config.channel_config
);
state.channel_config = self.config.channel_config.clone();
}
}

// Create ring buffers
let local_ring = HeapRb::<f32>::new(LOCAL_RING_BUFFER_SIZE);
let (local_prod, local_cons) = local_ring.split();
Expand Down
6 changes: 6 additions & 0 deletions src/hooks/useTrackAudioSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ export function useTrackAudioSync(currentUserId: string | undefined) {

// Note: Channel config is now handled at the global level via setChannelConfig()
// Native bridge uses single-track audio capture; multi-track is handled in browser

// Sync effects to native bridge when changed
if (currentState.effects && (!lastState || lastState.effects !== currentState.effects)) {
console.log('[useTrackAudioSync] Syncing effects to native bridge for track:', track.id);
nativeBridge.updateEffects(track.id, currentState.effects);
}
}

lastSyncRef.current.set(track.id, currentState);
Expand Down
Loading