diff --git a/zigsonnum/activity.zig b/zigsonnum/activity.zig index 6391747..29823c2 100644 --- a/zigsonnum/activity.zig +++ b/zigsonnum/activity.zig @@ -1,15 +1,54 @@ +const std = @import("std"); +const print = std.debug.print; const SoundNode = @import("soundnode.zig").SoundNode; pub const Activity = struct { - start_tick: u64, - end_tick: u64, + start_tick: u32, + end_tick: u32, opcode: u16, soundnode: *SoundNode, - operands: ?[10]f16, + operands: [10]f16 = std.mem.zeroes([10]f16), pub fn do(self: *Activity) !void { - try self.soundnode.freqmap.put(440, 0.8); + switch (self.opcode) { + 0 => { try self.reset(); }, + 1 => { try self.setfreq(); }, + 2 => { try self.relay(); }, + else => {}, + } + } + + pub fn reset(self: *Activity) !void { + try self.soundnode.freqamp.reset(); + } + + pub fn setfreq(self: *Activity) !void { + try self.soundnode.freqamp.setfreq(self.operands[0], self.operands[1]); + } + + pub fn relay(self: *Activity) !void { + + try self.soundnode.freqamp.reset(); + + for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { + + const current_index: u32 = self.soundnode.freqamp.current_index(); + if (current_index == 0) { + print("relaying {s} to {s}\n", .{wired_sn.name, self.soundnode.name}); + } + + const clist = wired_sn.freqamp.freqamps[current_index]; + + for (clist.lst.items) |freqamp| { + try self.soundnode.freqamp.addfreq(freqamp.freq, freqamp.r_amp); + } + + _ = i; + + } + + } }; \ No newline at end of file diff --git a/zigsonnum/freqamp.zig b/zigsonnum/freqamp.zig index b5fd075..39e1d30 100644 --- a/zigsonnum/freqamp.zig +++ b/zigsonnum/freqamp.zig @@ -69,11 +69,11 @@ pub const FreqAmpList = struct { pub const FreqAmpBuffer = struct { - const buffer_ticks_default = 44100 * 2; + const buffer_ticks_default = 44100 * 3; allocator: Allocator, - buffer_ticks: u64 = buffer_ticks_default, - current_tick: u64, + buffer_ticks: u32 = buffer_ticks_default, + current_tick: u32, freqamps: [buffer_ticks_default]*FreqAmpList, pub fn init(allocator: Allocator) !FreqAmpBuffer { @@ -105,77 +105,123 @@ pub const FreqAmpBuffer = struct { const prev_index = self.index_by_tick(self.current_tick); self.current_tick += 1; - const current_index = self.index_by_tick(self.current_tick); + const cur_index = self.index_by_tick(self.current_tick); - self.freqamps[current_index].refcount -= 1; + self.freqamps[cur_index].refcount -= 1; self.freqamps[prev_index].refcount += 1; - if (self.freqamps[current_index].refcount == 0) { - defer self.freqamps[current_index].deinit(); + if (self.freqamps[cur_index].refcount == 0) { + defer self.freqamps[cur_index].deinit(); } - self.freqamps[current_index] = self.freqamps[prev_index]; + self.freqamps[cur_index] = self.freqamps[prev_index]; } - pub fn index_by_tick(self: *FreqAmpBuffer, tick: u64) u64 { + 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 current_index = self.index_by_tick(self.current_tick); - return self.freqamps[current_index]; + 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", .{}); - print("0: {*}\n", .{self.freqamps[0]}); - self.freqamps[0].prnt(); - print("1: {*}\n", .{self.freqamps[1]}); - self.freqamps[1].prnt(); - print("2: {*}\n", .{self.freqamps[2]}); - self.freqamps[2].prnt(); + + 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 current_index = self.index_by_tick(self.current_tick); - var clist = self.freqamps[current_index]; - - clist.refcount -= 1; + const prev_index = self.index_by_tick(self.current_tick -% 1); + const cur_index = self.index_by_tick(self.current_tick); - if (clist.refcount == 0) { - defer clist.deinit(); + 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; } - - var new_list = try FreqAmpList.create(self.allocator); - - new_list.refcount += 1; - self.freqamps[current_index] = new_list; } pub fn setfreq(self: *FreqAmpBuffer, freq: f16, r_amp: f16) !void { - const current_index = self.index_by_tick(self.current_tick); - var clist = self.freqamps[current_index]; + 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 + // Currently turned off - print("!! {*} !!\n", .{clist}); + if (0>0) { + 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) { + if (0>0) { + for (clist.lst.items) |freqamp| { - freqamp.r_amp = r_amp; - return; + if (freqamp.freq == freq) { + + freqamp.r_amp += r_amp; + + if (freqamp.r_amp > 1) { + freqamp.r_amp = 1; + } + + return; + } + } - } // Otherwise, append new freqamp @@ -189,7 +235,7 @@ pub const FreqAmpBuffer = struct { }; -pub fn main() !void { +pub fn nmain() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); @@ -197,10 +243,13 @@ pub fn main() !void { 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(); diff --git a/zigsonnum/sonnum.zig b/zigsonnum/sonnum.zig index 5e1dbae..fdc033d 100644 --- a/zigsonnum/sonnum.zig +++ b/zigsonnum/sonnum.zig @@ -10,43 +10,75 @@ const Activity = @import("activity.zig").Activity; const SoundSettings = @import("settings.zig").SoundSettings; -pub fn singleSineTick(st: *SoundSettings, freq: u16, t: u64) f64 { +pub fn singleSineTick(st: *SoundSettings, freq: f16, t: u32) f64 { const ft: f64 = @floatFromInt(t); - const fr: f64 = @floatFromInt(freq); - return math.sin(st.sine_multiplier * fr * ft); - //return math.sin(st.sine_multiplier * @as(f64, freq) * ft); + return math.sin(st.sine_multiplier * @as(f64, freq) * ft); } pub fn main() !void { - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - const allocator = gpa.allocator(); + //var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + //const allocator = gpa.allocator(); + + const allocator = std.heap.c_allocator; var settings: SoundSettings = SoundSettings{}; - const start_tick: u64 = 0; - const end_tick: u64 = 44100 * 2; + const start_tick: u32 = 0; + const end_tick: u32 = 44100 * 120; - var sn1: SoundNode = try SoundNode.init(allocator, "sine"); - defer sn1.deinit(); + var left: SoundNode = try SoundNode.init(allocator, "left_sink"); + defer left.deinit(); + left.location.x = -0.15; + + var right: SoundNode = try SoundNode.init(allocator, "right_sink"); + defer right.deinit(); + right.location.x = 0.15; + + var sine: SoundNode = try SoundNode.init(allocator, "sine"); + defer sine.deinit(); var a = Activity{ .start_tick = 0, .end_tick = 0, .opcode = 1, - .soundnode = &sn1, - .operands = undefined, + .soundnode = &sine, }; - - try sn1.activities.append(&a); + + a.operands[0] = 410.0; + a.operands[1] = 0.8; + + try sine.activities.append(&a); + + var a2 = Activity{ + .start_tick = 0, + .end_tick = end_tick, + .opcode = 2, + .soundnode = &left, + }; + try left.activities.append(&a2); + + var a3 = Activity{ + .start_tick = 0, + .end_tick = end_tick, + .opcode = 2, + .soundnode = &right, + }; + try right.activities.append(&a3); var soundnodes = ArrayList(*SoundNode).init(allocator); defer soundnodes.deinit(); - try soundnodes.append(&sn1); + //Preset sink nodes + try soundnodes.append(&sine); + try soundnodes.append(&left); + try soundnodes.append(&right); - var tick: u64 = start_tick; + try left.wire_in.append(&sine); + try right.wire_in.append(&sine); + + var tick: u32 = start_tick; //STARTING WAV const stdout_file = std.io.getStdOut().writer(); @@ -57,7 +89,7 @@ pub fn main() !void { try stdout.writeAll("RIFF"); try stdout.writeInt( - u64, + u32, 36 + (end_tick * 2 * settings.sample_width), Endian.little, ); @@ -78,7 +110,7 @@ pub fn main() !void { try stdout.writeAll("data"); try stdout.writeInt( - u64, + u32, end_tick * 2 * settings.sample_width, Endian.little, ); @@ -87,30 +119,50 @@ pub fn main() !void { while (tick < end_tick) { + if (tick%44100 == 0) { + print("TICK {d}\n", .{tick}); + } + for (soundnodes.items, 0..) |soundnode, i| { for (soundnode.activities.items, 0..) |activity, j| { - try activity.do(); + if (tick <= activity.end_tick and tick >= activity.start_tick) { + try activity.do(); + } + _ = j; } - var amp: f64 = 0; - var it = soundnode.freqmap.iterator(); - - while (it.next()) |entry| { - - amp += entry.value_ptr.* * singleSineTick(&settings, @as(u16, entry.key_ptr.*), tick); - } - - sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp))); - - try stdout.writeInt(i24, sample, Endian.little); - try stdout.writeInt(i24, sample, Endian.little); + soundnode.freqamp.increment_tick(); _ = i; } + + var amp: f64 = 0; + + const current_index = left.freqamp.current_index(); + + const clist_left = left.freqamp.freqamps[current_index]; + + for (clist_left.lst.items) |freqamp| { + amp += freqamp.r_amp * singleSineTick(&settings, freqamp.freq, tick); + } + + sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp))); + try stdout.writeInt(i24, sample, Endian.little); + + amp = 0; + + const clist_right = right.freqamp.freqamps[current_index]; + + for (clist_right.lst.items) |freqamp| { + amp += freqamp.r_amp * singleSineTick(&settings, freqamp.freq, tick); + } + + sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp))); + try stdout.writeInt(i24, sample, Endian.little); tick += 1; diff --git a/zigsonnum/soundnode.zig b/zigsonnum/soundnode.zig index fb05a95..8917ee5 100644 --- a/zigsonnum/soundnode.zig +++ b/zigsonnum/soundnode.zig @@ -27,16 +27,14 @@ pub const SoundNode = struct { wire_in: ArrayList(*SoundNode), activities: ArrayList(*Activity), - freqmap: AutoHashMap(u16, f16), freqamp: FreqAmpBuffer, - pub fn init(allocator: Allocator, name: []const u8) SoundNode { + pub fn init(allocator: Allocator, name: []const u8) !SoundNode { const air_in = ArrayList(*SoundNode).init(allocator); const wire_in = ArrayList(*SoundNode).init(allocator); const activities = ArrayList(*Activity).init(allocator); - const freqmap = AutoHashMap(u16, f16).init(allocator); //REDO THIS TO INCORPORATE TICKS - const freqamp = FreqAmpBuffer.init(allocator); + const freqamp = try FreqAmpBuffer.init(allocator); return .{ .allocator = allocator, @@ -44,7 +42,6 @@ pub const SoundNode = struct { .air_in = air_in, .wire_in = wire_in, .activities = activities, - .freqmap = freqmap, .freqamp = freqamp, }; @@ -55,85 +52,8 @@ pub const SoundNode = struct { self.air_in.deinit(); self.wire_in.deinit(); self.activities.deinit(); - self.freqmap.deinit(); + self.freqamp.deinit(); } -}; - -pub fn singleSineTick(st: *SoundSettings, freq: f16, t: u64) f64 { - const ft: f64 = @floatFromInt(t); - return math.sin(st.sine_multiplier * @as(f64, freq) * ft); -} - -pub fn nmain() !void { - - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - const allocator = gpa.allocator(); - - var sn1: SoundNode = SoundNode.init(allocator, "left_sink"); - defer sn1.deinit(); - - var sn2: SoundNode = SoundNode.init(allocator, "right_sink"); - defer sn2.deinit(); - - sn2.location.x = -5; - sn1.location.x = 4; - try sn1.air_in.append(&sn2); - - var st = SoundSettings{}; - st.printSettings(); - - const duration_in_sec: u32 = 5*60; - - prnt("start"); - - const stdout_file = std.io.getStdOut().writer(); - var bw = std.io.bufferedWriter(stdout_file); - const stdout = bw.writer(); - - //WRITING WAV HEADER - try stdout.writeAll("RIFF"); - - try stdout.writeInt( - u32, - 36 + ((duration_in_sec * st.sample_rate) * 2 * st.sample_width), - Endian.little, - ); - - try stdout.writeAll("WAVE"); - try stdout.writeAll("fmt "); - - try stdout.writeInt(u32, 16, Endian.little); - try stdout.writeInt(u16, 1, Endian.little); - try stdout.writeInt(u16, 2, Endian.little); - try stdout.writeInt(u32, st.sample_rate, Endian.little); - - const block_align: u16 = @intCast(2 * st.sample_width); - - try stdout.writeInt(u32, @as(u32, block_align) * st.sample_rate, Endian.little); - try stdout.writeInt(u16, block_align, Endian.little); - try stdout.writeInt(u16, st.bit_depth, Endian.little); - - try stdout.writeAll("data"); - try stdout.writeInt( - u32, - (duration_in_sec * st.sample_rate) * 2 * st.sample_width, - Endian.little, - ); - - var sample: i24 = 0.0; - - var amp: f64 = undefined; - - for (0 .. st.sample_rate * duration_in_sec) |t| { - amp = singleSineTick(&st, 440, t); - - sample = @intFromFloat(amp * @as(f64, @floatFromInt(st.max_amp))); - try stdout.writeInt(i24, sample, Endian.little); - try stdout.writeInt(i24, sample, Endian.little); - } - prnt("done"); - - try bw.flush(); -} +}; \ No newline at end of file