menios icon indicating copy to clipboard operation
menios copied to clipboard

Audio syscalls and /dev/dsp device interface

Open pbalduino opened this issue 3 months ago • 0 comments

Goal

Implement syscalls and /dev/dsp device interface for userland audio output, compatible with OSS (Open Sound System) semantics.

Context

Part of #33 (Audio subsystem). This layer exposes the kernel audio core (#383) to userland via a character device (/dev/dsp) and ioctl-based configuration.

Scope

Device Interface

/dev/dsp Character Device

  • Create device node in devfs (#136)
  • Standard file operations: open, close, write, ioctl, poll
  • Multiple open semantics (exclusive vs shared access)
  • Non-blocking and blocking modes (O_NONBLOCK flag)

File Operations

open("/dev/dsp", flags)
  • Allocate audio stream structure (links to #383 stream manager)
  • Set default format (16-bit signed, 48 kHz, stereo)
  • Return file descriptor
  • Handle exclusive access (return -EBUSY if already opened)
write(fd, buffer, count)
  • Copy PCM samples from userland
  • Enqueue to stream buffer (ring buffer from #383)
  • Block if buffer full (sleep queue)
  • Return bytes written or -EAGAIN for non-blocking
ioctl(fd, cmd, arg)
  • SNDCTL_DSP_SETFMT: Set sample format (8/16-bit, signed/unsigned)
  • SNDCTL_DSP_CHANNELS: Set mono/stereo
  • SNDCTL_DSP_SPEED: Set sample rate (11/22/44/48 kHz)
  • SNDCTL_DSP_GETOSPACE: Get output buffer space info
  • SNDCTL_DSP_RESET: Stop playback and flush buffers
  • SNDCTL_DSP_SYNC: Block until all queued samples played
poll(fd, events, timeout)
  • Return POLLOUT when buffer has space for writing
  • Return POLLERR on errors
  • Integrate with kernel poll infrastructure (future: #348)
close(fd)
  • Drain remaining buffered samples (or truncate if non-blocking)
  • Release stream resources
  • Unregister from audio core (#383)

Syscalls

New System Calls

  • SYS_AUDIO_OPEN (alternative to open + ioctl)
  • SYS_AUDIO_WRITE (optimized write path, optional)
  • SYS_AUDIO_IOCTL (maps to generic ioctl)

Note: Can reuse existing syscalls (open/write/ioctl) if /dev/dsp approach is sufficient.

OSS Compatibility

Minimal OSS API Surface

  • Format negotiation (AFMT_U8, AFMT_S16_LE)
  • Sample rate selection (power-of-2 rates: 11025, 22050, 44100, 48000)
  • Channel configuration (mono, stereo)
  • Buffer size hints (fragment size)

Implementation Phases

Phase 1: Device Registration (2-3 days)

  • Register /dev/dsp in devfs (#136)
  • Implement open/close operations
  • Allocate/deallocate stream structures
  • Handle exclusive access locking

Phase 2: Write Path (3-4 days)

  • Implement write() syscall handler
  • Copy user buffer to kernel stream buffer (#383)
  • Blocking/non-blocking semantics
  • Sleep queue integration for buffer-full waits

Phase 3: ioctl Configuration (4-5 days)

  • Implement SNDCTL_DSP_* ioctls
  • Format/rate/channel validation
  • Buffer info queries (GETOSPACE)
  • RESET and SYNC operations

Phase 4: Integration and Testing (2-3 days)

  • Wire to audio core (#383)
  • Test with simple userland tool (tone generator)
  • Verify buffer refill timing
  • Add error handling and edge cases

Definition of Done

  • [ ] /dev/dsp device node created and accessible
  • [ ] open() allocates audio stream successfully
  • [ ] write() enqueues PCM data to kernel buffers
  • [ ] Blocking write() sleeps when buffer full
  • [ ] Non-blocking write() returns -EAGAIN appropriately
  • [ ] ioctl() configures format, rate, channels
  • [ ] close() drains buffers and releases resources
  • [ ] Integrates with audio core (#383) stream manager
  • [ ] Tested with userland tone generator (#385)
  • [ ] OSS-compatible API for Doom's I_InitSound()

Dependencies

  • #136 - Device filesystem (devfs) ✅ (CLOSED)
  • #96 - File descriptor management ✅ (CLOSED)
  • #220 - ioctl syscall infrastructure ✅ (CLOSED)
  • #383 - Kernel audio core (CRITICAL - must integrate with stream manager)
  • #40 - Condition variables ✅ (for sleep queue)

Risks

  • Buffer synchronization: Race conditions between write and mixer
  • Latency: High syscall overhead may cause audio stutter
  • Format conversion: Mismatch between user format and hardware format
  • Blocking semantics: Incorrect sleep/wakeup causes hangs or busy-wait

Timeline

Estimated effort: 2 weeks (11-15 days)

Testing Strategy

  • Unit tests: Mock audio core, verify ioctl parsing
  • Integration tests: Real audio core, check buffer handoff
  • Userland test: Simple tone generator (sine wave at 440 Hz)
  • Doom integration: Verify I_InitSound() and I_SubmitSound() work

References

  • OSS Programmer's Guide: http://www.opensound.com/pguide/
  • Linux OSS emulation: sound/oss/
  • FreeBSD /dev/dsp: sys/dev/sound/pcm/dsp.c
  • OSDev Wiki: Sound programming

Related Issues

  • Parent: #33 (Audio subsystem)
  • Depends on: #136, #96, #220, #383, #40
  • Enables: #385 (Userland audio API)

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