Skip to content

Commit

Permalink
add lowpass filter from StSound
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Jul 22, 2024
1 parent cf8a170 commit a6eaca7
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 41 deletions.
14 changes: 10 additions & 4 deletions src/chips/ay3891.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
const bitutils = @import("common").bitutils;
const mask = bitutils.mask;
const maskm = bitutils.maskm;
const dcadjust = @import("common").dcadjust;
const filter = @import("common").filter;

/// map chip pin names to bit positions
///
Expand Down Expand Up @@ -46,6 +46,8 @@ pub const Config = struct {
model: Model = .AY38910,
pins: Pins,
bus: type,
dcadjust_buf_len: u32 = 128,
enable_lowpass_filter: bool = true,
};

pub fn Type(comptime cfg: Config) type {
Expand Down Expand Up @@ -177,7 +179,11 @@ pub fn Type(comptime cfg: Config) type {
volume: f32 = 0.0,
value: f32 = 0.0,
ready: bool = false, // true if a new sample value is ready
dcadj: dcadjust.Type(.{ .buf_len = 128 }) = .{},
filter: filter.Type(.{
.enable_dcadjust = true,
.enable_lowpass_filter = cfg.enable_lowpass_filter,
.dcadjust_buf_len = cfg.dcadjust_buf_len,
}) = .{},
};

tick_count: u38 = 0, // tick counter for internal clock division
Expand Down Expand Up @@ -240,7 +246,7 @@ pub fn Type(comptime cfg: Config) type {

pub fn reset(self: *Self) void {
self.active = false;
self.sample.dcadjust.reset();
self.sample.filter.reset();
self.addr = 0;
self.tick_count = 0;
for (&self.regs) |r| {
Expand Down Expand Up @@ -342,7 +348,7 @@ pub fn Type(comptime cfg: Config) type {
}
}
}
self.sample.value = self.sample.dcadj.put(sm) * self.sample.volume;
self.sample.value = self.sample.filter.put(sm) * self.sample.volume;
self.sample.ready = true;
} else {
self.sample.ready = false;
Expand Down
2 changes: 1 addition & 1 deletion src/common/common.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ pub const bitutils = @import("bitutils.zig");
pub const memory = @import("memory.zig");
pub const glue = @import("glue.zig");
pub const clock = @import("clock.zig");
pub const dcadjust = @import("dcadjust.zig");
pub const filter = @import("filter.zig");
35 changes: 0 additions & 35 deletions src/common/dcadjust.zig

This file was deleted.

57 changes: 57 additions & 0 deletions src/common/filter.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//! audio filter (dc adjustment and lowpass filter)
//! taken from: https://github.com/arnaud-carre/StSound
const std = @import("std");
const assert = std.debug.assert;
const isPowerOfTwo = std.math.isPowerOfTwo;

pub const Config = struct {
enable_dcadjust: bool,
enable_lowpass_filter: bool,
dcadjust_buf_len: u32,
};

pub fn Type(cfg: Config) type {
assert(isPowerOfTwo(cfg.dcadjust_buf_len));
return struct {
const Self = @This();

lopass: [2]f32 = [_]f32{0} ** 2,
dcadj: struct {
sum: f32 = 0,
pos: u32 = 0,
buf: [cfg.dcadjust_buf_len]f32 = [_]f32{0} ** cfg.dcadjust_buf_len,
} = .{},

pub fn reset(self: *Self) void {
self.* = .{};
}

pub fn put(self: *Self, in: f32) f32 {
var s = in;
if (cfg.enable_dcadjust) {
s = self.dcAdjust(s);
}
if (cfg.enable_lowpass_filter) {
s = self.lowPassFilter(s);
}
return s;
}

fn dcAdjust(self: *Self, in: f32) f32 {
const pos = self.dcadj.pos;
self.dcadj.sum -= self.dcadj.buf[pos];
self.dcadj.sum += in;
self.dcadj.buf[pos] = in;
self.dcadj.pos = (pos + 1) & (cfg.dcadjust_buf_len - 1);
const div: f32 = @floatFromInt(cfg.dcadjust_buf_len);
return in - (self.dcadj.sum / div);
}

fn lowPassFilter(self: *Self, in: f32) f32 {
const out = self.lopass[0] * 0.25 + self.lopass[1] * 0.5 + in * 0.25;
self.lopass[0] = self.lopass[1];
self.lopass[1] = in;
return out;
}
};
}
8 changes: 7 additions & 1 deletion src/systems/namco.zig
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const z80 = @import("chips").z80;
const common = @import("common");
const memory = common.memory;
const clock = common.clock;
const filter = common.filter;
const pin = common.bitutils.pin;
const AudioCallback = common.glue.AudioCallback;
const AudioOptions = common.glue.AudioOptions;
Expand Down Expand Up @@ -386,6 +387,11 @@ pub fn Type(comptime sys: System) type {
sample_counter: i32,
volume: f32,
voices: [3]AudioVoice = [_]AudioVoice{.{}} ** 3,
filter: filter.Type(.{
.enable_dcadjust = false,
.enable_lowpass_filter = true,
.dcadjust_buf_len = 2,
}) = .{},
num_samples: u32,
sample_pos: u32,
callback: AudioCallback,
Expand Down Expand Up @@ -918,7 +924,7 @@ pub fn Type(comptime sys: System) type {
}
}
sm *= snd.volume * 0.333333;
snd.sample_buffer[snd.sample_pos] = sm;
snd.sample_buffer[snd.sample_pos] = self.audio.filter.put(sm);
snd.sample_pos += 1;
if (snd.sample_pos == snd.num_samples) {
if (snd.callback) |cb| {
Expand Down

0 comments on commit a6eaca7

Please sign in to comment.