Trying out miniaudio (#1652)

It does seem to offer a higher level interface, including spatial audio.

However this proof of concept only uses the low level interface, which
is pretty similar to port audio so far, also performance-wise.
Only technical difference so far seems to be that we can actually deinit
it without crashing.

@ikabod-kee since you got better ears for this, could you check if you
notice anything that got better or worse with this transition?
Particularly, I'd like to know if you notice any improvements with
respect to #571.

Remaining work if accepted:
- [x] Include this in the libs and precompile it instead of adding it
here
- [x] remove portaudio from the libs
- [x] make a new libs release and use it here
- [x] Remove remaining references of portaudio from the source

fixes #415
fixes #571
This commit is contained in:
IntegratedQuantum 2025-07-05 11:49:18 +02:00 committed by GitHub
parent dd506e197e
commit 4b856619b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 70 deletions

View File

@ -52,14 +52,10 @@ fn linkLibraries(b: *std.Build, exe: *std.Build.Step.Compile, useLocalDeps: bool
exe.addObjectFile(subPath.path(b, libName(b, "SPIRV-Tools-opt", t)));
if(t.os.tag == .windows) {
exe.linkSystemLibrary("ole32");
exe.linkSystemLibrary("winmm");
exe.linkSystemLibrary("uuid");
exe.linkSystemLibrary("gdi32");
exe.linkSystemLibrary("opengl32");
exe.linkSystemLibrary("ws2_32");
} else if(t.os.tag == .linux) {
exe.linkSystemLibrary("asound");
exe.linkSystemLibrary("X11");
exe.linkSystemLibrary("GL");
} else if(t.os.tag == .macos) {

View File

@ -9,39 +9,32 @@
.lazy = true,
},
.cubyz_deps_headers = .{
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/5/cubyz_deps_headers.tar.gz",
.hash = "N-V-__8AALzzRgA7omQPNlE657Y60UmkCdNdXsMES8VvMC6D",
.lazy = true,
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/6/cubyz_deps_headers.tar.gz",
.hash = "N-V-__8AAJ--TQDpDOZYIlfywTJhvDTy31Vm7gDmH0V104Fd",
},
.cubyz_deps_aarch64_macos = .{
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/5/cubyz_deps_aarch64-macos-none.tar.gz",
.hash = "N-V-__8AANwbIwJ6ad1lQFbXKAwT6VwXJY4oLyjZwOfz4LUx",
.lazy = true,
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/6/cubyz_deps_aarch64-macos-none.tar.gz",
.hash = "N-V-__8AAMQDQgJHVnvPvXG_aLxBTbf1JUS9nknqVj-gPyiq",
},
.cubyz_deps_aarch64_linux = .{
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/5/cubyz_deps_aarch64-linux-musl.tar.gz",
.hash = "N-V-__8AAG6FdQLSQL-LHeF5o7k3vRCnIdl0n2I0R0UO18K-",
.lazy = true,
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/6/cubyz_deps_aarch64-linux-musl.tar.gz",
.hash = "N-V-__8AAOTMkgKmHhBPhqTfh_7YcnM801wKAjg_qwobFXkS",
},
.cubyz_deps_aarch64_windows = .{
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/5/cubyz_deps_aarch64-windows-gnu.tar.gz",
.hash = "N-V-__8AANCHkQIGwA8SWUxMHaxnVnkTwBO0yei3HwBLOd2T",
.lazy = true,
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/6/cubyz_deps_aarch64-windows-gnu.tar.gz",
.hash = "N-V-__8AAAYpsgLaa_ttDfAghcK5vDzeIqM1hbVbSypPVifd",
},
.cubyz_deps_x86_64_macos = .{
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/5/cubyz_deps_x86_64-macos-none.tar.gz",
.hash = "N-V-__8AAIh5HAKP8i_TwkyD-6H_EL31J6Ereu9Kdx83J7Ks",
.lazy = true,
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/6/cubyz_deps_x86_64-macos-none.tar.gz",
.hash = "N-V-__8AALg4OwIwYK294eK0Nr-mZibpxJh_IpQLvNhO5Z0X",
},
.cubyz_deps_x86_64_linux = .{
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/5/cubyz_deps_x86_64-linux-musl.tar.gz",
.hash = "N-V-__8AAAy-cwLTBDz5YQSt3h-PdE4Cm-NDI9RGnrAz_onE",
.lazy = true,
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/6/cubyz_deps_x86_64-linux-musl.tar.gz",
.hash = "N-V-__8AABLMkQJIHo6bFgVMitmahlUhuGovf-SPw7-I42kX",
},
.cubyz_deps_x86_64_windows = .{
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/5/cubyz_deps_x86_64-windows-gnu.tar.gz",
.hash = "N-V-__8AAMzGtQKYP6AdoTC84UjbvypxwtagkWBMqrPc8Uhx",
.lazy = true,
.url = "https://github.com/PixelGuys/Cubyz-Libs/releases/download/6/cubyz_deps_x86_64-windows-gnu.tar.gz",
.hash = "N-V-__8AAIpW1AJNtAJnajSjZfiiqMB2tKQ8qkR2g6nhf5SE",
},
},
}

