fix: solve audio glitch/crackling on Emscripten via use higher buffer and AUDIO_S16LSB

This commit is contained in:
Ryan Walters
2025-09-10 23:08:08 -05:00
parent a2783ae62d
commit 46a73c5ace
3 changed files with 21 additions and 9 deletions

2
Cargo.lock generated
View File

@@ -663,7 +663,7 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]] [[package]]
name = "pacman" name = "pacman"
version = "0.79.1" version = "0.79.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bevy_ecs", "bevy_ecs",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "pacman" name = "pacman"
version = "0.79.1" version = "0.79.2"
authors = ["Xevion"] authors = ["Xevion"]
edition = "2021" edition = "2021"
rust-version = "1.86.0" rust-version = "1.86.0"

View File

@@ -1,7 +1,7 @@
//! This module handles the audio playback for the game. //! This module handles the audio playback for the game.
use crate::asset::{get_asset_bytes, Asset}; use crate::asset::{get_asset_bytes, Asset};
use sdl2::{ use sdl2::{
mixer::{self, Chunk, InitFlag, LoaderRWops, DEFAULT_FORMAT}, mixer::{self, Chunk, InitFlag, LoaderRWops, AUDIO_S16LSB, DEFAULT_CHANNELS},
rwops::RWops, rwops::RWops,
}; };
@@ -33,13 +33,24 @@ impl Audio {
/// If audio fails to initialize, the audio system will be disabled and /// If audio fails to initialize, the audio system will be disabled and
/// all functions will silently do nothing. /// all functions will silently do nothing.
pub fn new() -> Self { pub fn new() -> Self {
let frequency = 44100; let frequency = 44_100;
let format = DEFAULT_FORMAT; let format = AUDIO_S16LSB;
let channels = 4; let chunk_size = {
let chunk_size = 256; // 256 is minimum for emscripten // 256 is the minimum for Emscripten, but in practice 1024 is much more reliable
#[cfg(target_os = "emscripten")]
{
1024
}
// Otherwise, 256 is plenty safe.
#[cfg(not(target_os = "emscripten"))]
{
256
}
};
// Try to open audio, but don't panic if it fails // Try to open audio, but don't panic if it fails
if let Err(e) = mixer::open_audio(frequency, format, 1, chunk_size) { if let Err(e) = mixer::open_audio(frequency, format, DEFAULT_CHANNELS, chunk_size) {
tracing::warn!("Failed to open audio: {}. Audio will be disabled.", e); tracing::warn!("Failed to open audio: {}. Audio will be disabled.", e);
return Self { return Self {
_mixer_context: None, _mixer_context: None,
@@ -51,7 +62,8 @@ impl Audio {
}; };
} }
mixer::allocate_channels(channels); let channels = 4;
mixer::allocate_channels(4);
// set channel volume // set channel volume
for i in 0..channels { for i in 0..channels {