From a9530cdb87a0bcd7e4c5531b21adeb6d7f9ed180 Mon Sep 17 00:00:00 2001 From: aprilnightk Date: Thu, 11 Sep 2025 20:07:27 +0300 Subject: [PATCH] simplified version, much faster due to weird fix, no more additive --- pysonnum/instruction.py | 11 +-- snm.py | 1 + zigsonnum/activity.zig | 123 +++++------------------- zigsonnum/freqamp.zig | 206 +++++----------------------------------- zigsonnum/settings.zig | 1 + zigsonnum/sonnum.zig | 42 ++++---- zigsonnum/soundnode.zig | 7 ++ zigsonnum/utility.zig | 1 + 8 files changed, 79 insertions(+), 313 deletions(-) diff --git a/pysonnum/instruction.py b/pysonnum/instruction.py index 55f1279..0786045 100644 --- a/pysonnum/instruction.py +++ b/pysonnum/instruction.py @@ -8,11 +8,8 @@ OPCODES = { 'air': 2, 'endtick': 3, 'relay': 4, - 'accumulate': 5, - 'reset': 6, - 'setfreq': 7, - 'setpos': 8, - + 'setpos': 5, + 'sine': 6, } def i_create_simple(c, s, name): @@ -63,10 +60,10 @@ def i_setpos(c, s, start_tick, end_tick, node_name, x, y, z): node = s.node_by_name(node_name) c.add_activity('setpos', start_tick, end_tick, node, None, [x, y, z]) -def i_setfreq(c, s, start_tick, end_tick, node_name, freq, r_amp): +def i_sine(c, s, start_tick, end_tick, node_name, freq, r_amp): node = s.node_by_name(node_name) - c.add_activity('setfreq', start_tick, end_tick, node, None, [freq, r_amp]) + c.add_activity('sine', start_tick, end_tick, node, None, [freq, r_amp]) def i_triangle(c, s, start_tick, end_tick, node_name, harmonics_q, freq, r_amp): diff --git a/snm.py b/snm.py index 3d9b72f..65b2336 100644 --- a/snm.py +++ b/snm.py @@ -44,6 +44,7 @@ def run(): else: C.compile_to_smnb(snm, 'source.snmb') os.system(f'zig run zigsonnum/sonnum.zig -lc -OReleaseFast > {fn}.wav') + #os.system(f'zig run zigsonnum/sonnum.zig -lc > {fn}.wav') if __name__ == '__main__': run() \ No newline at end of file diff --git a/zigsonnum/activity.zig b/zigsonnum/activity.zig index 6c60fd8..e3724a3 100644 --- a/zigsonnum/activity.zig +++ b/zigsonnum/activity.zig @@ -1,8 +1,12 @@ const std = @import("std"); +const math = std.math; const print = std.debug.print; const Allocator = std.mem.Allocator; const SoundNode = @import("soundnode.zig").SoundNode; +const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer; const FreqAmpList = @import("freqamp.zig").FreqAmpList; +const utility = @import("utility.zig"); + pub const Activity = struct { @@ -29,60 +33,34 @@ pub const Activity = struct { pub fn do(self: *Activity) !void { switch (self.opcode) { - 4 => { try self.relay(); }, - 5 => { try self.accumulate(); }, - 6 => { try self.reset(); }, - 7 => { try self.setfreq(); }, - 8 => { self.setpos(); }, + 4 => { self.relay(); }, + 5 => { self.setpos(); }, + 6 => { self.sine(); }, else => {}, } } - pub fn reset(self: *Activity) !void { - try self.soundnode.fab.reset(); + pub fn sine(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const freq = self.operands[0]; + const r_amp = self.operands[1]; + const phase = self.operands[2]; + + const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau); + self.soundnode.fab.add_r_amp(amp); + } - pub fn setfreq(self: *Activity) !void { - try self.soundnode.fab.setfreq(self.operands[0], self.operands[1], self.operands[2]); - } - - pub fn slide_freq(self: *Activity) !void { + pub fn relay(self: *Activity) void { - // NEEDS REDO - try self.soundnode.fab.reset(); - - const init_freq: f64 = self.operands[0]; - const final_freq: f64 = self.operands[1]; - - const timediff: u32 = self.end_tick - self.start_tick; - const elapsed: u32 = self.soundnode.fab.current_tick - self.start_tick; - const freqdiff: f128 = ((@as(f128, final_freq - init_freq))) / @as(f128, @floatFromInt(timediff)); - - const res_freq: f64 = init_freq + @as(f64, @floatCast(freqdiff * @as(f128, @floatFromInt(elapsed)) )); - - try self.soundnode.fab.setfreq(res_freq, self.operands[2], 0); - - if (self.soundnode.fab.current_tick % 1000 == 0) { - print("TIMEDIFF {d}\n", .{timediff}); - print("FREQDIFF {d}\n", .{@as(f64, @floatCast(freqdiff))}); - print("RESFREQ {d}\n", .{res_freq}); - } - } - - pub fn relay(self: *Activity) !void { - - try self.soundnode.fab.reset(); const current_tick: u32 = self.soundnode.fab.current_tick; - const current_index: u32 = self.soundnode.fab.current_index; - + for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { - const current_fal = wired_sn.fab.fal_array[current_index]; - - for (current_fal.arraylist.items) |fa| { - try self.soundnode.fab.add_fa(fa); - } - + const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick); + self.soundnode.fab.add_r_amp(relayed_r_amp); _ = i; } @@ -95,62 +73,13 @@ pub const Activity = struct { const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); if (tck > 0) { + sample_tick = @intFromFloat( @floor(tck) ); - - const sample_index = aired_sn.fab.index_by_tick(sample_tick); const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); - const sample_fal = aired_sn.fab.fal_array[sample_index]; - - for (sample_fal.arraylist.items) |fa| { - try self.soundnode.fab.addfreq(fa.freq, fa.r_amp * attenuation, fa.phase); - } - - } - - _ = i; - - } - - } - - pub fn accumulate(self: *Activity) !void { - - try self.soundnode.fab.reset(); - const current_tick: u32 = self.soundnode.fab.current_tick; - const current_index: u32 = self.soundnode.fab.current_index; - - for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { - - const current_fal = wired_sn.fab.fal_array[current_index]; - - for (current_fal.arraylist.items) |fa| { - try self.soundnode.fab.addfreq(fa.freq, fa.r_amp, fa.phase); - } - - _ = i; - - } - - for (self.soundnode.air_in.items, 0..) |aired_sn, i| { - - const dist: f64 = self.soundnode.distance(aired_sn); - - var sample_tick: u32 = 0; - const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); - - if (tck > 0) { - sample_tick = @intFromFloat( @floor(tck) ); - - const sample_index = aired_sn.fab.index_by_tick(sample_tick); - const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); - - const sample_fal = aired_sn.fab.fal_array[sample_index]; - - for (sample_fal.arraylist.items) |fa| { - try self.soundnode.fab.addfreq(fa.freq, fa.r_amp * attenuation, fa.phase); - } - + const relayed_r_amp = aired_sn.fab.get_r_amp(sample_tick) * attenuation; + self.soundnode.fab.add_r_amp(relayed_r_amp); + } _ = i; diff --git a/zigsonnum/freqamp.zig b/zigsonnum/freqamp.zig index ee6a5f7..f2e8b50 100644 --- a/zigsonnum/freqamp.zig +++ b/zigsonnum/freqamp.zig @@ -4,118 +4,6 @@ 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 { @@ -125,23 +13,14 @@ pub const FreqAmpBuffer = struct { buffer_ticks: u32 = buffer_ticks_default, current_tick: u32, current_index: u32, - fal_array: [buffer_ticks_default]*FreqAmpList, + fal_array: [buffer_ticks_default]f64 = std.mem.zeroes([buffer_ticks_default]f64), 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, }; } @@ -154,35 +33,19 @@ pub const FreqAmpBuffer = struct { 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] = 0; - 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", .{}); @@ -192,60 +55,37 @@ pub const FreqAmpBuffer = struct { 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.fal_array[prev_index]}); print("{d}: {*}\n", .{self.current_tick, self.fal_array[cur_index]}); - self.fal_array[cur_index].prnt(); + print("{d}\n", .{self.fal_array[cur_index]}); print("{d}: {*}\n", .{self.current_tick+%1, self.fal_array[next_index]}); - self.fal_array[next_index].prnt(); + print("{d}\n", .{self.fal_array[next_index]}); } - pub fn reset(self: *FreqAmpBuffer) !void { + + pub fn add_r_amp(self: *FreqAmpBuffer, r_amp: f64) void { + + self.fal_array[self.current_index] += r_amp; - 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; + if (self.fal_array[self.current_index] > 1) { + self.fal_array[self.current_index] = 1; + } else if (self.fal_array[self.current_index] < -1) { + self.fal_array[self.current_index] = -1; } - } - 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 { + pub fn get_current_r_amp(self: *FreqAmpBuffer) f64 { - return self.fal_array[self.index_by_tick(tick)]; + return self.fal_array[self.current_index]; + + } + pub fn get_r_amp(self: *FreqAmpBuffer, tick: u32) f64 { + + const ind: u32 = self.index_by_tick(tick); + return self.fal_array[ind]; + } }; diff --git a/zigsonnum/settings.zig b/zigsonnum/settings.zig index f165c10..30eab99 100644 --- a/zigsonnum/settings.zig +++ b/zigsonnum/settings.zig @@ -14,6 +14,7 @@ pub const SoundSettings = struct { speed_of_sound: f32 = 343.0 / @as(f32, default_sample_rate), bit_depth: u8 = default_bit_depth, max_amp: i64 = math.pow(i64, 2, default_bit_depth-1) - 1, + max_amp_multiplier: f64 = @as(f64, @floatFromInt(math.pow(i64, 2, default_bit_depth-1) - 1)), min_amp: i64 = - math.pow(i64, 2, default_bit_depth-1), sample_width: u8 = @intFromFloat(@as(f32, default_bit_depth) / 8.0), sine_multiplier: f64 = utility.tau / default_sample_rate, diff --git a/zigsonnum/sonnum.zig b/zigsonnum/sonnum.zig index 3354758..ce91a33 100644 --- a/zigsonnum/sonnum.zig +++ b/zigsonnum/sonnum.zig @@ -21,7 +21,7 @@ pub fn main() !void { const allocator = std.heap.c_allocator; // Initializing sound settings - var settings: SoundSettings = SoundSettings{}; + const settings: SoundSettings = SoundSettings{}; // Creating a list of soundnodes var soundnodes = ArrayList(*SoundNode).init(allocator); @@ -85,7 +85,6 @@ pub fn main() !void { // Setting up tick iteration var tick: u32 = start_tick; - var amp: f64 = 0; var sample: i24 = 0.0; var left: *SoundNode = undefined; var right: *SoundNode = undefined; @@ -94,6 +93,10 @@ pub fn main() !void { while (tick < end_tick) { + if (tick%44100 == 0) { + print("T {d} ", .{tick}); + } + if (tick == nextopcodetick) { while (cursor < buf.len) { @@ -211,6 +214,7 @@ pub fn main() !void { for (soundnodes.items[2..], 0..) |soundnode, i| { var toremove = ArrayList(usize).init(allocator); + defer toremove.deinit(); for (soundnode.activities.items, 0..) |activity, j| { @@ -238,6 +242,7 @@ pub fn main() !void { for (soundnodes.items[0..2], 0..) |soundnode, i| { var toremove = ArrayList(usize).init(allocator); + defer toremove.deinit(); for (soundnode.activities.items, 0..) |activity, j| { @@ -257,39 +262,24 @@ pub fn main() !void { _ = soundnode.activities.swapRemove(activity_ind); } - soundnode.fab.increment_tick(); _ = i; } - - //Calculating and writing output amps - - amp = 0; + //Calculating and writing output amps + left = soundnodes.items[0]; right = soundnodes.items[1]; - const current_index = left.fab.current_index; - - const current_fal_left = left.fab.fal_array[current_index]; - - for (current_fal_left.arraylist.items) |fa| { - amp += fa.r_amp * singleSineTick(&settings, fa.freq, tick, fa.phase); - } + const current_r_amp_left = left.fab.get_current_r_amp(); + sample = @intFromFloat(current_r_amp_left * settings.max_amp_multiplier); + try stdout.writeInt(i24, sample, Endian.little); - sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp))); - try stdout.writeInt(i24, sample, Endian.little); - - amp = 0; - - const current_fal_right = right.fab.fal_array[current_index]; - - for (current_fal_right.arraylist.items) |fa| { - amp += fa.r_amp * singleSineTick(&settings, fa.freq, tick, fa.phase); - } - - sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp))); + const current_r_amp_right = right.fab.get_current_r_amp(); + sample = @intFromFloat(current_r_amp_right * settings.max_amp_multiplier); try stdout.writeInt(i24, sample, Endian.little); + left.fab.increment_tick(); + right.fab.increment_tick(); tick += 1; } diff --git a/zigsonnum/soundnode.zig b/zigsonnum/soundnode.zig index 3a45d6f..c15c749 100644 --- a/zigsonnum/soundnode.zig +++ b/zigsonnum/soundnode.zig @@ -6,6 +6,7 @@ const Endian = std.builtin.Endian; const ArrayList = std.ArrayList; const AutoHashMap = std.AutoHashMap; const Allocator = std.mem.Allocator; +const StringHashMap = std.StringHashMap; const pnt = @import("point.zig"); const Pnt = pnt.Pnt; @@ -27,6 +28,7 @@ pub const SoundNode = struct { air_in: ArrayList(*SoundNode), wire_in: ArrayList(*SoundNode), activities: ArrayList(*Activity), + props: StringHashMap(f64), fab: FreqAmpBuffer, @@ -36,6 +38,7 @@ pub const SoundNode = struct { const wire_in = ArrayList(*SoundNode).init(allocator); const activities = ArrayList(*Activity).init(allocator); const fab = try FreqAmpBuffer.init(allocator); + const props = StringHashMap(f64).init(allocator); const sn = try allocator.create(SoundNode); @@ -46,6 +49,7 @@ pub const SoundNode = struct { .wire_in = wire_in, .activities = activities, .fab = fab, + .props = props, }; return sn; @@ -58,6 +62,7 @@ pub const SoundNode = struct { const wire_in = ArrayList(*SoundNode).init(allocator); const activities = ArrayList(*Activity).init(allocator); const fab = try FreqAmpBuffer.init(allocator); + const props = StringHashMap(f64).init(allocator); return .{ .allocator = allocator, @@ -66,6 +71,7 @@ pub const SoundNode = struct { .wire_in = wire_in, .activities = activities, .fab = fab, + .props = props, }; } @@ -76,6 +82,7 @@ pub const SoundNode = struct { self.wire_in.deinit(); self.activities.deinit(); self.fab.deinit(); + self.props.deinit(); } diff --git a/zigsonnum/utility.zig b/zigsonnum/utility.zig index eb6c113..68a3c96 100644 --- a/zigsonnum/utility.zig +++ b/zigsonnum/utility.zig @@ -2,6 +2,7 @@ const std = @import("std"); const print = std.debug.print; pub const tau: f64 = 2 * 3.1415926535897932384626433832795028841971; +pub const corrected_tau: f64 = tau / 44100; pub fn prnt(s: []const u8) void { print("{s}\n", .{s});