fix(apu): pause device on mute instead of writing silence

This commit is contained in:
Rekai Nyangadzayi Musuka 2022-10-27 09:11:08 -03:00
parent 4b8ed3cebb
commit eb7ffa29f4
3 changed files with 14 additions and 18 deletions

View File

@ -20,7 +20,8 @@ const setLo = @import("../util.zig").setLo;
const log = std.log.scoped(.APU);
pub const host_sample_rate = 1 << 15;
pub const host_rate = @import("../platform.zig").sample_rate;
pub const host_format = @import("../platform.zig").sample_format;
pub fn read(comptime T: type, apu: *const Apu, addr: u32) ?T {
const byte = @truncate(u8, addr);
@ -189,7 +190,7 @@ pub const Apu = struct {
.bias = .{ .raw = 0x0200 },
.sampling_cycle = 0b00,
.stream = SDL.SDL_NewAudioStream(SDL.AUDIO_U16, 2, 1 << 15, SDL.AUDIO_U16, 2, host_sample_rate).?,
.stream = SDL.SDL_NewAudioStream(SDL.AUDIO_U16, 2, 1 << 15, host_format, 2, host_rate).?,
.sched = sched,
.capacitor = 0,
@ -356,7 +357,7 @@ pub const Apu = struct {
defer SDL.SDL_FreeAudioStream(old_stream);
self.sampling_cycle = self.bias.sampling_cycle.read();
self.stream = SDL.SDL_NewAudioStream(SDL.AUDIO_U16, 2, @intCast(c_int, sample_rate), SDL.AUDIO_U16, 2, host_sample_rate).?;
self.stream = SDL.SDL_NewAudioStream(SDL.AUDIO_U16, 2, @intCast(c_int, sample_rate), host_format, 2, host_rate).?;
}
fn interval(self: *const Self) u64 {

View File

@ -36,7 +36,7 @@ const RunKind = enum {
};
pub fn run(quit: *Atomic(bool), scheduler: *Scheduler, cpu: *Arm7tdmi, tracker: *FpsTracker) void {
const audio_sync = config.config().guest.audio_sync;
const audio_sync = config.config().guest.audio_sync and !config.config().host.mute;
if (audio_sync) log.info("Audio sync enabled", .{});
if (config.config().guest.video_sync) {

View File

@ -15,6 +15,9 @@ const pitch = @import("core/ppu.zig").framebuf_pitch;
const gba_width = @import("core/ppu.zig").width;
const gba_height = @import("core/ppu.zig").height;
pub const sample_rate = 44100;
pub const sample_format = SDL.AUDIO_F32;
const default_title: []const u8 = "ZBA";
pub const Gui = struct {
@ -253,7 +256,6 @@ pub const Gui = struct {
const Audio = struct {
const Self = @This();
const log = std.log.scoped(.PlatformAudio);
const sample_rate = @import("core/apu.zig").host_sample_rate;
device: SDL.SDL_AudioDeviceID,
@ -261,7 +263,7 @@ const Audio = struct {
var have: SDL.SDL_AudioSpec = undefined;
var want: SDL.SDL_AudioSpec = std.mem.zeroes(SDL.SDL_AudioSpec);
want.freq = sample_rate;
want.format = SDL.AUDIO_U16;
want.format = sample_format;
want.channels = 2;
want.samples = 0x100;
want.callback = Self.callback;
@ -270,6 +272,7 @@ const Audio = struct {
const device = SDL.SDL_OpenAudioDevice(null, 0, &want, &have, 0);
if (device == 0) panic();
if (!config.config().host.mute)
SDL.SDL_PauseAudioDevice(device, 0); // Unpause Audio
return .{ .device = device };
@ -281,18 +284,10 @@ const Audio = struct {
}
export fn callback(userdata: ?*anyopaque, stream: [*c]u8, len: c_int) void {
const apu = @ptrCast(*Apu, @alignCast(@alignOf(*Apu), userdata));
const T = *Apu;
const apu = @ptrCast(T, @alignCast(@alignOf(T), userdata));
// TODO: Find a better way to mute this
if (!config.config().host.mute) {
_ = SDL.SDL_AudioStreamGet(apu.stream, stream, len);
} else {
// FIXME: I don't think this hack to remove DC Offset is acceptable :thinking:
std.mem.set(u8, stream[0..@intCast(usize, len)], 0x40);
}
// If we don't write anything, play silence otherwise garbage will be played
// if (written == 0) std.mem.set(u8, stream[0..@intCast(usize, len)], 0x40);
}
};