fix(apu): pause device on mute instead of writing silence
This commit is contained in:
parent
4b8ed3cebb
commit
eb7ffa29f4
|
@ -20,7 +20,8 @@ const setLo = @import("../util.zig").setLo;
|
||||||
|
|
||||||
const log = std.log.scoped(.APU);
|
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 {
|
pub fn read(comptime T: type, apu: *const Apu, addr: u32) ?T {
|
||||||
const byte = @truncate(u8, addr);
|
const byte = @truncate(u8, addr);
|
||||||
|
@ -189,7 +190,7 @@ pub const Apu = struct {
|
||||||
.bias = .{ .raw = 0x0200 },
|
.bias = .{ .raw = 0x0200 },
|
||||||
|
|
||||||
.sampling_cycle = 0b00,
|
.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,
|
.sched = sched,
|
||||||
|
|
||||||
.capacitor = 0,
|
.capacitor = 0,
|
||||||
|
@ -356,7 +357,7 @@ pub const Apu = struct {
|
||||||
defer SDL.SDL_FreeAudioStream(old_stream);
|
defer SDL.SDL_FreeAudioStream(old_stream);
|
||||||
|
|
||||||
self.sampling_cycle = self.bias.sampling_cycle.read();
|
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 {
|
fn interval(self: *const Self) u64 {
|
||||||
|
|
|
@ -36,7 +36,7 @@ const RunKind = enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn run(quit: *Atomic(bool), scheduler: *Scheduler, cpu: *Arm7tdmi, tracker: *FpsTracker) void {
|
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 (audio_sync) log.info("Audio sync enabled", .{});
|
||||||
|
|
||||||
if (config.config().guest.video_sync) {
|
if (config.config().guest.video_sync) {
|
||||||
|
|
|
@ -15,6 +15,9 @@ const pitch = @import("core/ppu.zig").framebuf_pitch;
|
||||||
const gba_width = @import("core/ppu.zig").width;
|
const gba_width = @import("core/ppu.zig").width;
|
||||||
const gba_height = @import("core/ppu.zig").height;
|
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";
|
const default_title: []const u8 = "ZBA";
|
||||||
|
|
||||||
pub const Gui = struct {
|
pub const Gui = struct {
|
||||||
|
@ -253,7 +256,6 @@ pub const Gui = struct {
|
||||||
const Audio = struct {
|
const Audio = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
const log = std.log.scoped(.PlatformAudio);
|
const log = std.log.scoped(.PlatformAudio);
|
||||||
const sample_rate = @import("core/apu.zig").host_sample_rate;
|
|
||||||
|
|
||||||
device: SDL.SDL_AudioDeviceID,
|
device: SDL.SDL_AudioDeviceID,
|
||||||
|
|
||||||
|
@ -261,7 +263,7 @@ const Audio = struct {
|
||||||
var have: SDL.SDL_AudioSpec = undefined;
|
var have: SDL.SDL_AudioSpec = undefined;
|
||||||
var want: SDL.SDL_AudioSpec = std.mem.zeroes(SDL.SDL_AudioSpec);
|
var want: SDL.SDL_AudioSpec = std.mem.zeroes(SDL.SDL_AudioSpec);
|
||||||
want.freq = sample_rate;
|
want.freq = sample_rate;
|
||||||
want.format = SDL.AUDIO_U16;
|
want.format = sample_format;
|
||||||
want.channels = 2;
|
want.channels = 2;
|
||||||
want.samples = 0x100;
|
want.samples = 0x100;
|
||||||
want.callback = Self.callback;
|
want.callback = Self.callback;
|
||||||
|
@ -270,7 +272,8 @@ const Audio = struct {
|
||||||
const device = SDL.SDL_OpenAudioDevice(null, 0, &want, &have, 0);
|
const device = SDL.SDL_OpenAudioDevice(null, 0, &want, &have, 0);
|
||||||
if (device == 0) panic();
|
if (device == 0) panic();
|
||||||
|
|
||||||
SDL.SDL_PauseAudioDevice(device, 0); // Unpause Audio
|
if (!config.config().host.mute)
|
||||||
|
SDL.SDL_PauseAudioDevice(device, 0); // Unpause Audio
|
||||||
|
|
||||||
return .{ .device = device };
|
return .{ .device = device };
|
||||||
}
|
}
|
||||||
|
@ -281,18 +284,10 @@ const Audio = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn callback(userdata: ?*anyopaque, stream: [*c]u8, len: c_int) void {
|
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
|
_ = SDL.SDL_AudioStreamGet(apu.stream, stream, len);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue