Skip to content

Conversation

@LSXPrime
Copy link
Owner

This commit introduces a major architectural refactoring to move away from a singleton-based (AudioEngine.Instance) model to a device-centric, instance-based architecture. This fundamental change enables true multi-device input and output, allowing applications to manage and switch between multiple playback and capture devices simultaneously and independently.

This refactor also includes several new features, performance improvements, and critical bug fixes that are built upon the new architecture.

Key Changes & Features

  • Multi-Device Architecture: The global AudioEngine.Instance and Mixer.Master have been removed. The new design introduces AudioPlaybackDevice, AudioCaptureDevice, and FullDuplexDevice abstractions, each managing its own audio graph and MasterMixer.
  • Explicit Context: Core components now receive AudioEngine and AudioFormat context via their constructors, removing implicit dependencies on global state.
  • Device Switching API: A new, robust Engine.SwitchDevice() API allows for seamless hot-swapping of active audio devices while preserving their state (e.g., attached components or event subscribers).
  • New VoiceIsolationEffect: Adds an experimental modifier that acts as a band-pass filter to help isolate human speech frequencies.
  • New MultiEngines Sample: A new sample project is included to demonstrate and test the new multi-device capabilities.

Fixes & Performance Improvements

  • fix(network): Refactored NetworkDataProvider to use a chunked streaming and decoding model, resolving excessive memory usage. Memory consumption for a 15-minute audio file is reduced from ~1GB to ~20MB.
  • fix(recording): Corrects a critical audio format conversion bug that produced garbled audio when recording to formats other than F32.
  • refactor(native): Unified the FFT implementations in MathHelper for Scalar, SSE, and AVX paths to ensure consistent behavior. The SIMD paths are now toggleable via static properties for easier debugging.
  • refactor(interop): The native device configuration layer now uses a comprehensive DTO, allowing for more granular control over backend-specific settings (WASAPI, ALSA, etc.).

BREAKING CHANGE: This is a fundamental architectural change that affects the entire public API.

  • AudioEngine.Instance is removed. An AudioEngine must now be instantiated (e.g., new MiniAudioEngine()).
  • Audio is no longer played by adding components to Mixer.Master. Users must first initialize a device (e.g., engine.InitializePlaybackDevice(...)) and then add components to the device's MasterMixer.
  • Constructors for nearly all SoundComponent, ISoundDataProvider, SoundModifier, and AudioAnalyzer derivatives have changed. They now require an AudioEngine and/or AudioFormat instance to be passed in.
  • The global AudioEngine.OnAudioProcessed event is removed. Events for processed audio are now available on a per-device basis (e.g., AudioCaptureDevice.OnAudioProcessed).
  • The previous SwitchDevice API is replaced with new, more explicit methods on the AudioEngine instance that return a new device object.

LSXPrime and others added 2 commits July 21, 2025 19:40
This commit introduces a major architectural refactoring to move away from a singleton-based (`AudioEngine.Instance`) model to a device-centric, instance-based architecture. This fundamental change enables true multi-device input and output, allowing applications to manage and switch between multiple playback and capture devices simultaneously and independently.

This refactor also includes several new features, performance improvements, and critical bug fixes that are built upon the new architecture.

### Key Changes & Features

- **Multi-Device Architecture**: The global `AudioEngine.Instance` and `Mixer.Master` have been removed. The new design introduces `AudioPlaybackDevice`, `AudioCaptureDevice`, and `FullDuplexDevice` abstractions, each managing its own audio graph and `MasterMixer`.
- **Explicit Context**: Core components now receive `AudioEngine` and `AudioFormat` context via their constructors, removing implicit dependencies on global state.
- **Device Switching API**: A new, robust `Engine.SwitchDevice()` API allows for seamless hot-swapping of active audio devices while preserving their state (e.g., attached components or event subscribers).
- **New `VoiceIsolationEffect`**: Adds an experimental modifier that acts as a band-pass filter to help isolate human speech frequencies.
- **New `MultiEngines` Sample**: A new sample project is included to demonstrate and test the new multi-device capabilities.

### Fixes & Performance Improvements

- **fix(network)**: Refactored `NetworkDataProvider` to use a chunked streaming and decoding model, resolving excessive memory usage. Memory consumption for a 15-minute audio file is reduced from ~1GB to ~20MB.
- **fix(recording)**: Corrects a critical audio format conversion bug that produced garbled audio when recording to formats other than F32.
- **refactor(native)**: Unified the FFT implementations in `MathHelper` for Scalar, SSE, and AVX paths to ensure consistent behavior. The SIMD paths are now toggleable via static properties for easier debugging.
- **refactor(interop)**: The native device configuration layer now uses a comprehensive DTO, allowing for more granular control over backend-specific settings (WASAPI, ALSA, etc.).

BREAKING CHANGE: This is a fundamental architectural change that affects the entire public API.

- `AudioEngine.Instance` is removed. An `AudioEngine` must now be instantiated (e.g., `new MiniAudioEngine()`).
- Audio is no longer played by adding components to `Mixer.Master`. Users must first initialize a device (e.g., `engine.InitializePlaybackDevice(...)`) and then add components to the device's `MasterMixer`.
- Constructors for nearly all `SoundComponent`, `ISoundDataProvider`, `SoundModifier`, and `AudioAnalyzer` derivatives have changed. They now require an `AudioEngine` and/or `AudioFormat` instance to be passed in.
- The global `AudioEngine.OnAudioProcessed` event is removed. Events for processed audio are now available on a per-device basis (e.g., `AudioCaptureDevice.OnAudioProcessed`).
- The previous `SwitchDevice` API is replaced with new, more explicit methods on the `AudioEngine` instance that return a new device object.
@LSXPrime LSXPrime merged commit faac823 into master Jul 21, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant