diff --git a/mysynths/sintest.py b/mysynths/sintest.py new file mode 100644 index 0000000..12b8156 --- /dev/null +++ b/mysynths/sintest.py @@ -0,0 +1,9 @@ +s.setup(s.sec(60)) + +n = s.node() +n.setbasefreq(0, s.note("D4")) + +n.setgain(0, 0.09) +n.sine(0, s.sec(10)) + +s.wire(n, s.left) \ No newline at end of file diff --git a/pysonnum/activity.py b/pysonnum/activity.py index 3ab67e1..d303374 100644 --- a/pysonnum/activity.py +++ b/pysonnum/activity.py @@ -3,14 +3,13 @@ import struct OPCODES = { 'create': 0, - 'wire': 1, - 'air': 2, + 'pin': 1, 'endtick': 3, 'relay': 4, 'setpos': 5, 'setbasefreq': 6, 'setgain': 7, - 'setphase': 8, + 'setbasephase': 8, 'sine': 9, 'triangle': 10, 'square': 11, diff --git a/pysonnum/compiler.py b/pysonnum/compiler.py index bdbfe65..c3051a9 100644 --- a/pysonnum/compiler.py +++ b/pysonnum/compiler.py @@ -131,7 +131,7 @@ class SonnumCompiler: to_delete = [] for activity in self.activities: - if activity.name in ('wire','air'): + if activity.name in ('wire','air','pin'): new.append(activity) to_delete.append(activity) diff --git a/pysonnum/sonnum.py b/pysonnum/sonnum.py index a01c7f5..5168413 100644 --- a/pysonnum/sonnum.py +++ b/pysonnum/sonnum.py @@ -79,7 +79,7 @@ class Sonnum: for src_node in src_nodes: for trg_node in trg_nodes: - self.act('wire', 0, 0, src_node, trg_node, []) + self.act('pin', 0, 0, src_node, trg_node, [0, 0]) def air(self, src_nodes, trg_nodes): @@ -91,4 +91,16 @@ class Sonnum: for src_node in src_nodes: for trg_node in trg_nodes: - self.act('air', 0, 0, src_node, trg_node, []) \ No newline at end of file + self.act('pin', 0, 0, src_node, trg_node, [0, 1]) + + def pin(self, src_nodes, trg_nodes, src_pin, trg_pin): + + if not isinstance(src_nodes, list): + src_nodes = [src_nodes] + + if not isinstance(trg_nodes, list): + trg_nodes = [trg_nodes] + + for src_node in src_nodes: + for trg_node in trg_nodes: + self.act('pin', 0, 0, src_node, trg_node, [src_pin, trg_pin]) \ No newline at end of file diff --git a/zigsonnum/activity.bak.zig b/zigsonnum/activity.bak.zig new file mode 100644 index 0000000..2bc368f --- /dev/null +++ b/zigsonnum/activity.bak.zig @@ -0,0 +1,593 @@ +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 { + + start_tick: u32, + end_tick: u32, + opcode: u16, + soundnode: *SoundNode, + operands: [6]f64 = std.mem.zeroes([6]f64), + + pub fn create(allocator: Allocator, start_tick: u32, end_tick: u32, opcode: u16, soundnode: *SoundNode, operands: [6]f64) !*Activity { + + const a = try allocator.create(Activity); + a.* = .{ + .start_tick = start_tick, + .end_tick = end_tick, + .opcode = opcode, + .soundnode = soundnode, + .operands = operands, + }; + + return a; + + } + + pub fn do(self: *Activity) !void { + switch (self.opcode) { + 4 => { self.relay(); }, + 5 => { self.setpos(); }, + 6 => { self.setbasefreq(); }, + 7 => { self.setgain(); }, + 8 => { self.setphase(); }, + 9 => { self.sine(); }, + 10 => { self.triangle(); }, + 11 => { self.square(); }, + 12 => { self.sawtooth(); }, + 13 => { self.setskew(); }, + 14 => { self.skewsine(); }, + 15 => { try self.slidebasefreq(); }, + 16 => { try self.slidegain(); }, + 17 => { try self.slidephase(); }, + 18 => { try self.slideskew(); }, + 19 => { self.slidepos(); }, + 20 => { self.pulse(); }, + 21 => { try self.fmsetup(); }, + 22 => { try self.fm(); }, + 23 => { try self.am(); }, + 24 => { try self.mute(); }, + 25 => { self.whitenoise(); }, + 26 => { try self.setadsrgain(); }, + 27 => { try self.setadsrsustain(); }, + 28 => { try self.adsr(); }, + else => {}, + } + } + + + pub fn relay_imprecise(self: *Activity) void { + + const current_tick: u32 = self.soundnode.fab.current_tick; + + for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { + + const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick); + self.soundnode.fab.add_r_amp(relayed_r_amp); + _ = 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 attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const relayed_r_amp = aired_sn.fab.get_r_amp(sample_tick) * attenuation; + self.soundnode.fab.add_r_amp(relayed_r_amp); + + } + + _ = i; + + } + + } + + pub fn relay(self: *Activity) void { + + self.soundnode.fab.add_r_amp(self.soundnode.in_wire); + self.soundnode.fab.add_r_amp(self.soundnode.in_air); + + self.soundnode.r_amp += self.soundnode.in_wire; + self.soundnode.r_amp += self.soundnode.in_air; + + } + + pub fn setbasefreq(self: *Activity) void { + self.soundnode.basefreq = self.operands[0]; + } + + pub fn setgain(self: *Activity) !void { + self.soundnode.gain = self.operands[0]; + } + + pub fn setbasephase(self: *Activity) !void { + self.soundnode.basephase = self.operands[0]; + } + + pub fn setpos(self: *Activity) void { + self.soundnode.x = @as(f32, @floatCast(self.operands[0])); + self.soundnode.y = @as(f32, @floatCast(self.operands[1])); + self.soundnode.z = @as(f32, @floatCast(self.operands[2])); + + } + + pub fn sine(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const freq = self.soundnode.g("basefreq"); + const phase = self.soundnode.g("phase"); + const gainmult = self.operands[0]; + var r_amp = self.soundnode.g("gain"); + + if (gainmult > 0) { + r_amp *= gainmult; + } + + + const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau); + self.soundnode.fab.add_r_amp(amp); + + } + + pub fn triangle(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const freq = self.soundnode.g("basefreq"); + const phase = self.soundnode.g("phase"); + const gainmult = self.operands[0]; + var r_amp = self.soundnode.g("gain"); + + if (gainmult > 0) { + r_amp *= gainmult; + } + + const period = 44100 / freq; + const tp = (current_tick - (period * phase)) / period; + + const amp = r_amp * (@abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1); + self.soundnode.fab.add_r_amp(amp); + + } + + pub fn square(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const freq = self.soundnode.g("basefreq"); + const phase = self.soundnode.g("phase"); + const gainmult = self.operands[0]; + var r_amp = self.soundnode.g("gain"); + + if (gainmult > 0) { + r_amp *= gainmult; + } + + const sin = math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau); + + if (sin > 0) { + self.soundnode.fab.add_r_amp(r_amp); + } else { + self.soundnode.fab.add_r_amp(-r_amp); + } + + } + + pub fn sawtooth(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const freq = self.soundnode.g("basefreq"); + const phase = self.soundnode.g("phase"); + const gainmult = self.operands[0]; + var r_amp = self.soundnode.g("gain"); + + if (gainmult > 0) { + r_amp *= gainmult; + } + + const period = 44100 / freq; + const tp = (current_tick - (period * phase)) / period; + + const amp = r_amp * (2 * (tp - @floor(0.5+tp))); + self.soundnode.fab.add_r_amp(amp); + + } + + pub fn setskew(self: *Activity) !void { + try self.soundnode.s("skew", self.operands[0]); + } + + pub fn skewsine(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const freq = self.soundnode.g("basefreq"); + const phase = self.soundnode.g("phase"); + const gainmult = self.operands[0]; + var r_amp = self.soundnode.g("gain"); + + if (gainmult > 0) { + r_amp *= gainmult; + } + const skew = self.soundnode.g("skew"); + + if (skew == 0) { + const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau); + self.soundnode.fab.add_r_amp(amp); + } else if (skew > 0) { + const m = (utility.corrected_tau * freq * current_tick) - (phase * utility.tau); + const sincos = skew * math.sin(m) / (1 - skew*math.cos(m)); + const amp = r_amp * ((1/skew) * math.atan(sincos)); + self.soundnode.fab.add_r_amp(amp); + } else if (skew < 0) { + const m = (utility.corrected_tau * freq * current_tick); + const sincos = skew * math.cos(m) / (1 + skew*math.sin(m)); + const amp = r_amp * ((1/skew) * math.atan(sincos)); + self.soundnode.fab.add_r_amp(amp); + } + + } + + pub fn slidebasefreq(self: *Activity) !void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const start_tick: f64 = @floatFromInt(self.start_tick); + const end_tick: f64 = @floatFromInt(self.end_tick); + + const startfreq = self.operands[0]; + const endfreq = self.operands[1]; + + const x = (current_tick * (current_tick / 2)) - (start_tick*current_tick); + const xx = ((endfreq - startfreq) / (end_tick - start_tick)) * x; + const freq = ((startfreq * current_tick) + xx) / current_tick; + + try self.soundnode.s("basefreq", freq); + + } + + pub fn slidebasefreq_iterative(self: *Activity) !void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const start_tick: f64 = @floatFromInt(self.start_tick); + const end_tick: f64 = @floatFromInt(self.end_tick); + + const startfreq = self.operands[0]; + const endfreq = self.operands[1]; + + const instfreq = utility.interpolate(current_tick, start_tick, end_tick, startfreq, endfreq); + const c = current_tick / 44100; + + const prevphase = self.soundnode.g("phase"); + const prevfreq = self.soundnode.g("basefreq"); + + const pp = prevphase + c*(instfreq - prevfreq) + @floor(c * prevfreq - prevphase); + const newphase = pp - @floor(pp); + + try self.soundnode.s("phase", newphase); + try self.soundnode.s("basefreq", instfreq); + + } + + pub fn slidegain(self: *Activity) !void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const start_tick: f64 = @floatFromInt(self.start_tick); + const end_tick: f64 = @floatFromInt(self.end_tick); + + const startgain = self.operands[0]; + const endgain = self.operands[1]; + + const gain = utility.interpolate(current_tick, start_tick, end_tick, startgain, endgain); + try self.soundnode.s("gain", gain); + + } + + pub fn slidephase(self: *Activity) !void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const start_tick: f64 = @floatFromInt(self.start_tick); + const end_tick: f64 = @floatFromInt(self.end_tick); + + const startphase = self.operands[0]; + const endphase = self.operands[1]; + + const phase = utility.interpolate(current_tick, start_tick, end_tick, startphase, endphase); + try self.soundnode.s("phase", phase); + + } + + pub fn slideskew(self: *Activity) !void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const start_tick: f64 = @floatFromInt(self.start_tick); + const end_tick: f64 = @floatFromInt(self.end_tick); + + const startskew = self.operands[0]; + const endskew = self.operands[1]; + + const skew = utility.interpolate(current_tick, start_tick, end_tick, startskew, endskew); + try self.soundnode.s("skew", skew); + + } + + pub fn slidepos(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const start_tick: f64 = @floatFromInt(self.start_tick); + const end_tick: f64 = @floatFromInt(self.end_tick); + + const start_x = self.operands[0]; + const start_y = self.operands[1]; + const start_z = self.operands[2]; + const end_x = self.operands[3]; + const end_y = self.operands[4]; + const end_z = self.operands[5]; + + const x = utility.interpolate(current_tick, start_tick, end_tick, start_x, end_x); + const y = utility.interpolate(current_tick, start_tick, end_tick, start_y, end_y); + const z = utility.interpolate(current_tick, start_tick, end_tick, start_z, end_z); + + self.soundnode.x = @as(f32, @floatCast(x)); + self.soundnode.y = @as(f32, @floatCast(y)); + self.soundnode.z = @as(f32, @floatCast(z)); + + } + + pub fn pulse(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const freq = self.soundnode.g("basefreq"); + const phase = self.soundnode.g("phase"); + const gainmult = self.operands[0]; + var r_amp = self.soundnode.g("gain"); + + if (gainmult > 0) { + r_amp *= gainmult; + } + + const period = 44100 / freq; + const tp = current_tick / period; + const tp_detract = (current_tick - (period * phase)) / period; + + const amp =2 * (tp - @floor(0.5+tp)); + const amp_detract = 2 * (tp_detract - @floor(0.5+tp_detract)); + + const final_amp = r_amp * (amp - amp_detract); + + self.soundnode.fab.add_r_amp(final_amp); + + } + + pub fn fmsetup(self: *Activity) !void { + try self.soundnode.s("fmbasefreq", self.operands[0]); + try self.soundnode.s("instfreq", self.operands[0]); + try self.soundnode.s("fmq", self.operands[1]); + } + + + pub fn fm(self: *Activity) !void { + + const current_tick: u32 = self.soundnode.fab.current_tick; + const fcurrent_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + var fprev_tick: f64 = 0; + + if (fcurrent_tick > 0) { + fprev_tick = @floatFromInt(current_tick - 1); + } + + const fmq = self.soundnode.g("fmq"); + const fmbasefreq = self.soundnode.g("fmbasefreq"); + + const prevphase = self.soundnode.g("phase"); + const prevfreq = self.soundnode.g("basefreq"); + + var srcamp: f64 = 0; + + for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { + + if (wired_sn.active == 1) { + const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick); + srcamp += relayed_r_amp; + } + _ = i; + + } + + for (self.soundnode.air_in.items, 0..) |aired_sn, i| { + + if (aired_sn.active == 1) { + + const dist: f64 = self.soundnode.distance(aired_sn); + + var b_sample_tick: u32 = 0; + var n_sample_tick: u32 = 0; + + const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); + + if (tck > 0) { + + b_sample_tick = @intFromFloat( @floor(tck) ); + n_sample_tick = b_sample_tick + 1; + + const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const b_r_amp = aired_sn.fab.get_r_amp(b_sample_tick); + const n_r_amp = aired_sn.fab.get_r_amp(n_sample_tick); + + const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); + const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; + + srcamp += relayed_r_amp; + + } + } + _ = i; + + } + + if (srcamp > 1) { + srcamp = 1; + } else if (srcamp < -1) { + srcamp = -1; + } + + const instfreq = fmbasefreq + (fmbasefreq * fmq * srcamp); + const c = fcurrent_tick / 44100; + + const pp = prevphase + c*(instfreq - prevfreq) + @floor(c * prevfreq - prevphase); + const newphase = pp - @floor(pp); + + try self.soundnode.s("phase", newphase); + try self.soundnode.s("basefreq", instfreq); + + + } + + pub fn am(self: *Activity) !void { + + const current_tick: u32 = self.soundnode.fab.current_tick; + + var srcamp: f64 = 0; + + for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { + + const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick); + srcamp += relayed_r_amp; + _ = i; + + } + + for (self.soundnode.air_in.items, 0..) |aired_sn, i| { + + const dist: f64 = self.soundnode.distance(aired_sn); + + var b_sample_tick: u32 = 0; + var n_sample_tick: u32 = 0; + + const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); + + if (tck > 0) { + + b_sample_tick = @intFromFloat( @floor(tck) ); + n_sample_tick = b_sample_tick + 1; + + const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const b_r_amp = aired_sn.fab.get_r_amp(b_sample_tick); + const n_r_amp = aired_sn.fab.get_r_amp(n_sample_tick); + + const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); + const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; + + srcamp += relayed_r_amp; + + } + + _ = i; + + } + + if (srcamp > 1) { + srcamp = 1; + } else if (srcamp < -1) { + srcamp = -1; + } + + try self.soundnode.s("gain", srcamp); + + } + + pub fn mute(self: *Activity) !void { + try self.soundnode.s("gain", 0); + } + + pub fn whitenoise(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const seed = self.operands[0]; + const gainmult = self.operands[1]; + + var r_amp = self.soundnode.g("gain"); + + if (gainmult > 0) { + r_amp *= gainmult; + } + + const w = (seed*current_tick) / math.sin(current_tick); + const rnd = (2 * (w - @floor(w))) - 1; + + const amp = r_amp * rnd; + self.soundnode.fab.add_r_amp(amp); + + } + + + pub fn setadsrgain(self: *Activity) !void { + try self.soundnode.s("adsrgain", self.operands[0]); + } + + + pub fn setadsrsustain(self: *Activity) !void { + try self.soundnode.s("adsrsustain", self.operands[0]); + } + + pub fn adsr(self: *Activity) !void { + + const real_current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const start_tick: f64 = @floatFromInt(self.start_tick); + const current_tick = real_current_tick - start_tick; + + var adsrgain = self.soundnode.g("adsrgain"); + const adsrsustain = self.soundnode.g("adsrsustain"); + + const attack_tick = self.operands[0]; + const hold_tick = self.operands[1]; + const decay_tick = self.operands[2]; + const sustain_tick = self.operands[3]; + const release_tick = self.operands[4]; + const gainmult = self.operands[5]; + + if (gainmult > 0) { + adsrgain *= gainmult; + } + + var gain: f64 = 0; + + if (current_tick <= attack_tick) { + gain = adsrgain * current_tick / attack_tick; + } else if (current_tick <= hold_tick) { + gain = adsrgain; + } else if (current_tick <= decay_tick) { + gain = ((current_tick-hold_tick)*(adsrsustain-adsrgain)/(decay_tick - hold_tick)) + adsrgain; + } else if (current_tick <= sustain_tick) { + gain = adsrsustain; + } else if (current_tick <= release_tick) { + gain = (adsrsustain * (current_tick - sustain_tick) / (sustain_tick - release_tick)) + adsrsustain; + } + + try self.soundnode.s("gain", gain); + + } + +}; \ No newline at end of file diff --git a/zigsonnum/activity.zig b/zigsonnum/activity.zig index 36546be..0fc45ff 100644 --- a/zigsonnum/activity.zig +++ b/zigsonnum/activity.zig @@ -35,29 +35,10 @@ pub const Activity = struct { switch (self.opcode) { 4 => { self.relay(); }, 5 => { self.setpos(); }, - 6 => { try self.setbasefreq(); }, - 7 => { try self.setgain(); }, - 8 => { try self.setphase(); }, + 6 => { self.setbasefreq(); }, + 7 => { self.setgain(); }, + 8 => { self.setbasephase(); }, 9 => { self.sine(); }, - 10 => { self.triangle(); }, - 11 => { self.square(); }, - 12 => { self.sawtooth(); }, - 13 => { try self.setskew(); }, - 14 => { self.skewsine(); }, - 15 => { try self.slidebasefreq(); }, - 16 => { try self.slidegain(); }, - 17 => { try self.slidephase(); }, - 18 => { try self.slideskew(); }, - 19 => { self.slidepos(); }, - 20 => { self.pulse(); }, - 21 => { try self.fmsetup(); }, - 22 => { try self.fm(); }, - 23 => { try self.am(); }, - 24 => { try self.mute(); }, - 25 => { self.whitenoise(); }, - 26 => { try self.setadsrgain(); }, - 27 => { try self.setadsrsustain(); }, - 28 => { try self.adsr(); }, else => {}, } } @@ -100,61 +81,21 @@ pub const Activity = struct { pub fn relay(self: *Activity) void { - const current_tick: u32 = self.soundnode.fab.current_tick; - - for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { - - if (wired_sn.active == 1) { - const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick); - self.soundnode.fab.add_r_amp(relayed_r_amp); - } - _ = i; - - } - - for (self.soundnode.air_in.items, 0..) |aired_sn, i| { - - if (aired_sn.active == 1) { - const dist: f64 = self.soundnode.distance(aired_sn); + self.soundnode.add_r_amp(self.soundnode.in_wire); + self.soundnode.add_r_amp(self.soundnode.in_air); - var b_sample_tick: u32 = 0; - var n_sample_tick: u32 = 0; - - const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); - - if (tck > 0) { - - b_sample_tick = @intFromFloat( @floor(tck) ); - n_sample_tick = b_sample_tick + 1; - - const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); - - const b_r_amp = aired_sn.fab.get_r_amp(b_sample_tick); - const n_r_amp = aired_sn.fab.get_r_amp(n_sample_tick); - - const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); - const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; - - self.soundnode.fab.add_r_amp(relayed_r_amp); - - } - } - _ = i; - - } - } - pub fn setbasefreq(self: *Activity) !void { - try self.soundnode.s("basefreq", self.operands[0]); + pub fn setbasefreq(self: *Activity) void { + self.soundnode.basefreq = self.operands[0]; } - pub fn setgain(self: *Activity) !void { - try self.soundnode.s("gain", self.operands[0]); + pub fn setgain(self: *Activity) void { + self.soundnode.gain = self.operands[0]; } - pub fn setphase(self: *Activity) !void { - try self.soundnode.s("phase", self.operands[0]); + pub fn setbasephase(self: *Activity) void { + self.soundnode.basephase = self.operands[0]; } pub fn setpos(self: *Activity) void { @@ -168,463 +109,16 @@ pub const Activity = struct { const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - const freq = self.soundnode.g("basefreq"); - const phase = self.soundnode.g("phase"); const gainmult = self.operands[0]; - var r_amp = self.soundnode.g("gain"); + + var gain = self.soundnode.gain; if (gainmult > 0) { - r_amp *= gainmult; - } - - - const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau); - self.soundnode.fab.add_r_amp(amp); - - } - - pub fn triangle(self: *Activity) void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - - const freq = self.soundnode.g("basefreq"); - const phase = self.soundnode.g("phase"); - const gainmult = self.operands[0]; - var r_amp = self.soundnode.g("gain"); - - if (gainmult > 0) { - r_amp *= gainmult; - } - - const period = 44100 / freq; - const tp = (current_tick - (period * phase)) / period; - - const amp = r_amp * (@abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1); - self.soundnode.fab.add_r_amp(amp); - - } - - pub fn square(self: *Activity) void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - - const freq = self.soundnode.g("basefreq"); - const phase = self.soundnode.g("phase"); - const gainmult = self.operands[0]; - var r_amp = self.soundnode.g("gain"); - - if (gainmult > 0) { - r_amp *= gainmult; - } - - const sin = math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau); - - if (sin > 0) { - self.soundnode.fab.add_r_amp(r_amp); - } else { - self.soundnode.fab.add_r_amp(-r_amp); - } - - } - - pub fn sawtooth(self: *Activity) void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - - const freq = self.soundnode.g("basefreq"); - const phase = self.soundnode.g("phase"); - const gainmult = self.operands[0]; - var r_amp = self.soundnode.g("gain"); - - if (gainmult > 0) { - r_amp *= gainmult; - } - - const period = 44100 / freq; - const tp = (current_tick - (period * phase)) / period; - - const amp = r_amp * (2 * (tp - @floor(0.5+tp))); - self.soundnode.fab.add_r_amp(amp); - - } - - pub fn setskew(self: *Activity) !void { - try self.soundnode.s("skew", self.operands[0]); - } - - pub fn skewsine(self: *Activity) void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - - const freq = self.soundnode.g("basefreq"); - const phase = self.soundnode.g("phase"); - const gainmult = self.operands[0]; - var r_amp = self.soundnode.g("gain"); - - if (gainmult > 0) { - r_amp *= gainmult; - } - const skew = self.soundnode.g("skew"); - - if (skew == 0) { - const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau); - self.soundnode.fab.add_r_amp(amp); - } else if (skew > 0) { - const m = (utility.corrected_tau * freq * current_tick) - (phase * utility.tau); - const sincos = skew * math.sin(m) / (1 - skew*math.cos(m)); - const amp = r_amp * ((1/skew) * math.atan(sincos)); - self.soundnode.fab.add_r_amp(amp); - } else if (skew < 0) { - const m = (utility.corrected_tau * freq * current_tick); - const sincos = skew * math.cos(m) / (1 + skew*math.sin(m)); - const amp = r_amp * ((1/skew) * math.atan(sincos)); - self.soundnode.fab.add_r_amp(amp); - } - - } - - pub fn slidebasefreq(self: *Activity) !void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - const start_tick: f64 = @floatFromInt(self.start_tick); - const end_tick: f64 = @floatFromInt(self.end_tick); - - const startfreq = self.operands[0]; - const endfreq = self.operands[1]; - - const x = (current_tick * (current_tick / 2)) - (start_tick*current_tick); - const xx = ((endfreq - startfreq) / (end_tick - start_tick)) * x; - const freq = ((startfreq * current_tick) + xx) / current_tick; - - try self.soundnode.s("basefreq", freq); - - } - - pub fn slidebasefreq_iterative(self: *Activity) !void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - const start_tick: f64 = @floatFromInt(self.start_tick); - const end_tick: f64 = @floatFromInt(self.end_tick); - - const startfreq = self.operands[0]; - const endfreq = self.operands[1]; - - const instfreq = utility.interpolate(current_tick, start_tick, end_tick, startfreq, endfreq); - const c = current_tick / 44100; - - const prevphase = self.soundnode.g("phase"); - const prevfreq = self.soundnode.g("basefreq"); - - const pp = prevphase + c*(instfreq - prevfreq) + @floor(c * prevfreq - prevphase); - const newphase = pp - @floor(pp); - - try self.soundnode.s("phase", newphase); - try self.soundnode.s("basefreq", instfreq); - - } - - pub fn slidegain(self: *Activity) !void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - const start_tick: f64 = @floatFromInt(self.start_tick); - const end_tick: f64 = @floatFromInt(self.end_tick); - - const startgain = self.operands[0]; - const endgain = self.operands[1]; - - const gain = utility.interpolate(current_tick, start_tick, end_tick, startgain, endgain); - try self.soundnode.s("gain", gain); - - } - - pub fn slidephase(self: *Activity) !void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - const start_tick: f64 = @floatFromInt(self.start_tick); - const end_tick: f64 = @floatFromInt(self.end_tick); - - const startphase = self.operands[0]; - const endphase = self.operands[1]; - - const phase = utility.interpolate(current_tick, start_tick, end_tick, startphase, endphase); - try self.soundnode.s("phase", phase); - - } - - pub fn slideskew(self: *Activity) !void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - const start_tick: f64 = @floatFromInt(self.start_tick); - const end_tick: f64 = @floatFromInt(self.end_tick); - - const startskew = self.operands[0]; - const endskew = self.operands[1]; - - const skew = utility.interpolate(current_tick, start_tick, end_tick, startskew, endskew); - try self.soundnode.s("skew", skew); - - } - - pub fn slidepos(self: *Activity) void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - const start_tick: f64 = @floatFromInt(self.start_tick); - const end_tick: f64 = @floatFromInt(self.end_tick); - - const start_x = self.operands[0]; - const start_y = self.operands[1]; - const start_z = self.operands[2]; - const end_x = self.operands[3]; - const end_y = self.operands[4]; - const end_z = self.operands[5]; - - const x = utility.interpolate(current_tick, start_tick, end_tick, start_x, end_x); - const y = utility.interpolate(current_tick, start_tick, end_tick, start_y, end_y); - const z = utility.interpolate(current_tick, start_tick, end_tick, start_z, end_z); - - self.soundnode.x = @as(f32, @floatCast(x)); - self.soundnode.y = @as(f32, @floatCast(y)); - self.soundnode.z = @as(f32, @floatCast(z)); - - } - - pub fn pulse(self: *Activity) void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - - const freq = self.soundnode.g("basefreq"); - const phase = self.soundnode.g("phase"); - const gainmult = self.operands[0]; - var r_amp = self.soundnode.g("gain"); - - if (gainmult > 0) { - r_amp *= gainmult; - } - - const period = 44100 / freq; - const tp = current_tick / period; - const tp_detract = (current_tick - (period * phase)) / period; - - const amp =2 * (tp - @floor(0.5+tp)); - const amp_detract = 2 * (tp_detract - @floor(0.5+tp_detract)); - - const final_amp = r_amp * (amp - amp_detract); - - self.soundnode.fab.add_r_amp(final_amp); - - } - - pub fn fmsetup(self: *Activity) !void { - try self.soundnode.s("fmbasefreq", self.operands[0]); - try self.soundnode.s("instfreq", self.operands[0]); - try self.soundnode.s("fmq", self.operands[1]); - } - - - pub fn fm(self: *Activity) !void { - - const current_tick: u32 = self.soundnode.fab.current_tick; - const fcurrent_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - - var fprev_tick: f64 = 0; - - if (fcurrent_tick > 0) { - fprev_tick = @floatFromInt(current_tick - 1); - } - - const fmq = self.soundnode.g("fmq"); - const fmbasefreq = self.soundnode.g("fmbasefreq"); - - const prevphase = self.soundnode.g("phase"); - const prevfreq = self.soundnode.g("basefreq"); - - var srcamp: f64 = 0; - - for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { - - if (wired_sn.active == 1) { - const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick); - srcamp += relayed_r_amp; - } - _ = i; - - } - - for (self.soundnode.air_in.items, 0..) |aired_sn, i| { - - if (aired_sn.active == 1) { - - const dist: f64 = self.soundnode.distance(aired_sn); - - var b_sample_tick: u32 = 0; - var n_sample_tick: u32 = 0; - - const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); - - if (tck > 0) { - - b_sample_tick = @intFromFloat( @floor(tck) ); - n_sample_tick = b_sample_tick + 1; - - const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); - - const b_r_amp = aired_sn.fab.get_r_amp(b_sample_tick); - const n_r_amp = aired_sn.fab.get_r_amp(n_sample_tick); - - const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); - const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; - - srcamp += relayed_r_amp; - - } - } - _ = i; - - } - - if (srcamp > 1) { - srcamp = 1; - } else if (srcamp < -1) { - srcamp = -1; - } - - const instfreq = fmbasefreq + (fmbasefreq * fmq * srcamp); - const c = fcurrent_tick / 44100; - - const pp = prevphase + c*(instfreq - prevfreq) + @floor(c * prevfreq - prevphase); - const newphase = pp - @floor(pp); - - try self.soundnode.s("phase", newphase); - try self.soundnode.s("basefreq", instfreq); - - - } - - pub fn am(self: *Activity) !void { - - const current_tick: u32 = self.soundnode.fab.current_tick; - - var srcamp: f64 = 0; - - for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { - - const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick); - srcamp += relayed_r_amp; - _ = i; - - } - - for (self.soundnode.air_in.items, 0..) |aired_sn, i| { - - const dist: f64 = self.soundnode.distance(aired_sn); - - var b_sample_tick: u32 = 0; - var n_sample_tick: u32 = 0; - - const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); - - if (tck > 0) { - - b_sample_tick = @intFromFloat( @floor(tck) ); - n_sample_tick = b_sample_tick + 1; - - const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); - - const b_r_amp = aired_sn.fab.get_r_amp(b_sample_tick); - const n_r_amp = aired_sn.fab.get_r_amp(n_sample_tick); - - const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); - const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; - - srcamp += relayed_r_amp; - - } - - _ = i; - - } - - if (srcamp > 1) { - srcamp = 1; - } else if (srcamp < -1) { - srcamp = -1; - } - - try self.soundnode.s("gain", srcamp); - - } - - pub fn mute(self: *Activity) !void { - try self.soundnode.s("gain", 0); - } - - pub fn whitenoise(self: *Activity) void { - - const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - - const seed = self.operands[0]; - const gainmult = self.operands[1]; - - var r_amp = self.soundnode.g("gain"); - - if (gainmult > 0) { - r_amp *= gainmult; - } - - const w = (seed*current_tick) / math.sin(current_tick); - const rnd = (2 * (w - @floor(w))) - 1; - - const amp = r_amp * rnd; - self.soundnode.fab.add_r_amp(amp); - - } - - - pub fn setadsrgain(self: *Activity) !void { - try self.soundnode.s("adsrgain", self.operands[0]); - } - - - pub fn setadsrsustain(self: *Activity) !void { - try self.soundnode.s("adsrsustain", self.operands[0]); - } - - pub fn adsr(self: *Activity) !void { - - const real_current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); - const start_tick: f64 = @floatFromInt(self.start_tick); - const current_tick = real_current_tick - start_tick; - - var adsrgain = self.soundnode.g("adsrgain"); - const adsrsustain = self.soundnode.g("adsrsustain"); - - const attack_tick = self.operands[0]; - const hold_tick = self.operands[1]; - const decay_tick = self.operands[2]; - const sustain_tick = self.operands[3]; - const release_tick = self.operands[4]; - const gainmult = self.operands[5]; - - if (gainmult > 0) { - adsrgain *= gainmult; - } - - var gain: f64 = 0; - - if (current_tick <= attack_tick) { - gain = adsrgain * current_tick / attack_tick; - } else if (current_tick <= hold_tick) { - gain = adsrgain; - } else if (current_tick <= decay_tick) { - gain = ((current_tick-hold_tick)*(adsrsustain-adsrgain)/(decay_tick - hold_tick)) + adsrgain; - } else if (current_tick <= sustain_tick) { - gain = adsrsustain; - } else if (current_tick <= release_tick) { - gain = (adsrsustain * (current_tick - sustain_tick) / (sustain_tick - release_tick)) + adsrsustain; - } - - try self.soundnode.s("gain", gain); + gain *= gainmult; + } + const amp = gain * math.sin(utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau); + self.soundnode.add_r_amp(amp); } }; \ No newline at end of file diff --git a/zigsonnum/pin.zig b/zigsonnum/pin.zig new file mode 100644 index 0000000..07f309e --- /dev/null +++ b/zigsonnum/pin.zig @@ -0,0 +1,267 @@ +const std = @import("std"); +const SoundNode = @import("soundnode.zig").SoundNode; +const Allocator = std.mem.Allocator; + + +pub const Pin = struct { + + uid: usize = 0, + allocator: Allocator, + + src_node: *SoundNode, + trg_node: *SoundNode, + + src_pin: usize = 0, + trg_pin: usize = 0, + + active: u8 = 0, + + pub fn create(allocator: Allocator, + uid: usize, + src_node: *SoundNode, + trg_node: *SoundNode, + src_pin: usize, + trg_pin: usize) !*Pin { + + const pin = try allocator.create(Pin); + + pin.* = .{ + .allocator = allocator, + .uid = uid, + .src_node = src_node, + .trg_node = trg_node, + .src_pin = src_pin, + .trg_pin = trg_pin, + .active = 0, + }; + + return pin; + } + + pub fn propagate(self: *Pin) void { + + switch (self.src_pin) { + + 0 => { + switch (self.trg_pin) { + 0 => {self.trg_node.in_wire += self.src_node.r_amp; }, + 1 => { + const current_tick = self.src_node.fab.current_tick; + + const dist: f64 = self.trg_node.distance(self.src_node); + var b_sample_tick: u32 = 0; + var n_sample_tick: u32 = 0; + const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); + + if (tck > 0) { + + b_sample_tick = @intFromFloat( @floor(tck) ); + n_sample_tick = b_sample_tick + 1; + + const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const b_r_amp = self.src_node.fab.get_r_amp(b_sample_tick); + const n_r_amp = self.src_node.fab.get_r_amp(n_sample_tick); + + const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); + const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; + + self.trg_node.in_air += relayed_r_amp; + } + + }, + 6 => {self.trg_node.in6 += self.src_node.r_amp; }, + 7 => {self.trg_node.in7 *= self.src_node.r_amp; }, + else => {}, + } + }, + + 1 => { + switch (self.trg_pin) { + 0 => {self.trg_node.in_wire += self.src_node.out1; }, + 1 => { + const current_tick = self.src_node.fab.current_tick; + const dist: f64 = self.trg_node.distance(self.src_node); + var b_sample_tick: u32 = 0; + var n_sample_tick: u32 = 0; + const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); + + if (tck > 0) { + + b_sample_tick = @intFromFloat( @floor(tck) ); + n_sample_tick = b_sample_tick + 1; + + const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const b_r_amp = self.src_node.fab.get_r_amp(b_sample_tick); + const n_r_amp = self.src_node.fab.get_r_amp(n_sample_tick); + + const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); + const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; + + self.trg_node.in_air += relayed_r_amp; + } + + }, + 6 => {self.trg_node.in6 += self.src_node.out1; }, + 7 => {self.trg_node.in7 *= self.src_node.out1; }, + else => {}, + } + }, + + 6 => { + switch (self.trg_pin) { + 0 => {self.trg_node.in_wire += self.src_node.out6; }, + 1 => { + const current_tick = self.src_node.fab.current_tick; + const dist: f64 = self.trg_node.distance(self.src_node); + var b_sample_tick: u32 = 0; + var n_sample_tick: u32 = 0; + const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); + + if (tck > 0) { + + b_sample_tick = @intFromFloat( @floor(tck) ); + n_sample_tick = b_sample_tick + 1; + + const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const b_r_amp = self.src_node.fab.get_r_amp(b_sample_tick); + const n_r_amp = self.src_node.fab.get_r_amp(n_sample_tick); + + const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); + const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; + + self.trg_node.in_air += relayed_r_amp; + } + + }, + 6 => {self.trg_node.in6 += self.src_node.out6; }, + 7 => {self.trg_node.in7 *= self.src_node.out6; }, + else => {}, + } + }, + + 7 => { + switch (self.trg_pin) { + 0 => {self.trg_node.in_wire += self.src_node.out7; }, + 1 => { + const current_tick = self.src_node.fab.current_tick; + const dist: f64 = self.trg_node.distance(self.src_node); + var b_sample_tick: u32 = 0; + var n_sample_tick: u32 = 0; + const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); + + if (tck > 0) { + + b_sample_tick = @intFromFloat( @floor(tck) ); + n_sample_tick = b_sample_tick + 1; + + const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const b_r_amp = self.src_node.fab.get_r_amp(b_sample_tick); + const n_r_amp = self.src_node.fab.get_r_amp(n_sample_tick); + + const tick_diff = tck - @as(f64, @floatFromInt(b_sample_tick)); + const relayed_r_amp = (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation; + + self.trg_node.in_air += relayed_r_amp; + } + + }, + 6 => {self.trg_node.in6 += self.src_node.out7; }, + 7 => {self.trg_node.in7 *= self.src_node.out7; }, + else => {}, + } + }, + + 2 => { + switch (self.trg_pin) { + 2 => {self.trg_node.in_gain += self.src_node.gain; }, + 3 => {self.trg_node.in_basephase += self.src_node.gain; }, + 4 => {self.trg_node.in_phase += self.src_node.gain; }, + 8 => {self.trg_node.in8 += self.src_node.gain; }, + 9 => {self.trg_node.in9 *= self.src_node.gain; }, + else => {}, + } + }, + + 3 => { + switch (self.trg_pin) { + 2 => {self.trg_node.in_gain += self.src_node.basephase; }, + 3 => {self.trg_node.in_basephase += self.src_node.basephase; }, + 4 => {self.trg_node.in_phase += self.src_node.basephase; }, + 8 => {self.trg_node.in8 += self.src_node.basephase; }, + 9 => {self.trg_node.in9 *= self.src_node.basephase; }, + else => {}, + } + }, + + 4 => { + switch (self.trg_pin) { + 2 => {self.trg_node.in_gain += self.src_node.phase; }, + 3 => {self.trg_node.in_basephase += self.src_node.phase; }, + 4 => {self.trg_node.in_phase += self.src_node.phase; }, + 8 => {self.trg_node.in8 += self.src_node.phase; }, + 9 => {self.trg_node.in9 *= self.src_node.phase; }, + else => {}, + } + }, + + 8 => { + switch (self.trg_pin) { + 2 => {self.trg_node.in_gain += self.src_node.out8; }, + 3 => {self.trg_node.in_basephase += self.src_node.out8; }, + 4 => {self.trg_node.in_phase += self.src_node.out8; }, + 8 => {self.trg_node.in8 += self.src_node.out8; }, + 9 => {self.trg_node.in9 *= self.src_node.out8; }, + else => {}, + } + }, + + 9 => { + switch (self.trg_pin) { + 2 => {self.trg_node.in_gain += self.src_node.out9; }, + 3 => {self.trg_node.in_basephase += self.src_node.out9; }, + 4 => {self.trg_node.in_phase += self.src_node.out9; }, + 8 => {self.trg_node.in8 += self.src_node.out9; }, + 9 => {self.trg_node.in9 *= self.src_node.out9; }, + else => {}, + } + }, + + + 5 => { + switch (self.trg_pin) { + 5 => {self.trg_node.in_basefreq += self.src_node.basefreq; }, + 10 => {self.trg_node.in10 += self.src_node.basefreq; }, + 11 => {self.trg_node.in11 *= self.src_node.basefreq; }, + else => {}, + } + }, + + 10 => { + switch (self.trg_pin) { + 5 => {self.trg_node.in_basefreq += self.src_node.out10; }, + 10 => {self.trg_node.in10 += self.src_node.out10; }, + 11 => {self.trg_node.in11 *= self.src_node.out10; }, + else => {}, + } + }, + + 11 => { + switch (self.trg_pin) { + 5 => {self.trg_node.in_basefreq += self.src_node.out11; }, + 10 => {self.trg_node.in10 += self.src_node.out11; }, + 11 => {self.trg_node.in11 *= self.src_node.out11; }, + else => {}, + } + }, + + else => {}, + + } + + } + +}; \ No newline at end of file diff --git a/zigsonnum/sonnum.zig b/zigsonnum/sonnum.zig index b82e06d..4696305 100644 --- a/zigsonnum/sonnum.zig +++ b/zigsonnum/sonnum.zig @@ -6,6 +6,7 @@ const ArrayList = std.ArrayList; const Endian = std.builtin.Endian; const SoundNode = @import("soundnode.zig").SoundNode; +const Pin = @import ("pin.zig").Pin; const Activity = @import("activity.zig").Activity; const SoundSettings = @import("settings.zig").SoundSettings; const utility = @import("utility.zig"); @@ -54,6 +55,44 @@ pub fn removeSoundNodeFromList(snlist: *ArrayList(*SoundNode), sn: *SoundNode) u } +pub fn returnPinToList(pinlist: *ArrayList(*Pin), pn: *Pin) !void { + + for (pinlist.items, 0..) |pin, ind| { + + if (pn.uid < pin.uid) { + try pinlist.insert(ind, pn); + return; + } + + } + + try pinlist.append(pn); + return; + +} + +pub fn removePinFromList(pinlist: *ArrayList(*Pin), pn: *Pin) !void { + + var found: u8 = 0; + var toremove: usize = 0; + + for (pinlist.items, 0..) |pin, ind| { + + if (pn.uid == pin.uid) { + toremove = ind; + found = 1; + } + + } + + if (found == 1) { + _ = pinlist.orderedRemove(toremove); + } + + return found; + +} + pub fn reactivateSoundNode(alist: *ArrayList(*SoundNode), plist: *ArrayList(*SoundNode), sn: *SoundNode) !void { const remove_success = removeSoundNodeFromList(plist, sn); @@ -70,6 +109,22 @@ pub fn deactivateSoundNode(alist: *ArrayList(*SoundNode), plist: *ArrayList(*Sou } +pub fn reactivatePin(alist: *ArrayList(*Pin), plist: *ArrayList(*Pin), pn: *Pin) !void { + + const remove_success = removePinFromList(plist, pn); + _ = remove_success; + try returnSoundNodeToList(alist, pn); + +} + +pub fn deactivatePin(alist: *ArrayList(*Pin), plist: *ArrayList(*Pin), pn: *Pin) !void { + + const remove_success = removePinFromList(alist, pn); + _ = remove_success; + try plist.append(pn); + +} + pub fn main() !void { const allocator = std.heap.c_allocator; @@ -80,12 +135,18 @@ pub fn main() !void { // Creating a list of soundnodes var soundnodes = ArrayList(*SoundNode).init(allocator); defer soundnodes.deinit(); - + + // Active and passive soundnodes + var a_soundnodes = ArrayList(*SoundNode).init(allocator); defer a_soundnodes.deinit(); var p_soundnodes = ArrayList(*SoundNode).init(allocator); defer p_soundnodes.deinit(); + // Creating a list of soundnodes + var pins = ArrayList(*Pin).init(allocator); + defer pins.deinit(); + // Determining length of resulting audio in ticks const start_tick: u32 = 0; var end_tick: u32 = 44100 * 10; @@ -216,18 +277,12 @@ pub fn main() !void { switch (opcode) { 0 => { - const nodename = try std.fmt.allocPrint(allocator, "{d}", .{src_node}); - const uid: usize = @as(usize, src_node); - const sn = try SoundNode.create(allocator, nodename, uid); + const sn = try SoundNode.create(allocator, uid); //print("Added node {s} at tick {d}\n", .{nodename, tick}); try soundnodes.append(sn); try p_soundnodes.append(sn); - - try sn.s("basefreq", @as(f64, 440)); - try sn.s("gain", @as(f64, 1)); - try sn.s("phase", @as(f64, 0)); - + }, 1 => { @@ -235,29 +290,26 @@ pub fn main() !void { const trg = soundnodes.items[trg_node]; //print("Wired nodes at tick {d}\n", .{tick}); - try trg.wire_in.append(src); - try src.wire_targets.append(trg); - }, - - 2 => { - const src = soundnodes.items[src_node]; - const trg = soundnodes.items[trg_node]; + const uid: usize = pins.items.len; + const src_pin: usize = @intFromFloat(op1); + const trg_pin: usize = @intFromFloat(op2); - //print("Aired nodes at tick {d}\n", .{tick}); - try trg.air_in.append(src); - try src.air_targets.append(trg); + const pin = try Pin.create(allocator, uid, src, trg, src_pin, trg_pin); + + try pins.append(pin); + try src.pins.append(pin); }, - + 3 => { + end_tick = tick_end; try stdout.writeInt( u32, end_tick * 2 * settings.sample_width, - Endian.little, - ); - //print("End tick set to {d}\n", .{end_tick}); - }, + Endian.little); + + }, else => { @@ -270,6 +322,12 @@ pub fn main() !void { if (src.activities.items.len == 1 and src.active == 0) { src.active = 1; try reactivateSoundNode(&a_soundnodes, &p_soundnodes, src); + + for (src.pins.items, 0..) |pin, zj| { + pin.active = 1; + _ = zj; + } + } }, @@ -282,38 +340,62 @@ pub fn main() !void { } + + for (soundnodes.items, 0..) |soundnode, i| { + soundnode.nullizeStartTick(); + _ = i; + } + //All but left and right - for (soundnodes.items[2..], 0..) |soundnode, i| { - - var toremove = ArrayList(usize).init(allocator); - defer toremove.deinit(); + if (a_soundnodes.items.len > 2) { + for (a_soundnodes.items[2..], 0..) |soundnode, i| { - for (soundnode.activities.items, 0..) |activity, j| { - - if (tick <= activity.end_tick and tick >= activity.start_tick) { - try activity.do(); - } else if (tick >= activity.end_tick) { - try toremove.append(j); + var toremove = ArrayList(usize).init(allocator); + defer toremove.deinit(); + + for (soundnode.activities.items, 0..) |activity, j| { + + if (tick <= activity.end_tick and tick >= activity.start_tick) { + try activity.do(); + } else if (tick >= activity.end_tick) { + try toremove.append(j); + } } - } - - var j: usize = toremove.items.len; - while (j > 0) { - j -= 1; - const activity_ind = toremove.items[j]; + for (soundnode.pins.items, 0..) |pin, zj| { + pin.propagate(); + _ = zj; + } + + var j: usize = toremove.items.len; + + while (j > 0) { + j -= 1; + const activity_ind = toremove.items[j]; + + _ = soundnode.activities.swapRemove(activity_ind); + + if (soundnode.activities.items.len == 0 and soundnode.active == 1) { - _ = soundnode.activities.swapRemove(activity_ind); - - if (soundnode.activities.items.len == 0 and soundnode.active == 1) { - - soundnode.active = 0; - try deactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode); - + soundnode.active = 0; + try deactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode); + + for (soundnode.pins.items, 0..) |pin, zj| { + pin.active = 0; + _ = zj; + } + } } + + soundnode.fab.increment_tick(); + _ = i; } - + } + + // Incrementing passive ones too + + for (p_soundnodes.items, 0..) |soundnode, i| { soundnode.fab.increment_tick(); _ = i; } @@ -335,6 +417,11 @@ pub fn main() !void { } + for (soundnode.pins.items, 0..) |pin, jz| { + pin.propagate(); + _ = jz; + } + var j: usize = toremove.items.len; while (j > 0) { @@ -351,12 +438,10 @@ pub fn main() !void { left = soundnodes.items[0]; right = soundnodes.items[1]; - const current_r_amp_left = left.fab.get_current_r_amp(); - sample = @intFromFloat(current_r_amp_left * settings.max_amp_multiplier); + sample = @intFromFloat(left.r_amp * settings.max_amp_multiplier); try stdout.writeInt(i24, sample, Endian.little); - const current_r_amp_right = right.fab.get_current_r_amp(); - sample = @intFromFloat(current_r_amp_right * settings.max_amp_multiplier); + sample = @intFromFloat(right.r_amp * settings.max_amp_multiplier); try stdout.writeInt(i24, sample, Endian.little); left.fab.increment_tick(); diff --git a/zigsonnum/soundnode.zig b/zigsonnum/soundnode.zig index 26517f6..e4cc0b0 100644 --- a/zigsonnum/soundnode.zig +++ b/zigsonnum/soundnode.zig @@ -10,6 +10,7 @@ const StringHashMap = std.StringHashMap; const pnt = @import("point.zig"); const Pnt = pnt.Pnt; +const Pin = @import("pin.zig").Pin; const Activity = @import("activity.zig").Activity; const SoundSettings = @import("settings.zig").SoundSettings; const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer; @@ -22,6 +23,178 @@ pub const SoundNode = struct { allocator: Allocator, + uid: usize = 0, + + // Input pins + in_wire: f64, + in_air: f64, + in_gain: f64, + in_basephase: f64, + in_phase: f64, + in_basefreq: f64, + in6: f64, + in7: f64, + in8: f64, + in9: f64, + in10: f64, + in11: f64, + + // Output pins + + r_amp: f64, + out1: f64, + gain: f64, + basephase: f64, + phase: f64, + basefreq: f64, + out6: f64, + out7: f64, + out8: f64, + out9: f64, + out10: f64, + out11: f64, + + activities: ArrayList(*Activity), + pins: ArrayList(*Pin), + props: StringHashMap(f64), + + x: f32 = 0, + y: f32 = 0, + z: f32 = 0, + + fab: FreqAmpBuffer, + active: u8 = 1, + + pub fn nullizeStartTick(self: *SoundNode) void { + + self.in_wire = 0; + self.in_air = 0; + self.in_gain = 0; + self.in_basephase = 0; + self.in_phase = 0; + self.in_basefreq = 0; + self.in6 = 0; + self.in7 = 0; + self.in8 = 0; + self.in9 = 0; + self.in10 = 0; + self.in11 = 0; + + self.r_amp = 0; + + } + + pub fn create(allocator: Allocator, uid: usize) !*SoundNode { + + const activities = ArrayList(*Activity).init(allocator); + const pins = ArrayList(*Pin).init(allocator); + const fab = FreqAmpBuffer{}; + const props = StringHashMap(f64).init(allocator); + + const sn = try allocator.create(SoundNode); + + sn.* = .{ + .uid = uid, + .allocator = allocator, + + .in_wire = 0, + .in_air = 0, + .in_gain = 0, + .in_basephase = 0, + .in_phase = 0, + .in_basefreq = 0, + .in6 = 0, + .in7 = 0, + .in8 = 0, + .in9 = 0, + .in10 = 0, + .in11 = 0, + + .r_amp = 0, + .out1 = 0, + .gain = 0, + .basephase = 0, + .phase = 0, + .basefreq = 0, + .out6 = 0, + .out7 = 0, + .out8 = 0, + .out9 = 0, + .out10 = 0, + .out11 = 0, + + .activities = activities, + .pins = pins, + .fab = fab, + .props = props, + .x = 0, + .y = 0, + .z = 0, + .active = 0, + }; + + return sn; + + } + + pub fn deinit(self: *SoundNode) void { + + self.activities.deinit(); + self.fab.deinit(); + self.props.deinit(); + + } + + pub fn current_tick(self: *SoundNode) u32 { + + return self.fab.current_tick; + + } + + pub fn add_r_amp(self: *SoundNode, r_amp: f64) void { + self.fab.add_r_amp(r_amp); + self.r_amp += r_amp; + } + + pub fn g(self: *SoundNode, key: []const u8) f64 { + + const value = self.props.get(key); + + if (value) |v| { + return v; + } else { + return @as(f64, 0.0); + } + } + + pub fn s(self: *SoundNode, key: []const u8, value: f64) !void { + + try self.props.put(key, value); + + } + + pub fn distance(self: *SoundNode, other: *SoundNode) f64 { + + if ((self.x == other.x) and (self.y == other.y) and (self.z == other.z)) { + return 0; + } + + const dx: f32 = self.x - other.x; + const dy: f32 = self.y - other.y; + const dz: f32 = self.z - other.z; + + return math.sqrt(dx*dx + dy*dy + dz*dz); + + } + +}; + + + +pub const SoundNodeOld = struct { + + allocator: Allocator, + name: []const u8 = "soundnode", uid: usize = 0,