353c090b42
Replace MultichannelAudioSource with CaptureAudioSource, add ProcessedAudioSource (audio_source_id + audio_processing_template_id), remove MonoAudioSource and BandExtractAudioSource entirely. Update store resolution to walk processed chains collecting template IDs. Update all API schemas, routes, and frontend references.
7.5 KiB
7.5 KiB
Phase 3: Processed Audio Source Model
Status: ✅ Done Parent plan: 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→CaptureAudioSourceinstorage/audio_source.py- Change class name, update
source_typedefault to"capture" - Same fields:
device_index,is_loopback,audio_template_id
- Change class name, update
- Task 2: Add
ProcessedAudioSourcedataclass instorage/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)
- Fields:
- Task 3: Remove
MonoAudioSourceclass entirely - Task 4: Remove
BandExtractAudioSourceclass entirely - Task 5: Update
create_audio_source()factory function to handle new types - Task 6: Update
AudioSourceStoreresolution 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
ResolvedAudioSourcedataclass:- Remove
channelandfreq_low/freq_highfields (handled by filters now) - Add
audio_processing_template_ids: List[str]— ordered list of template IDs along the chain
- Remove
- Task 8: Update reference validation in store:
ProcessedAudioSource.audio_source_idmust reference an existing audio sourceProcessedAudioSource.audio_processing_template_idmust reference an existing template- Delete checks: can't delete a source referenced by another ProcessedAudioSource
- Added
get_sources_referencing_template()helper for template delete checks
- Task 9: Update API schemas in
api/schemas/audio_sources.py- Remove
MonoAudioSourceCreate/Update/Responseschemas - Remove
BandExtractAudioSourceCreate/Update/Responseschemas - Add
CaptureAudioSourceCreate/Update/Response(rename from Multichannel) - Add
ProcessedAudioSourceCreate/Update/Response - Update discriminated union to use new type literals
- Remove
- 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 new resolution (no channel/band)
- 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 dataclassesstorage/audio_source_store.py— modify — new resolution logic, validationstorage/audio_template_store.py— modify — CaptureAudioSource importapi/schemas/audio_sources.py— modify — new schemasapi/routes/audio_sources.py— modify — handle new typescore/processing/audio_stream.py— modify — remove channel/band logiccore/processing/value_stream.py— modify — remove channel logiccore/demo_seed.py— modify — update demo data to new typesstorage/color_strip_source.py— modify — update commentstorage/value_source.py— modify — update commentstatic/js/types.ts— modify — new TS interfacesstatic/js/core/icons.ts— modify — new icon mappingstatic/js/core/graph-nodes.ts— modify — new icon mappingstatic/js/features/audio-sources.ts— modify — new source typesstatic/js/features/streams.ts— modify — new card sectionsstatic/js/features/value-sources.ts— modify — badge textstatic/js/features/color-strips.ts— modify — badge text, navigationstatic/js/core/command-palette.ts— modify — navigation mapping
Acceptance Criteria
CaptureAudioSourcereplacesMultichannelAudioSource(same behavior, new name/type)ProcessedAudioSourcecan be created referencing a source + templateMonoAudioSourceandBandExtractAudioSourceare 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_typestring changes from"multichannel"to"capture"— this is a breaking change but acceptable for clean-slate. ResolvedAudioSourceis consumed byAudioColorStripStreamandAudioValueStream— 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
What was built
CaptureAudioSourcereplacesMultichannelAudioSource(class + source_type "capture")ProcessedAudioSourceadded withaudio_source_id+audio_processing_template_idfieldsMonoAudioSourceandBandExtractAudioSourcefully removed from model, store, schemas, routes, and all frontend referencesResolvedAudioSourcenow returnsaudio_processing_template_ids: List[str]instead ofchannel/freq_low/freq_high- Chain resolution walks ProcessedAudioSource → ... → CaptureAudioSource, collecting template IDs in order (outermost first)
- Cycle detection for both create and update operations
get_sources_referencing_template()helper added for template delete checks- All frontend TS files updated: types, icons, card sections, navigation, command palette
What Phase 4 needs to know
ResolvedAudioSourcenow hasaudio_processing_template_idsfield — Phase 4 must resolve these toFilterInstancelists and instantiate/apply them in the stream runtimeAudioColorStripStream._pick_channel()currently returns rawanalysis.spectrum, analysis.rms— Phase 4 must wire filter processing hereAudioValueStream._pick_rms()and_pick_peak()currently return raw analysis values — Phase 4 must apply filter chain- Both streams store
self._audio_processing_template_idsfor use by Phase 4 - The WebSocket test endpoint also needs filter application wired in Phase 4
Temporary breakages (resolved in Phase 4)
- Channel selection removed from
AudioColorStripStream._pick_channel()— always uses mono mix - Channel selection removed from
AudioValueStream._pick_rms()and_pick_peak()— always uses mono - These were previously handled by MonoAudioSource/BandExtractAudioSource; now handled by channel_extract/band_extract filters in ProcessedAudioSource chains
Known deviations from plan
- Task 7: Used
audio_processing_template_ids: List[str](template IDs) rather thanfilter_instances: List[FilterInstance]— runtime resolution deferred to Phase 4 - Task 8: Template reference validation at create time not implemented (would require injecting AudioProcessingTemplateStore as dependency) — deferred to Phase 4 or Phase 7
- Frontend was also updated comprehensively (not just backend) to avoid broken UI