const std = @import("std"); const print = std.debug.print; const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; pub const FreqAmp = struct { freq: f16, r_amp: f16, pub fn create(allocator: Allocator, freq: f16, r_amp: f16) !*FreqAmp { const fa = try allocator.create(FreqAmp); fa.* = .{.freq = freq, .r_amp = r_amp}; return fa; } pub fn prnt(self: *FreqAmp) void { print("<{d}::{d}>\n", .{self.freq, self.r_amp}); } }; pub const FreqAmpList = struct { allocator: Allocator, refcount: u64, lst: ArrayList(*FreqAmp), pub fn create(allocator: Allocator) !*FreqAmpList { const lst = ArrayList(*FreqAmp).init(allocator); const fal = try allocator.create(FreqAmpList); fal.* = .{ .allocator = allocator, .refcount = 0, .lst = lst, }; return fal; } pub fn deinit(self: *FreqAmpList) void { for (self.lst.items) |freqamp| { self.allocator.destroy(freqamp); } self.lst.deinit(); } pub fn prnt(self: *FreqAmpList) void { print("\n", .{self.refcount}); for (self.lst.items) |freqamp| { freqamp.prnt(); } print("\n", .{}); } }; pub const FreqAmpBuffer = struct { const buffer_ticks_default = 44100; allocator: Allocator, buffer_ticks: u32 = buffer_ticks_default, current_tick: u32, freqamps: [buffer_ticks_default]*FreqAmpList, pub fn init(allocator: Allocator) !FreqAmpBuffer { const current_tick = 0; var initial_list = try FreqAmpList.create(allocator); initial_list.refcount = buffer_ticks_default; initial_list.prnt(); var freqamps: [buffer_ticks_default]*FreqAmpList = undefined; @memset(&freqamps, initial_list); return .{ .allocator = allocator, .current_tick = current_tick, .freqamps = freqamps, }; } pub fn deinit(self: *FreqAmpBuffer) void { _ = self; } pub fn increment_tick(self: *FreqAmpBuffer) void { const prev_index = self.index_by_tick(self.current_tick); self.current_tick += 1; const cur_index = self.index_by_tick(self.current_tick); self.freqamps[cur_index].refcount -= 1; self.freqamps[prev_index].refcount += 1; if (self.freqamps[cur_index].refcount == 0) { defer self.freqamps[cur_index].deinit(); } self.freqamps[cur_index] = self.freqamps[prev_index]; } pub fn index_by_tick(self: *FreqAmpBuffer, tick: u32) u32 { return tick % self.buffer_ticks; } pub fn current_index(self: *FreqAmpBuffer) u32 { return self.index_by_tick(self.current_tick); } pub fn current_list(self: *FreqAmpBuffer) *FreqAmpList { const cur_index = self.index_by_tick(self.current_tick); return self.freqamps[cur_index]; } pub fn prnt(self: *FreqAmpBuffer) void { print("CURRENT STATE:\n", .{}); const prev_index = self.index_by_tick(self.current_tick-%1); const cur_index = self.index_by_tick(self.current_tick); const next_index = self.index_by_tick(self.current_tick+%1); print("{d}: {*}\n", .{self.current_tick-%1, self.freqamps[prev_index]}); self.freqamps[prev_index].prnt(); print("{d}: {*}\n", .{self.current_tick, self.freqamps[cur_index]}); self.freqamps[cur_index].prnt(); print("{d}: {*}\n", .{self.current_tick+%1, self.freqamps[next_index]}); self.freqamps[next_index].prnt(); } pub fn reset(self: *FreqAmpBuffer) !void { const prev_index = self.index_by_tick(self.current_tick -% 1); const cur_index = self.index_by_tick(self.current_tick); if (self.freqamps[cur_index] == self.freqamps[prev_index]) { var clist = self.freqamps[cur_index]; clist.refcount -= 1; if (clist.refcount == 0) { defer clist.deinit(); } var new_list = try FreqAmpList.create(self.allocator); new_list.refcount += 1; self.freqamps[cur_index] = new_list; } } pub fn setfreq(self: *FreqAmpBuffer, freq: f16, r_amp: f16) !void { const cur_index = self.index_by_tick(self.current_tick); var clist = self.freqamps[cur_index]; // If this freq already is set, sum the r_amps for (clist.lst.items) |freqamp| { if (freqamp.freq == freq) { freqamp.r_amp = r_amp; return; } } // Otherwise, append new freqamp const fa = try FreqAmp.create(self.allocator, freq, r_amp); try clist.lst.append(fa); } pub fn addfreq(self: *FreqAmpBuffer, freq: f16, r_amp: f16) !void { const cur_index = self.index_by_tick(self.current_tick); var clist = self.freqamps[cur_index]; // If this freq already is set, sum the r_amps for (clist.lst.items) |freqamp| { if (freqamp.freq == freq) { freqamp.r_amp += r_amp; if (freqamp.r_amp > 1) { freqamp.r_amp = 1; } return; } } // Otherwise, append new freqamp const fa = try FreqAmp.create(self.allocator, freq, r_amp); try clist.lst.append(fa); } }; pub fn nmain() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); var fab = try FreqAmpBuffer.init(allocator); defer fab.deinit(); try fab.reset(); try fab.setfreq(440.0, 0.84); try fab.setfreq(440, 0.854); try fab.setfreq(441.3, 0.8); try fab.reset(); fab.prnt(); fab.increment_tick(); print("\nINCREMENT TICK\n\n", .{}); fab.prnt(); }