# Phase 3: Processed Audio Source Model **Status:** ⬜ Not Started **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** backend ## Objective Add the `ProcessedAudioSource` type, rename `MultichannelAudioSource` to `CaptureAudioSource`, remove `MonoAudioSource` and `BandExtractAudioSource`, and update the store's resolution logic. ## Tasks - [ ] Task 1: Rename `MultichannelAudioSource` → `CaptureAudioSource` in `storage/audio_source.py` - Change class name, update `source_type` default to `"capture"` - Same fields: `device_index`, `is_loopback`, `audio_template_id` - [ ] Task 2: Add `ProcessedAudioSource` dataclass in `storage/audio_source.py` - Fields: `audio_source_id: str` (input source), `audio_processing_template_id: str` - `source_type` = `"processed"` - Inherits standard base fields (id, name, description, tags, created_at, updated_at) - [ ] Task 3: Remove `MonoAudioSource` class entirely - [ ] Task 4: Remove `BandExtractAudioSource` class entirely - [ ] Task 5: Update `create_audio_source()` factory function to handle new types - [ ] Task 6: Update `AudioSourceStore` resolution logic: - `resolve_audio_source()` now returns: device info (from CaptureAudioSource at chain end) + ordered list of filter chains (from AudioProcessingTemplates along the chain) - Walk chain: ProcessedAudioSource → ... → CaptureAudioSource - Collect all audio_processing_template_ids in order - Cycle detection for ProcessedAudioSource chains - [ ] Task 7: Update `ResolvedAudioSource` dataclass: - Remove `channel` and `freq_low`/`freq_high` fields (handled by filters now) - Add `filter_instances: List[FilterInstance]` — flattened, ordered list of all filters to apply - Or add `template_ids: List[str]` and resolve at runtime - [ ] Task 8: Update reference validation in store: - `ProcessedAudioSource.audio_source_id` must reference an existing audio source - `ProcessedAudioSource.audio_processing_template_id` must reference an existing template - Delete checks: can't delete a source referenced by another ProcessedAudioSource - Delete checks: can't delete a template referenced by a ProcessedAudioSource - [ ] Task 9: Update API schemas in `api/schemas/audio_sources.py` - Remove `MonoAudioSourceCreate/Update/Response` schemas - Remove `BandExtractAudioSourceCreate/Update/Response` schemas - Add `CaptureAudioSourceCreate/Update/Response` (rename from Multichannel) - Add `ProcessedAudioSourceCreate/Update/Response` - Update discriminated union to use new type literals - [ ] Task 10: Update API routes in `api/routes/audio_sources.py` - Handle new source types in create/update endpoints - Remove handling of old types - Update WebSocket test endpoint to work with ProcessedAudioSource - [ ] Task 11: Update any imports/references across the codebase that reference the old types ## Files to Modify/Create - `storage/audio_source.py` — **modify** — rename, add, remove dataclasses - `storage/audio_source_store.py` — **modify** — new resolution logic, validation - `api/schemas/audio_sources.py` — **modify** — new schemas - `api/routes/audio_sources.py` — **modify** — handle new types - Any files importing `MultichannelAudioSource`, `MonoAudioSource`, `BandExtractAudioSource` — **modify** ## Acceptance Criteria - `CaptureAudioSource` replaces `MultichannelAudioSource` (same behavior, new name/type) - `ProcessedAudioSource` can be created referencing a source + template - `MonoAudioSource` and `BandExtractAudioSource` are fully removed - Chain resolution walks ProcessedAudioSource → ... → CaptureAudioSource correctly - Cycle detection prevents circular source references - Reference validation prevents dangling references - API accepts/returns new type discriminators ## Notes - Clean-slate: no migration of existing data. Old source type records will be lost. - The `source_type` string changes from `"multichannel"` to `"capture"` — this is a breaking change but acceptable for clean-slate. - `ResolvedAudioSource` is consumed by `AudioColorStripStream` and `AudioValueStream` — they will need updates in Phase 4. - Template reference checks in the store need coordination with `AudioProcessingTemplateStore` — may need to pass it as a dependency. ## Review Checklist - [ ] All tasks completed - [ ] Code follows project conventions - [ ] No unintended side effects - [ ] Build passes - [ ] Tests pass (new + existing) ## Handoff to Next Phase