emscripten-core / emscripten-core/emscripten

SDL Audio: playing audio in strict mode using audio element results in error when ended

Open
#21,898 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

Description

**Version of emscripten/emsdk:**
```
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.59 (0e4c5994eb5b8defd38367a416d0703fd506ad81)
clang version 19.0.0git (https:/github.com/llvm/llvm-project df762a1643bb5b0b3c907611d118c82d4b68a39d)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: F:\Code\emsdk\upstream\bin
```

When emscripten is run in javascript strict mode (such as when `STRICT_JS` is enabled), and SDL audio is played using an audio element (such as preloaded audio with `--use-preload-plugins`), then the [audio `onended` event](https://github.com/emscripten-core/emscripten/blob/fa80cf25b8641974d60605b8a24cb7150fd63701/src/library_sdl.js#L2863) attempts to set the read-only property `paused` of the audio element. This is not allowed in strict mode, and results in an error. As a result, the audio is not cleaned up and SDL will run out of channels.

Example code:
```c
#include
#include
#include

Mix_Chunk* chunk;

EMSCRIPTEN_KEEPALIVE void play_audio() {
Mix_PlayChannel(-1, chunk, 0);
}

int main() {
SDL_Init(SDL_INIT_AUDIO);
Mix_OpenAudio(48000, MIX_DEFAULT_FORMAT, 1, 1024);
chunk = Mix_LoadWAV("test.wav");
EM_ASM(document.querySelector('#canvas').addEventListener('click', () => Module._play_audio()));
}
```

Compiling with `emcc main.c -s USE_SDL=1 --use-preload-plugins --preload-file=test.wav -o main.html` and clicking the canvas does not result in an error, as emscripten is not in strict mode.

Compiling with `emcc main.c -s USE_SDL=1 -s STRICT_JS --use-preload-plugins --preload-file=test.wav -o main.html` and clicking the canvas results in `Uncaught TypeError: setting getter-only property "paused"` when the audio ends. Clicking enough times will eventually result in the error `All 32 channels in use!` being logged and no further audio can be played.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.