audio: provide OSS-compatible /dev/dsp PCM playback - #947
Open
brandonpayton wants to merge 7 commits into
Open
Conversation
Contributor
Phase B-1 matrix build status —
|
| Package | Arch | Status | Sha |
|---|---|---|---|
| icu | wasm32 | failed | — |
| libcurl | wasm32 | failed | — |
| libcxx | wasm32 | built | d86a56cf |
| libcxx | wasm64 | built | 187a1130 |
| libiconv | wasm32 | failed | — |
| libpng | wasm32 | failed | — |
| libxml2 | wasm32 | failed | — |
| libzip | wasm32 | failed | — |
| openssl | wasm32 | failed | — |
| openssl | wasm64 | failed | — |
| sdl2 | wasm32 | failed | — |
| sdl3 | wasm32 | failed | — |
| sqlite | wasm32 | failed | — |
| sqlite | wasm64 | failed | — |
| zlib | wasm32 | failed | — |
| zlib | wasm64 | failed | — |
| bc | wasm32 | failed | — |
| bzip2 | wasm32 | failed | — |
| coreutils | wasm32 | failed | — |
| curl | wasm32 | failed | — |
| dash | wasm32 | failed | — |
| diffutils | wasm32 | failed | — |
| dinit | wasm32 | failed | — |
| fbdoom | wasm32 | failed | — |
| file | wasm32 | failed | — |
| findutils | wasm32 | failed | — |
| gawk | wasm32 | failed | — |
| git | wasm32 | failed | — |
| grep | wasm32 | failed | — |
| gzip | wasm32 | failed | — |
| hello | wasm32 | failed | — |
| kandelo-sdk | wasm32 | failed | — |
| kernel | wasm32 | failed | — |
| less | wasm32 | failed | — |
| lsof | wasm32 | failed | — |
| m4 | wasm32 | failed | — |
| make | wasm32 | failed | — |
| mariadb | wasm32 | failed | — |
| mariadb | wasm64 | failed | — |
| modeset | wasm32 | failed | — |
| msmtpd | wasm32 | failed | — |
| nano | wasm32 | failed | — |
| ncurses | wasm32 | failed | — |
| netcat | wasm32 | failed | — |
| nginx | wasm32 | failed | — |
| php | wasm32 | failed | — |
| posix-utils-lite | wasm32 | failed | — |
| ruby | wasm32 | failed | — |
| sdl-dsp-test | wasm32 | failed | — |
| sdl2-mixer-playwave | wasm32 | failed | — |
| sed | wasm32 | failed | — |
| spidermonkey | wasm32 | failed | — |
| tar | wasm32 | failed | — |
| tcl | wasm32 | failed | — |
| unzip | wasm32 | failed | — |
| userspace | wasm32 | failed | — |
| vim | wasm32 | failed | — |
| wget | wasm32 | failed | — |
| xz | wasm32 | failed | — |
| zip | wasm32 | failed | — |
| zstd | wasm32 | failed | — |
| bash | wasm32 | failed | — |
| mariadb-test | wasm32 | failed | — |
| mariadb-vfs | wasm32 | failed | — |
| mariadb-vfs | wasm64 | failed | — |
| nethack | wasm32 | failed | — |
| node | wasm32 | failed | — |
| spidermonkey-node | wasm32 | failed | — |
| vim-browser-bundle | wasm32 | failed | — |
| nethack-browser-bundle | wasm32 | failed | — |
| rootfs | wasm32 | failed | — |
| shell | wasm32 | failed | — |
| lamp | wasm32 | failed | — |
| node-vfs | wasm32 | failed | — |
| wordpress | wasm32 | failed | — |
Auto-generated; replaced on each push. Raw data in the publish-status workflow artifact.
brandonpayton
added a commit
that referenced
this pull request
Aug 12, 2026
Forward-port the accepted browser portion of PR #947 onto the ABI 43 integration branch. Keep the current lazy test-runner artifact loading while adding the real AudioWorklet lifecycle proof and machine-level resume controls. Source: c288f562146acf263f8ee28405fdd7d3bcc21caf
brandonpayton
added a commit
that referenced
this pull request
Aug 12, 2026
Forward-port the accepted SDL package and integration-test slice of PR #947 onto ABI 43. Build official SDL2 and SDL3 releases through the worktree SDK, keep their upstream OSS backends, and exercise paced PCM through the production Node path. The generated program-package projection remains reserved for the final artifact commit. Source: 66e8dcbe8dcb5da95de43b5b9da214a3879bbf4a
brandonpayton
added a commit
that referenced
this pull request
Aug 17, 2026
Forward-port the accepted browser portion of PR #947 onto the ABI 43 integration branch. Keep the current lazy test-runner artifact loading while adding the real AudioWorklet lifecycle proof and machine-level resume controls. Source: c288f562146acf263f8ee28405fdd7d3bcc21caf
brandonpayton
added a commit
that referenced
this pull request
Aug 17, 2026
Forward-port the accepted SDL package and integration-test slice of PR #947 onto ABI 43. Build official SDL2 and SDL3 releases through the worktree SDK, keep their upstream OSS backends, and exercise paced PCM through the production Node path. The generated program-package projection remains reserved for the final artifact commit. Source: 66e8dcbe8dcb5da95de43b5b9da214a3879bbf4a
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Kandelo applications currently have no standard POSIX-style device for playing digital audio. Programs such as SDL games can render graphics and accept input, but they either need application-specific audio code or run silently because
/dev/dspdoes not exist./dev/dspis the conventional Open Sound System (OSS) device used by many portable Unix programs for Pulse-Code Modulation (PCM) audio samples.Adding this device at the platform layer lets unmodified software use its normal OSS backend in both Node.js and the browser. It also keeps buffering, blocking writes, polling, and close/drain behavior in one authoritative kernel model instead of recreating those semantics in each demo.
What changed
/dev/dspApplication Binary Interface (ABI), including the control operations used by SDL2 and SDL3 plus truthful buffer size, delay, capability, nonblocking, post, and output-position reporting.AudioWorklet; pace Node.js playback with a wall-clock null sink. Both hosts preserve the same kernel-visible playback position and drain behavior.playwave. Simplify fbDOOM so it uses the standard<sys/soundcard.h>interface instead of private audio definitions.This PR supersedes #698. That earlier PR established useful AudioWorklet and host-transport experiments, but it also introduced an Advanced Linux Sound Architecture (ALSA)
/dev/sndinterface and ALSA-specific state that are outside this focused OSS device contract.Compatibility boundary
The initial device is playback-only and exposes one exclusive default stream. It supports unsigned 8-bit audio, signed 16-bit little-endian audio, and signed 16-bit big-endian audio; mono or stereo; and rates clamped to 8–192 kHz. Capture, duplex, memory mapping, mixer controls, trigger control, multi-client mixing, and ALSA interfaces remain explicitly unsupported and are not advertised.
SDL and application evidence
SNDCTL_DSP_GETOSPACEwait path.playwaveruns at 44.1 kHz signed 16-bit stereo and 22.05 kHz unsigned 8-bit mono. The Node.js sink captures bytes consumed from the shared ring buffer; the test compares the non-silent payload byte-for-byte with the generated WAV file, checks real-time pacing and negotiated controls, and requires a clean drain with no discarded bytes.AudioContextis suspended, a trusted click resumes the packaged worklet, and close waits for the remaining audio to drain.Validation
Automated browser validation covers user activation, worklet loading, clock-driven consumption, drain, suspend/resume, and teardown. A human audible browser check remains unrun because it requires a reviewer with audio output.
Footprint and buffering
playwaveWebAssembly: 1,800,045 / 434,029 bytes