Audio validation and tooling (WAV player, tests)
Goal
Develop comprehensive validation tools, tests, and utilities to verify audio subsystem correctness before Doom integration.
Context
Part of #33 (Audio subsystem). This work ensures the entire audio stack (#382, #383, #384, #385) works correctly through systematic testing and practical tools.
Scope
Testing Infrastructure
1. Host Test Harness (Unity Framework)
Unit Tests
// test/test_audio_mixer.c
- test_mix_two_streams_16bit()
- test_mix_overflow_clipping()
- test_sample_rate_conversion()
- test_buffer_wraparound()
- test_format_conversion_u8_to_s16()
Mock Infrastructure
- Mock DMA buffers (simulate hardware ring)
- Mock interrupt delivery
- Timing simulation (virtual time for deterministic tests)
2. Kernel Integration Tests
// test/test_audio_syscalls.c
- test_dsp_open_close()
- test_dsp_write_blocking()
- test_dsp_write_nonblocking()
- test_dsp_ioctl_format()
- test_dsp_buffer_underrun_recovery()
3. Stress Tests
- Multiple streams simultaneously (4-8 streams)
- Rapid open/close cycles (resource leak detection)
- Buffer underrun/overrun injection
- Latency measurement (time-to-first-sample)
Validation Tools
1. Tone Generator (/bin/tone)
Simple PCM sine wave generator:
# Generate 440 Hz tone at 22050 Hz, 5 seconds
/bin/tone 440 22050 5
Features:
- Configurable frequency (Hz)
- Configurable sample rate (11025, 22050, 44100, 48000)
- Duration control
- Format selection (8-bit, 16-bit)
- Mono/stereo output
Implementation:
// app/tone/tone.c
- Parse command-line arguments
- Generate sine wave samples (lookup table or math.h)
- Open /dev/dsp, configure format
- Write samples in chunks
- Report timing and buffer stats
2. WAV File Player (/bin/play)
Play RIFF WAVE files from filesystem:
# Play a WAV file
/bin/play /HOME/DOOM/sounds/pistol.wav
Features:
- Parse RIFF WAVE header (fmt chunk, data chunk)
- Support common formats (8/16-bit PCM, mono/stereo)
- Automatic rate conversion if needed
- Progress indicator
- Error reporting (unsupported format, file not found)
Implementation:
// app/play/play.c
- Read and parse WAV header
- Validate format (reject compressed formats)
- Configure /dev/dsp to match WAV format
- Stream data chunks to audio device
- Handle short reads, EOF
3. Audio Diagnostic Tool (/bin/audioinfo)
Query audio subsystem status:
# Show audio device information
/bin/audioinfo
Output:
Audio Device: /dev/dsp
Driver: AC'97 (Intel ICH)
Status: Ready
Supported Formats: U8, S16_LE
Supported Rates: 11025, 22050, 44100, 48000
Buffer Size: 16384 bytes (4 fragments × 4096)
Latency: ~93 ms
Active Streams: 0
Implementation:
- Query via ioctl (SNDCTL_DSP_GETCAPS, GETOSPACE, etc.)
- Read /proc/audio (if implemented)
- Pretty-print capabilities
Sample Audio Files
Provide test WAV files in initrd or FAT32:
- tone440.wav - 440 Hz sine wave, 16-bit, 22050 Hz, 2 sec
- sweep.wav - Frequency sweep 20 Hz - 20 kHz
- pistol.wav - Doom pistol sound effect (from shareware WAD)
- music.wav - Short music clip (E1M1 excerpt)
Documentation
1. Testing Guide (docs/testing/audio.md)
- How to run audio tests
- Interpreting test failures
- QEMU audio setup (enable AC'97)
- Real hardware validation checklist
2. Audio API Reference (docs/api/audio.md)
- libc audio functions
- /dev/dsp ioctl reference
- Code examples
- Troubleshooting common issues
3. Developer Notes (docs/design/audio.md)
- Architecture overview (driver → core → syscalls → libc)
- Buffer flow diagrams
- Timing and latency analysis
- Known limitations
Implementation Phases
Phase 1: Host Unit Tests (3-4 days)
- Set up Unity test framework for audio
- Write mixer unit tests
- Write buffer management tests
- Mock DMA and interrupts
Phase 2: Kernel Integration Tests (3-4 days)
- Implement syscall tests
- Test blocking/non-blocking semantics
- Verify ioctl configuration
- Test error conditions
Phase 3: Validation Tools (4-5 days)
- Implement tone generator (
/bin/tone) - Implement WAV player (
/bin/play) - Implement audioinfo utility
- Create sample WAV files
Phase 4: Documentation and Stress Tests (2-3 days)
- Write testing guide
- Write API reference
- Run stress tests (multi-stream, leak detection)
- Document findings and limitations
Definition of Done
- [ ] Unit tests for mixer and buffer management (host harness)
- [ ] Integration tests for /dev/dsp syscalls
- [ ] Tone generator (
/bin/tone) working - [ ] WAV player (
/bin/play) plays sample files - [ ] Audio info utility (
/bin/audioinfo) displays status - [ ] Sample WAV files included in build
- [ ] Documentation: testing guide, API reference, design notes
- [ ] All tests passing in QEMU
- [ ] Stress tests complete (no leaks, no crashes)
- [ ] Ready for Doom integration (#33)
Dependencies
- #382 - PCI audio driver (to test real hardware path)
- #383 - Kernel audio core (mixer tests)
- #384 - Audio syscalls (integration tests)
- #385 - Userland audio API (for tools)
- #193 - Minimal libc ✅ (for utility programs)
- #189 - FAT32 write support ✅ (for WAV files)
Risks
- QEMU audio quirks: QEMU AC'97 may not match real hardware
- WAV parsing bugs: Malformed files cause crashes
- Timing sensitivity: Tests may be flaky on slow systems
- Sample file licensing: Ensure Doom sound effects are shareware
Timeline
Estimated effort: 2 weeks (12-16 days)
Testing Strategy
Automated Tests
make test-audio # Run all audio tests
make test-audio-unit # Unit tests only
make test-audio-stress # Stress tests
Manual Validation
- Boot meniOS in QEMU with audio enabled
- Run
/bin/tone 440 22050 3→ verify audible 440 Hz tone - Run
/bin/play /HOME/test.wav→ verify WAV playback - Run
/bin/audioinfo→ verify device info - Load Doom → verify sound effects and music
Acceptance Criteria
- Tone generator produces clean sine wave (no clicks/pops)
- WAV player handles 8/16-bit, mono/stereo files
- No buffer underruns during normal playback
- Tests pass on both host and native
Example Test Output
[TEST] test_mix_two_streams_16bit ... PASS
[TEST] test_mix_overflow_clipping ... PASS
[TEST] test_sample_rate_conversion ... PASS
[TEST] test_buffer_wraparound ... PASS
[TEST] test_dsp_open_close ... PASS
[TEST] test_dsp_write_blocking ... PASS
Audio Tests: 6/6 passed ✓
Tone Generator Test:
Frequency: 440 Hz
Sample Rate: 22050 Hz
Duration: 3.0 sec
Samples Written: 66150
Buffer Underruns: 0
✓ Playback complete
WAV Player Test:
File: /HOME/pistol.wav
Format: S16_LE, 22050 Hz, Mono
Size: 8192 bytes
Duration: 0.37 sec
✓ Playback complete
References
- Unity Testing Framework: http://www.throwtheswitch.org/unity
- RIFF WAVE format: http://soundfile.sapp.org/doc/WaveFormat/
- OSS testing examples: Linux
sound/oss/tests - Audio testing best practices
Related Issues
- Parent: #33 (Audio subsystem)
- Depends on: #382, #383, #384, #385, #193, #189
- Validates: Entire audio stack
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.