View File

@ -4,15 +4,15 @@ const main = @import("main");
const utils = main.utils;
const c = @cImport({
@cInclude("portaudio.h");
@cInclude("miniaudio.h");
@cDefine("STB_VORBIS_HEADER_ONLY", "");
@cInclude("stb/stb_vorbis.h");
});
fn handleError(paError: c_int) !void {
if(paError != c.paNoError) {
std.log.err("PortAudio error: {s}", .{c.Pa_GetErrorText(paError)});
return error.paError;
fn handleError(miniaudioError: c.ma_result) !void {
if(miniaudioError != c.MA_SUCCESS) {
std.log.err("miniaudio error: {s}", .{c.ma_result_description(miniaudioError)});
return error.miniaudioError;
}
}
@ -175,38 +175,29 @@ const MusicLoadTask = struct {
// TODO: Proper sound and music system
var stream: ?*c.PaStream = null;
var device: c.ma_device = undefined;
var sampleRate: f32 = 0;
pub fn init() error{paError}!void {
try handleError(c.Pa_Initialize());
errdefer handleError(c.Pa_Terminate()) catch {};
pub fn init() error{miniaudioError}!void {
var config = c.ma_device_config_init(c.ma_device_type_playback);
config.playback.format = c.ma_format_f32;
config.playback.channels = 2;
config.sampleRate = 44100;
config.dataCallback = &miniaudioCallback;
config.pUserData = undefined;
const device = c.Pa_GetDeviceInfo(c.Pa_GetDefaultOutputDevice());
sampleRate = @floatCast(device.*.defaultSampleRate);
try handleError(c.ma_device_init(null, &config, &device));
try handleError(c.Pa_OpenDefaultStream(
&stream,
0, // input channels
2, // stereo output
c.paFloat32,
sampleRate,
c.paFramesPerBufferUnspecified,
&patestCallback,
null,
));
errdefer handleError(c.Pa_CloseStream(stream)) catch {};
try handleError(c.ma_device_start(&device));
try handleError(c.Pa_StartStream(stream));
sampleRate = 44100;
lastTime = std.time.milliTimestamp();
}
pub fn deinit() void {
// Something about this causes a crash later in __GI___pthread_exit, this started happening after adding glslang, which may or may not be related
//handleError(c.Pa_StopStream(stream)) catch {};
//handleError(c.Pa_CloseStream(stream)) catch {};
//handleError(c.Pa_Terminate()) catch {};
handleError(c.ma_device_stop(&device)) catch {};
c.ma_device_uninit(&device);
mutex.lock();
defer mutex.unlock();
main.threadPool.closeAllTasksOfType(&MusicLoadTask.vtable);
@ -313,24 +304,16 @@ fn addMusic(buffer: []f32) void {
}
}
fn patestCallback(
inputBuffer: ?*const anyopaque,
outputBuffer: ?*anyopaque,
framesPerBuffer: c_ulong,
timeInfo: ?*const c.PaStreamCallbackTimeInfo,
statusFlags: c.PaStreamCallbackFlags,
userData: ?*anyopaque,
) callconv(.C) c_int {
// This routine will be called by the PortAudio engine when audio is needed.
// It may called at interrupt level on some machines so don't do anything
// that could mess up the system like calling malloc() or free().
_ = inputBuffer;
_ = timeInfo; // TODO: Synchronize this to the rest of the world
_ = statusFlags;
_ = userData;
const valuesPerBuffer = 2*framesPerBuffer; // Stereo
const buffer = @as([*]f32, @ptrCast(@alignCast(outputBuffer)))[0..valuesPerBuffer];
fn miniaudioCallback(
maDevice: ?*anyopaque,
output: ?*anyopaque,
input: ?*const anyopaque,
frameCount: u32,
) callconv(.C) void {
_ = input;
_ = maDevice;
const valuesPerBuffer = 2*frameCount; // Stereo
const buffer = @as([*]f32, @ptrCast(@alignCast(output)))[0..valuesPerBuffer];
@memset(buffer, 0);
addMusic(buffer);
return 0;
}