Compare commits
5 Commits
3fe577abb9
...
apu-things
| Author | SHA1 | Date | |
|---|---|---|---|
| 2f2c03b96d | |||
| 9a2b7a48c0 | |||
| fe908a6ea9 | |||
| bf95eee3f1 | |||
| 240fbcb1df |
Submodule lib/zig-clap updated: dbc6b8e54a...a1b01ffeab
Submodule lib/zig-toml updated: 3cc4bb6dfb...016b8bcf98
@@ -58,7 +58,10 @@ pub fn load(allocator: Allocator, file_path: []const u8) !void {
|
|||||||
const contents = try config_file.readToEndAlloc(allocator, try config_file.getEndPos());
|
const contents = try config_file.readToEndAlloc(allocator, try config_file.getEndPos());
|
||||||
defer allocator.free(contents);
|
defer allocator.free(contents);
|
||||||
|
|
||||||
const table = try toml.parseContents(allocator, contents, null);
|
var parser = try toml.parseFile(allocator, file_path);
|
||||||
|
defer parser.deinit();
|
||||||
|
|
||||||
|
const table = try parser.parse();
|
||||||
defer table.deinit();
|
defer table.deinit();
|
||||||
|
|
||||||
// TODO: Report unknown config options
|
// TODO: Report unknown config options
|
||||||
|
|||||||
@@ -94,10 +94,9 @@ pub fn sound1CntL(self: *const Self) u8 {
|
|||||||
pub fn setSound1CntL(self: *Self, value: u8) void {
|
pub fn setSound1CntL(self: *Self, value: u8) void {
|
||||||
const new = io.Sweep{ .raw = value };
|
const new = io.Sweep{ .raw = value };
|
||||||
|
|
||||||
if (self.sweep.direction.read() and !new.direction.read()) {
|
if (!new.direction.read()) {
|
||||||
// Sweep Negate bit has been cleared
|
// If at least one (1) sweep calculation has been made with
|
||||||
// If At least 1 Sweep Calculation has been made since
|
// the negate bit set (since last trigger), disable the channel
|
||||||
// the last trigger, the channel is immediately disabled
|
|
||||||
|
|
||||||
if (self.sweep_dev.calc_performed) self.enabled = false;
|
if (self.sweep_dev.calc_performed) self.enabled = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ pub fn tick(self: *Self, ch1: *ToneSweep) void {
|
|||||||
if (self.timer == 0) {
|
if (self.timer == 0) {
|
||||||
const period = ch1.sweep.period.read();
|
const period = ch1.sweep.period.read();
|
||||||
self.timer = if (period == 0) 8 else period;
|
self.timer = if (period == 0) 8 else period;
|
||||||
if (!self.calc_performed) self.calc_performed = true;
|
|
||||||
|
|
||||||
if (self.enabled and period != 0) {
|
if (self.enabled and period != 0) {
|
||||||
const new_freq = self.calculate(ch1.sweep, &ch1.enabled);
|
const new_freq = self.calculate(ch1.sweep, &ch1.enabled);
|
||||||
@@ -52,7 +51,10 @@ pub fn calculate(self: *Self, sweep: io.Sweep, ch_enable: *bool) u12 {
|
|||||||
const shadow_shifted = shadow >> sweep.shift.read();
|
const shadow_shifted = shadow >> sweep.shift.read();
|
||||||
const decrease = sweep.direction.read();
|
const decrease = sweep.direction.read();
|
||||||
|
|
||||||
const freq = if (decrease) shadow - shadow_shifted else shadow + shadow_shifted;
|
const freq = if (decrease) blk: {
|
||||||
|
self.calc_performed = true;
|
||||||
|
break :blk shadow - shadow_shifted;
|
||||||
|
} else shadow + shadow_shifted;
|
||||||
if (freq > 0x7FF) ch_enable.* = false;
|
if (freq > 0x7FF) ch_enable.* = false;
|
||||||
|
|
||||||
return freq;
|
return freq;
|
||||||
|
|||||||
55
src/util.zig
55
src/util.zig
@@ -282,7 +282,9 @@ pub fn RingBuffer(comptime T: type) type {
|
|||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
const Index = usize;
|
const Index = usize;
|
||||||
const max_capacity = (std.math.powi(Index, 2, @typeInfo(Index).Int.bits - 1) catch @compileError("uhhhhh")) - 1;
|
const max_capacity = (@as(Index, 1) << @typeInfo(Index).Int.bits - 1) - 1; // half the range of index type
|
||||||
|
|
||||||
|
const log = std.log.scoped(.RingBuffer);
|
||||||
|
|
||||||
read: Index,
|
read: Index,
|
||||||
write: Index,
|
write: Index,
|
||||||
@@ -294,8 +296,10 @@ pub fn RingBuffer(comptime T: type) type {
|
|||||||
const Error = error{buffer_full};
|
const Error = error{buffer_full};
|
||||||
|
|
||||||
pub fn init(buf: []T) Self {
|
pub fn init(buf: []T) Self {
|
||||||
|
std.mem.set(T, buf, 0);
|
||||||
|
|
||||||
std.debug.assert(std.math.isPowerOfTwo(buf.len)); // capacity must be a power of two
|
std.debug.assert(std.math.isPowerOfTwo(buf.len)); // capacity must be a power of two
|
||||||
std.debug.assert(buf.len <= max_capacity); // Capacity must be half the range of the index data types
|
std.debug.assert(buf.len <= max_capacity);
|
||||||
|
|
||||||
return .{ .read = 0, .write = 0, .buf = buf, .mutex = .{} };
|
return .{ .read = 0, .write = 0, .buf = buf, .mutex = .{} };
|
||||||
}
|
}
|
||||||
@@ -315,14 +319,14 @@ pub fn RingBuffer(comptime T: type) type {
|
|||||||
self.mutex.lock();
|
self.mutex.lock();
|
||||||
defer self.mutex.unlock();
|
defer self.mutex.unlock();
|
||||||
|
|
||||||
if (self.isEmpty()) return null;
|
return self._pop();
|
||||||
defer self.read += 1;
|
|
||||||
|
|
||||||
return self.buf[self.mask(self.read)];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(self: *const Self) Index {
|
pub fn len(self: *Self) Index {
|
||||||
return self.write - self.read;
|
self.mutex.lock();
|
||||||
|
defer self.mutex.unlock();
|
||||||
|
|
||||||
|
return self._len();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _push(self: *Self, value: T) Error!void {
|
fn _push(self: *Self, value: T) Error!void {
|
||||||
@@ -332,8 +336,19 @@ pub fn RingBuffer(comptime T: type) type {
|
|||||||
self.buf[self.mask(self.write)] = value;
|
self.buf[self.mask(self.write)] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _pop(self: *Self) ?T {
|
||||||
|
if (self.isEmpty()) return null;
|
||||||
|
defer self.read += 1;
|
||||||
|
|
||||||
|
return self.buf[self.mask(self.read)];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _len(self: *const Self) Index {
|
||||||
|
return self.write - self.read;
|
||||||
|
}
|
||||||
|
|
||||||
fn isFull(self: *const Self) bool {
|
fn isFull(self: *const Self) bool {
|
||||||
return self.len() == self.buf.len;
|
return self._len() == self.buf.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn isEmpty(self: *const Self) bool {
|
fn isEmpty(self: *const Self) bool {
|
||||||
@@ -345,3 +360,25 @@ pub fn RingBuffer(comptime T: type) type {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "RingBuffer" {
|
||||||
|
const Queue = RingBuffer(u8);
|
||||||
|
|
||||||
|
var buf: [4]u8 = undefined;
|
||||||
|
var queue = Queue.init(&buf);
|
||||||
|
|
||||||
|
try queue.push(1, 2);
|
||||||
|
try std.testing.expectEqual(@as(?u8, 1), queue.pop());
|
||||||
|
|
||||||
|
try queue.push(3, 4);
|
||||||
|
try std.testing.expectError(Queue.Error.buffer_full, queue.push(5, 6));
|
||||||
|
try std.testing.expectEqual(@as(?u8, 2), queue.pop());
|
||||||
|
|
||||||
|
try queue.push(7, 8);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(@as(?u8, 3), queue.pop());
|
||||||
|
try std.testing.expectEqual(@as(?u8, 4), queue.pop());
|
||||||
|
try std.testing.expectEqual(@as(?u8, 7), queue.pop());
|
||||||
|
try std.testing.expectEqual(@as(?u8, 8), queue.pop());
|
||||||
|
try std.testing.expectEqual(@as(?u8, null), queue.pop());
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user