Skip to content

Fatal crash with multi-channel audio interfaces (e.g. Scarlett 18i20) #8766

Description

@stevenwritescode

Summary

Decentraland Explorer crashes with a fatal WebRTC assertion when a multi-channel audio interface is selected as the input device. The crash is instant and unrecoverable — the process aborts.

Environment

  • OS: macOS (Darwin 25.2.0)
  • Audio Device: Focusrite Scarlett 18i20, connected via docking station
  • Explorer: Unity-based Decentraland Explorer (latest)

Error

Fatal error in: ../api/audio/audio_frame.cc, line 75
last system error: 0
Check failed: num_channels <= kMaxConcurrentChannels (20 vs. 8)

Full stack trace includes GPUI Pro NullReferenceException during the crash unwind, but the root cause is the WebRTC audio frame assertion.

Steps to Reproduce

  1. Connect a multi-channel audio interface (e.g. Focusrite Scarlett 18i20) to the system
  2. Select it as the input device in Decentraland's audio settings
  3. The client crashes immediately

If the multi-channel interface was previously selected, the client will remember this preference and automatically select it again on next launch. In this case, the crash occurs as soon as a scene loads — before the user has a chance to change the audio setting.

Confirmed Behavior

  • The crash only occurs when the multi-channel device is actively selected as the input device
  • Simply having the interface connected does not cause the crash
  • Switching to MacBook internal mic in Decentraland settings, then restarting the client, resolves the crash — even with the Scarlett plugged in and turned on
  • Switching back to the Scarlett as input while logged in immediately crashes the client again

Root Cause

The Rust audio capture layer (RustAudio/rust-audio/src/lib.rs in decentraland/client-sdk-unity) uses cpal to open the selected input device and selects the first F32-compatible config via with_max_sample_rate().config(). This takes whatever channel count the device reports with no clamping.

This channel count flows through unchanged:

  1. rust_audio_input_stream_new_internal() → returns config.channels as u32
  2. MicrophoneInfo.channels (C#)
  3. MicrophoneRtcAudioSource → sets NumChannels = deviceMicrophoneAudioSource.MicrophoneInfo.channels
  4. LiveKit FFI → WebRTC AudioFrame
  5. RTC_CHECK_LE(num_channels, kMaxConcurrentChannels) — fatal assertion fails because the channel count exceeds 8

Voice chat only needs mono or stereo — there is no reason to pass the device's full channel count into the WebRTC pipeline.

Proposed Fix

Clamp the channel count to stereo at the audio capture level (see decentraland/client-sdk-unity#67):

Rust side (lib.rs) — prevents cpal from capturing unnecessary channels:

let mut config = supported_config.with_max_sample_rate().config();
config.channels = config.channels.min(2);

C# side (MicrophoneRtcAudioSource.cs) — defensive clamp before passing to LiveKit:

NumChannels = Math.Min(deviceMicrophoneAudioSource.MicrophoneInfo.channels, 2);

Affected Devices

Any multi-channel audio interface with >8 channels would trigger this crash when selected as input. Common examples:

  • Focusrite Scarlett 18i20
  • Universal Audio Apollo x8/x16
  • MOTU 828/1248 series
  • RME Fireface/Babyface series
  • Any aggregate audio device combining multiple inputs

Workaround

If the client is crashing on launch due to a saved device preference:

  1. Turn off or unplug the multi-channel audio interface
  2. Launch the client — it will fall back to a different input device since the saved one is unavailable
  3. Go into Decentraland's audio settings and switch to a different input device (e.g. MacBook internal mic)
  4. The interface can now be turned back on or reconnected safely, as long as it is not re-selected as the input device

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions