# Phase 3: Virtual Audio Engine

**Status:** ⬜ Not Started
**Parent plan:** [PLAN.md](./PLAN.md)
**Domain:** backend

## Objective
Create a `DemoAudioEngine` that provides virtual audio devices and produces synthetic audio data, enabling audio-reactive visualizations in demo mode.

## Tasks

- [ ] Task 1: Create `server/src/wled_controller/core/audio/demo_engine.py` with `DemoAudioEngine` and `DemoAudioCaptureStream`
- [ ] Task 2: `DemoAudioEngine.ENGINE_TYPE = "demo"`, `ENGINE_PRIORITY = 1000`
- [ ] Task 3: `is_available()` returns `True` only when `is_demo_mode()` is True
- [ ] Task 4: `enumerate_devices()` returns 2 virtual devices:
  - "Demo Microphone" (input, not loopback)
  - "Demo System Audio" (loopback)
- [ ] Task 5: `DemoAudioCaptureStream` implements:
  - `channels = 2`, `sample_rate = 44100`, `chunk_size = 1024`
  - `read_chunk()` produces synthetic audio: a mix of sine waves with slowly varying frequencies to simulate music-like beat patterns
  - Returns proper float32 ndarray
- [ ] Task 6: Register `DemoAudioEngine` in `audio/__init__.py`

## Files to Modify/Create
- `server/src/wled_controller/core/audio/demo_engine.py` — New file: DemoAudioEngine + DemoAudioCaptureStream
- `server/src/wled_controller/core/audio/__init__.py` — Register DemoAudioEngine

## Acceptance Criteria
- `DemoAudioEngine.is_available()` is True only in demo mode
- Virtual audio devices appear in audio device enumeration when in demo mode
- `read_chunk()` returns valid float32 audio data that varies over time
- Audio analyzer produces non-trivial frequency band data from the synthetic signal

## Notes
- Synthetic audio should produce interesting FFT results (multiple frequencies, amplitude modulation)
- Keep it computationally lightweight
- Must conform to `AudioCaptureStreamBase` interface exactly

## Review Checklist
- [ ] All tasks completed
- [ ] Code follows project conventions
- [ ] No unintended side effects
- [ ] Build passes
- [ ] Tests pass (new + existing)

## Handoff to Next Phase
<!-- Filled in after completion -->
