Skip to content

Commit

Permalink
move dcadjuster into its own module
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Jul 20, 2024
1 parent 1b1f48b commit 4cc4841
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 21 deletions.
25 changes: 4 additions & 21 deletions src/chips/ay3891.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
const bitutils = @import("common").bitutils;
const mask = bitutils.mask;
const maskm = bitutils.maskm;
const dcadjust = @import("common").dcadjust;

/// map chip pin names to bit positions
///
Expand Down Expand Up @@ -91,7 +92,6 @@ pub fn Type(comptime cfg: Config) type {
// misc constants
const NUM_CHANNELS = 3;
const FIXEDPOINT_SCALE = 16; // error accumulation precision boost
const DCADJ_BUFLEN = 128;

// registers
pub const REG = struct {
Expand Down Expand Up @@ -177,11 +177,7 @@ 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: struct {
sum: f32 = 0.0,
pos: u32 = 0.0,
buf: [DCADJ_BUFLEN]f32 = [_]f32{0.0} ** DCADJ_BUFLEN,
} = .{},
dcadj: dcadjust.Type(.{ .buf_len = 128 }) = .{},
};

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

pub fn reset(self: *Self) void {
self.active = false;
self.sample.dcadjust.reset();
self.addr = 0;
self.tick_count = 0;
for (&self.regs) |r| {
Expand Down Expand Up @@ -345,28 +342,14 @@ pub fn Type(comptime cfg: Config) type {
}
}
}
self.sample.value = dcadjust(self, sm) * self.sample.volume;
self.sample.value = self.sample.dcadj.put(sm) * self.sample.volume;
self.sample.ready = true;
} else {
self.sample.ready = false;
}
return bus;
}

// DC adjustment filter from StSound, this moves an "offcenter"
// signal back to the zero-line (e.g. the volume-level output
// from the chip simulation which is >0.0 gets converted to
//a +/- sample value)
fn dcadjust(self: *Self, s: f32) f32 {
const pos = self.sample.dcadj.pos;
self.sample.dcadj.sum -= self.sample.dcadj.buf[pos];
self.sample.dcadj.sum += s;
self.sample.dcadj.buf[pos] = s;
self.sample.dcadj.pos = (pos + 1) & (DCADJ_BUFLEN - 1);
const div: f32 = @floatFromInt(DCADJ_BUFLEN);
return s - (self.sample.dcadj.sum / div);
}

// write from data bus to register
fn write(self: *Self, bus: Bus) void {
const data = getData(bus);
Expand Down
1 change: 1 addition & 0 deletions src/common/common.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +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");
35 changes: 35 additions & 0 deletions src/common/dcadjust.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! an audio DC adjuster (centers an off-center signal)
//! see: https://github.com/arnaud-carre/StSound/blob/91d2d3c604386c637b038bba747c8da6c976c245/StSoundLibrary/Ym2149Ex.cpp#L67-L93
const std = @import("std");
const assert = std.debug.assert;
const isPowerOfTwo = std.math.isPowerOfTwo;

pub const Config = struct {
buf_len: comptime_int,
};

pub fn Type(cfg: Config) type {
assert(isPowerOfTwo(cfg.buf_len));

return struct {
const Self = @This();

sum: f32 = 0,
pos: u32 = 0,
buf: [cfg.buf_len]f32 = [_]f32{0.0} ** cfg.buf_len,

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

pub fn put(self: *Self, s: f32) f32 {
const pos = self.pos;
self.sum -= self.buf[pos];
self.sum += s;
self.buf[pos] = s;
self.pos = (pos + 1) & (cfg.buf_len - 1);
const div: f32 = @floatFromInt(cfg.buf_len);
return s - (self.sum / div);
}
};
}

0 comments on commit 4cc4841

Please sign in to comment.