Files
ledgrab/plans/processed-audio-sources/phase-3-processed-audio-source-model.md
T
alexei.dolgolyov 353c090b42 feat(processed-audio-sources): phase 3 - processed audio source model
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.
2026-03-31 19:01:46 +03:00

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 MultichannelAudioSourceCaptureAudioSource 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 audio_processing_template_ids: List[str] — ordered list of template IDs along the chain
  • 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
    • Added get_sources_referencing_template() helper for template delete checks
  • 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 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.pymodify — rename, add, remove dataclasses
  • storage/audio_source_store.pymodify — new resolution logic, validation
  • storage/audio_template_store.pymodify — CaptureAudioSource import
  • api/schemas/audio_sources.pymodify — new schemas
  • api/routes/audio_sources.pymodify — handle new types
  • core/processing/audio_stream.pymodify — remove channel/band logic
  • core/processing/value_stream.pymodify — remove channel logic
  • core/demo_seed.pymodify — update demo data to new types
  • storage/color_strip_source.pymodify — update comment
  • storage/value_source.pymodify — update comment
  • static/js/types.tsmodify — new TS interfaces
  • static/js/core/icons.tsmodify — new icon mapping
  • static/js/core/graph-nodes.tsmodify — new icon mapping
  • static/js/features/audio-sources.tsmodify — new source types
  • static/js/features/streams.tsmodify — new card sections
  • static/js/features/value-sources.tsmodify — badge text
  • static/js/features/color-strips.tsmodify — badge text, navigation
  • static/js/core/command-palette.tsmodify — navigation mapping

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

What was built

  • CaptureAudioSource replaces MultichannelAudioSource (class + source_type "capture")
  • ProcessedAudioSource added with audio_source_id + audio_processing_template_id fields
  • MonoAudioSource and BandExtractAudioSource fully removed from model, store, schemas, routes, and all frontend references
  • ResolvedAudioSource now returns audio_processing_template_ids: List[str] instead of channel/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

  • ResolvedAudioSource now has audio_processing_template_ids field — Phase 4 must resolve these to FilterInstance lists and instantiate/apply them in the stream runtime
  • AudioColorStripStream._pick_channel() currently returns raw analysis.spectrum, analysis.rms — Phase 4 must wire filter processing here
  • AudioValueStream._pick_rms() and _pick_peak() currently return raw analysis values — Phase 4 must apply filter chain
  • Both streams store self._audio_processing_template_ids for 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 than filter_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