const std = @import("std"); const print = std.debug.print; const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; pub const FreqAmp = struct { freq: f64, r_amp: f64, phase: f64, pub fn create(allocator: Allocator, freq: f64, r_amp: f64, phase: f64) !*FreqAmp { const fa = try allocator.create(FreqAmp); fa.* = .{.freq = freq, .r_amp = r_amp, .phase = phase}; return fa; } pub fn prnt(self: *FreqAmp) void { print("<{d}::{d}::{d}>\n", .{self.freq, self.r_amp, self.phase}); } }; pub const FreqAmpList = struct { allocator: Allocator, refcount: u64, arraylist: ArrayList(*FreqAmp), pub fn create(allocator: Allocator) !*FreqAmpList { const arraylist = ArrayList(*FreqAmp).init(allocator); const fal = try allocator.create(FreqAmpList); fal.* = .{ .allocator = allocator, .refcount = 0, .arraylist = arraylist, }; return fal; } pub fn add_fa(self: *FreqAmpList, fa: *FreqAmp) !void { try self.arraylist.append(fa); } pub fn setfreq(self: *FreqAmpList, freq: f64, r_amp: f64, phase: f64) !void { for (self.arraylist.items) |fa| { if (fa.freq == freq and fa.phase == phase) { fa.r_amp = r_amp; return; } } const fa = try FreqAmp.create(self.allocator, freq, r_amp, phase); try self.arraylist.append(fa); } pub fn addfreq(self: *FreqAmpList, freq: f64, r_amp: f64, phase: f64) !void { for (self.arraylist.items) |fa| { if (fa.freq == freq and fa.phase == phase) { fa.r_amp = r_amp; if (fa.r_amp > 1) { fa.r_amp = 1; } return; } } const fa = try FreqAmp.create(self.allocator, freq, r_amp, phase); try self.arraylist.append(fa); } pub fn deinit(self: *FreqAmpList) void { if (0>0) { for (self.arraylist.items) |freqamp| { self.allocator.destroy(freqamp); } } self.arraylist.deinit(); } pub fn prnt(self: *FreqAmpList) void { print("\n", .{self.refcount}); for (self.arraylist.items) |freqamp| { freqamp.prnt(); } print("\n", .{}); } }; pub const FreqAmpBuffer = struct { const buffer_ticks_default = 44100 * 2; allocator: Allocator, buffer_ticks: u32 = buffer_ticks_default, current_tick: u32, current_index: u32, fal_array: [buffer_ticks_default]*FreqAmpList, pub fn init(allocator: Allocator) !FreqAmpBuffer { //Creating an empty filler FreaAmpList var initial_list = try FreqAmpList.create(allocator); initial_list.refcount = buffer_ticks_default; //Initializing the array with empry FreaAmpLists var fal_array: [buffer_ticks_default]*FreqAmpList = undefined; @memset(&fal_array, initial_list); return .{ .allocator = allocator, .current_tick = 0, .current_index = 0, .fal_array = fal_array, }; } pub fn deinit(self: *FreqAmpBuffer) void { //Need to redo this _ = self; } pub fn increment_tick(self: *FreqAmpBuffer) void { const prev_index = self.current_index; self.current_tick += 1; const cur_index = self.index_by_tick(self.current_tick); self.current_index = cur_index; self.fal_array[cur_index].refcount -= 1; self.fal_array[prev_index].refcount += 1; if (self.fal_array[cur_index].refcount == 0) { defer self.fal_array[cur_index].deinit(); } self.fal_array[cur_index] = self.fal_array[prev_index]; } pub fn index_by_tick(self: *FreqAmpBuffer, tick: u32) u32 { return tick % self.buffer_ticks; } pub fn current_list(self: *FreqAmpBuffer) *FreqAmpList { const cur_index = self.index_by_tick(self.current_tick); return self.fal_array[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.current_index; const next_index = self.index_by_tick(self.current_tick+%1); print("{d}: {*}\n", .{self.current_tick-%1, self.fal_array[prev_index]}); self.fal_array[prev_index].prnt(); print("{d}: {*}\n", .{self.current_tick, self.fal_array[cur_index]}); self.fal_array[cur_index].prnt(); print("{d}: {*}\n", .{self.current_tick+%1, self.fal_array[next_index]}); self.fal_array[next_index].prnt(); } pub fn reset(self: *FreqAmpBuffer) !void { const prev_index = self.index_by_tick(self.current_tick -% 1); const cur_index = self.current_index; if (self.fal_array[cur_index] == self.fal_array[prev_index]) { var clist = self.fal_array[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.fal_array[cur_index] = new_list; } } pub fn setfreq(self: *FreqAmpBuffer, freq: f64, r_amp: f64, phase: f64) !void { var current_fal = self.fal_array[self.current_index]; try current_fal.setfreq(freq, r_amp, phase); } pub fn add_fa(self: *FreqAmpBuffer, fa: *FreqAmp) !void { var current_fal = self.fal_array[self.current_index]; try current_fal.add_fa(fa); } pub fn addfreq(self: *FreqAmpBuffer, freq: f64, r_amp: f64, phase: f64) !void { var current_fal = self.fal_array[self.current_index]; try current_fal.addfreq(freq, r_amp, phase); } pub fn get_fal(self: *FreqAmpBuffer, tick: u32) *FreqAmpList { return self.fal_array[self.index_by_tick(tick)]; } };