menios icon indicating copy to clipboard operation
menios copied to clipboard

Kernel audio core (PCM buffer manager and mixer)

Open pbalduino opened this issue 3 months ago • 2 comments

Goal

Implement the kernel audio core subsystem that manages PCM buffers, software mixing, and coordination between audio drivers and userland applications.

Context

Part of #33 (Audio subsystem). This is the central audio management layer that sits between the hardware driver (#382) and userland applications. It handles multi-stream mixing, buffer scheduling, and format conversion.

Scope

Core Components

1. PCM Ring Buffer Manager

  • Circular buffer allocation (kernel heap or DMA-capable memory)
  • Read/write pointer management (producer/consumer model)
  • Buffer full/empty detection
  • Wraparound handling
  • Lock-free or spinlock-protected access paths

2. Audio Stream Manager

  • Per-process audio stream tracking (struct audio_stream)
  • Stream state machine (IDLE → SETUP → RUNNING → DRAINING → STOPPED)
  • Reference counting for cleanup
  • Stream registration/deregistration API

3. Software Mixer

  • Mix multiple PCM streams into single output buffer
  • Support different sample formats (8-bit, 16-bit signed/unsigned)
  • Sample rate conversion (SRC) if needed (e.g., 11 kHz → 48 kHz)
  • Volume control per stream (optional MVP)
  • Clipping prevention (saturating arithmetic)

4. Scheduling and Timing

  • Timer-driven or interrupt-driven buffer refill
  • Wake writers before buffer underrun (watermark thresholds)
  • Sleep queue for blocking write() calls
  • Poll/select support for non-blocking I/O

5. Hardware Driver Interface

  • Driver registration API (audio_driver_register)
  • Callbacks: get_buffer_info, submit_buffer, get_position
  • Notification path for hardware buffer completion (IRQ → wakeup)

Implementation Phases

Phase 1: Buffer and Stream Infrastructure (4-5 days)

  • Define struct audio_stream and struct audio_buffer
  • Implement circular buffer allocation/deallocation
  • Add stream lifecycle management (create/destroy/ref/unref)
  • Basic spinlock protection

Phase 2: Software Mixer (5-6 days)

  • Implement multi-stream mixing loop
  • Support 8-bit unsigned, 16-bit signed PCM
  • Basic sample rate conversion (nearest-neighbor or linear interpolation)
  • Clipping/saturation logic
  • Mixing timer/scheduler integration

Phase 3: Driver Interface (3-4 days)

  • Define struct audio_driver operations
  • Implement driver registration/unregistration
  • Add hardware buffer handoff mechanism
  • Interrupt callback path (driver → core → wakeup writers)

Phase 4: Timing and Synchronization (3-4 days)

  • Integrate with kernel timer subsystem (#239, #287)
  • Implement buffer watermark monitoring
  • Add sleep queue for blocking writes
  • Poll/select infrastructure (future: #348)

Definition of Done

  • [ ] PCM ring buffer allocation and wraparound working
  • [ ] Stream lifecycle management (create/setup/run/drain/stop)
  • [ ] Software mixer combines multiple streams correctly
  • [ ] Sample rate conversion (at least basic 11/22/44 kHz → 48 kHz)
  • [ ] Driver registration API functional
  • [ ] Interrupt-driven buffer refill wakes blocked writers
  • [ ] No buffer underruns during normal operation
  • [ ] Integrates with #382 (PCI audio driver)
  • [ ] Unit tests for mixing logic (host harness)

Dependencies

  • #239 - Kernel time syscalls ✅ (CLOSED)
  • #287 - nanosleep() and sleep queue ✅ (CLOSED)
  • #40 - Condition variables ✅ (CLOSED - for wakeup)
  • #382 - PCI audio driver (parallel development, tight coupling)
  • #279 - Dynamic IRQ allocation (for interrupt notification path)

Risks

  • Timing accuracy: Poor timer resolution causes audio glitches
  • CPU overhead: Software mixing may be expensive; profile early
  • DMA constraints: Buffers must be physically contiguous and page-aligned
  • Format mismatches: Doom uses 8/16-bit at 11-22 kHz; hardware expects 48 kHz
  • Underrun handling: Graceful recovery needed (silence fill vs pause)

Timeline

Estimated effort: 2-3 weeks (15-19 days)

Testing Strategy

  • Unit tests: Mixing logic with mock streams (host harness)
  • Integration tests: Connect to mock driver, verify buffer handoff
  • Stress tests: Multiple streams at different rates
  • Real hardware: QEMU with AC'97, verify no crackles/pops

References

  • Linux ALSA: sound/core/pcm*.c (PCM infrastructure)
  • OSS: /dev/dsp semantics
  • FreeBSD: sys/dev/sound/pcm/ (software mixing)
  • OSDev Wiki: Audio mixing concepts

Related Issues

  • Parent: #33 (Audio subsystem)
  • Depends on: #239, #287, #40, #382, #279
  • Enables: #383 (Audio syscalls)

Priority

Medium - Part of Doom audio milestone, blocked by #279

Status

BLOCKED BY #279 (Dynamic IRQ handler registration API)

This issue is part of the audio subsystem implementation for the Doom milestone. It cannot proceed until #279 is complete.

Dependency Chain

#279 (Dynamic IRQ) ← CRITICAL BLOCKER (HIGH priority)
  ↓
#382 + #383 (Audio driver + core) ← YOU ARE HERE
  ↓
#384 (Syscalls) → #385 (API) → #386 (Testing)
  ↓
Doom audio integration

Related Issues

  • #33 (Audio subsystem parent) - umbrella issue
  • #279 (Dynamic IRQ) - BLOCKS THIS ISSUE

Priority Rationale: Medium priority appropriate for Doom milestone work, but cannot start until HIGH priority #279 is complete.

pbalduino avatar Oct 29 '25 22:10 pbalduino