diff --git a/mysynths/sintest.py b/mysynths/sintest.py index 949c3c3..fca8bf6 100644 --- a/mysynths/sintest.py +++ b/mysynths/sintest.py @@ -1,9 +1,9 @@ s.setup(s.sec(10)) n = s.node() -n.setbasefreq(0, s.note("D4")) -n.setgain(0, 0.09) +n.setpin(0, s.BASEFREQ, s.note("D4")) n.sine(0, s.sec(10)) -s.wire(n, s.left) \ No newline at end of file +s.wire(n, s.left) +s.wire(n, s.right) \ No newline at end of file diff --git a/pysonnum/activity.py b/pysonnum/activity.py index d303374..d48ab00 100644 --- a/pysonnum/activity.py +++ b/pysonnum/activity.py @@ -4,17 +4,18 @@ OPCODES = { 'create': 0, 'pin': 1, - 'endtick': 3, + 'endtick': 2, + 'setpin': 3, 'relay': 4, - 'setpos': 5, - 'setbasefreq': 6, - 'setgain': 7, - 'setbasephase': 8, - 'sine': 9, - 'triangle': 10, - 'square': 11, - 'sawtooth': 12, - 'setskew': 13, + + 'setpos': 10, + + 'sine': 50, + 'triangle': 51, + + 'square': 10, + 'sawtooth': 11, + 'setskew': 12, 'skewsine': 14, 'slidebasefreq': 15, 'slidegain': 16, @@ -30,6 +31,7 @@ OPCODES = { 'setadsrgain': 26, 'setadsrsustain': 27, 'adsr': 28, + } class Activity: diff --git a/pysonnum/sonnum.py b/pysonnum/sonnum.py index 5168413..93b2990 100644 --- a/pysonnum/sonnum.py +++ b/pysonnum/sonnum.py @@ -3,6 +3,19 @@ from .notes import * class Sonnum: + R_AMP = 0 + OUT1 = 1 + GAIN = 2 + BASEPHASE = 3 + PHASE = 4 + BASEFREQ = 5 + OUT6 = 6 + OUT7 = 7 + OUT8 = 8 + OUT9 = 9 + OUT10 = 10 + OUT11 = 11 + def __init__(self, compiler): self.c = compiler diff --git a/pysonnum/soundnode.py b/pysonnum/soundnode.py index 19b8926..295bf01 100644 --- a/pysonnum/soundnode.py +++ b/pysonnum/soundnode.py @@ -24,14 +24,8 @@ class SoundNode: def setpos(self, start_tick, x, y, z): self.act('setpos', start_tick, start_tick, self, None, [x, y, z]) - def setbasefreq(self, start_tick, basefreq): - self.act('setbasefreq', start_tick, start_tick, self, None, [basefreq]) - - def setgain(self, start_tick, gain): - self.act('setgain', start_tick, start_tick, self, None, [gain]) - - def setphase(self, start_tick, phase): - self.act('setphase', start_tick, start_tick, self, None, [phase]) + def setpin(self, start_tick, pin_no, value): + self.act('setpin', start_tick, start_tick, self, None, [pin_no, value]) def sine(self, start_tick, end_tick, gainmult = 0.0): self.act('sine', start_tick, end_tick, self, None, [gainmult]) @@ -45,9 +39,6 @@ class SoundNode: def sawtooth(self, start_tick, end_tick, gainmult = 0.0): self.act('sawtooth', start_tick, end_tick, self, None, [gainmult]) - def setskew(self, start_tick, skew): - self.act('setskew', start_tick, start_tick, self, None, [skew]) - def skewsine(self, start_tick, end_tick, gainmult = 0.0): self.act('skewsine', start_tick, end_tick, self, None, [gainmult]) diff --git a/zigsonnum/activities/basicsynths.zig b/zigsonnum/activities/basicsynths.zig new file mode 100644 index 0000000..5be0643 --- /dev/null +++ b/zigsonnum/activities/basicsynths.zig @@ -0,0 +1,107 @@ +const std = @import("std"); +const math = std.math; +const print = std.debug.print; +const Activity = @import ("../activity.zig").Activity; +const SoundNode = @import("../soundnode.zig").SoundNode; +const utility = @import("../utility.zig"); +const dbg = utility.dbg; +const idbg = utility.idbg; + + +// Produces a sine wave to r_amp pin +pub fn sine(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const gain = self.soundnode.corrGain(self.operands[0]); + + const amp = math.sin(utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau); + const final_amp = gain * amp; + + self.soundnode.add_r_amp(final_amp); + +} + +// Produces a triangle wave to r_amp pin +pub fn triangle(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const gain = self.soundnode.corrGain(self.operands[0]); + + const period = 44100 / self.soundnode.basefreq; + const tp = (current_tick - (period * self.soundnode.basephase)) / period; + + const amp = @abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1; + const final_amp = gain * amp; + + self.soundnode.add_r_amp(final_amp); + +} + +// Produces a square wave to r_amp pin +pub fn square(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const gain = self.soundnode.corrGain(self.operands[0]); + + const sin = math.sin(utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau); + + if (sin > 0) { + self.soundnode.add_r_amp(gain); + } else { + self.soundnode.add_r_amp(-gain); + } + +} + +// Produces a sawtooth wave to r_amp pin +pub fn sawtooth(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + + const gain = self.soundnode.corrGain(self.operands[0]); + + const period = 44100 / self.soundnode.basefreq; + const tp = (current_tick - (period * self.soundnode.basephase)) / period; + + const amp = 2 * (tp - @floor(0.5+tp)); + const final_amp = gain * amp; + + self.soundnode.add_r_amp(final_amp); + +} + +// Produces a skewed sine wave to R_AMP pin +// Skeweness factor is taken from OUT8 pin +pub fn skewsine(self: *Activity) void { + + const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const gain = self.soundnode.corrGain(self.operands[0]); + + const skew = self.soundnode.out8; + var amp: f64 = 0; + + if (skew == 0) { + + amp = math.sin(utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau); + + } else if (skew > 0) { + + const m = (utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau); + const sincos = skew * math.sin(m) / (1 - skew*math.cos(m)); + amp = (1/skew) * math.atan(sincos); + + } else if (skew < 0) { + + const m = (utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau); + const sincos = skew * math.cos(m) / (1 + skew*math.sin(m)); + amp = (1/skew) * math.atan(sincos); + + } + + const final_amp = gain * amp; + + self.soundnode.add_r_amp(final_amp); + +} \ No newline at end of file diff --git a/zigsonnum/activities/spatial.zig b/zigsonnum/activities/spatial.zig new file mode 100644 index 0000000..41ed80d --- /dev/null +++ b/zigsonnum/activities/spatial.zig @@ -0,0 +1,17 @@ +const std = @import("std"); +const math = std.math; +const print = std.debug.print; +const Activity = @import ("../activity.zig").Activity; +const SoundNode = @import("../soundnode.zig").SoundNode; +const utility = @import("../utility.zig"); +const dbg = utility.dbg; +const idbg = utility.idbg; + +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])); + + +} diff --git a/zigsonnum/activity.zig b/zigsonnum/activity.zig index 36a9f70..9349bda 100644 --- a/zigsonnum/activity.zig +++ b/zigsonnum/activity.zig @@ -4,9 +4,10 @@ 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"); +const basicsynths = @import ("activities/basicsynths.zig"); +const spatial = @import ("activities/spatial.zig"); pub const Activity = struct { @@ -34,50 +35,12 @@ pub const Activity = struct { pub fn do(self: *Activity) !void { switch (self.opcode) { 4 => { self.relay(); }, - 5 => { self.setpos(); }, - 6 => { self.setbasefreq(); }, - 7 => { self.setgain(); }, - 8 => { self.setbasephase(); }, - 9 => { self.sine(); }, + 10 => { spatial.setpos(self); }, + 50 => { basicsynths.sine(self); }, + 51 => { basicsynths.triangle(self); }, 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 { @@ -86,40 +49,4 @@ pub const Activity = struct { } - 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 gainmult = self.operands[0]; - - var gain = self.soundnode.gain; - - if (gainmult > 0) { - 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/sonnum.zig b/zigsonnum/sonnum.zig index 05e562b..9116c50 100644 --- a/zigsonnum/sonnum.zig +++ b/zigsonnum/sonnum.zig @@ -153,9 +153,14 @@ pub fn main() !void { while (tick < end_tick) { if (tick%44100 == 0) { - print("T {d} ", .{tick}); + print("{d}-- ", .{tick/44100}); } + for (soundnodes.items, 0..) |soundnode, i| { + soundnode.nullizeStartTick(); + _ = i; + } + if (tick == nextopcodetick) { while (cursor < buf.len) { @@ -237,7 +242,7 @@ pub fn main() !void { try trg.pins.append(pin); }, - 3 => { + 2 => { end_tick = tick_end; @@ -247,6 +252,31 @@ pub fn main() !void { Endian.little); }, + + 3 => { + + const sn = soundnodes.items[src_node]; + const sn_pin: usize = @intFromFloat(op1); + + switch (sn_pin) { + + 0 => { sn.r_amp = op2; }, + 1 => { sn.out1 = op2; }, + 2 => { sn.gain = op2; }, + 3 => { sn.basephase = op2; }, + 4 => { sn.phase = op2; }, + 5 => { sn.basefreq = op2; }, + 6 => { sn.out6 = op2; }, + 7 => { sn.out7 = op2; }, + 8 => { sn.out8 = op2; }, + 9 => { sn.out9 = op2; }, + 10 => { sn.out10 = op2; }, + 11 => { sn.out11 = op2; }, + else => {}, + + } + + }, else => { @@ -273,22 +303,20 @@ pub fn main() !void { } - for (soundnodes.items, 0..) |soundnode, i| { - soundnode.nullizeStartTick(); - _ = i; - } - //All but left and right if (a_soundnodes.items.len > 2) { + for (a_soundnodes.items[2..], 0..) |soundnode, i| { - for (soundnode.pins.items, 0..) |pin, zj| { + for (soundnode.pins.items, 0..) |pin, j| { + if (pin.src_node.active == 1 or pin.trg_pin == 1) { pin.propagate(); } - _ = zj; + _ = j; } + var toremove = ArrayList(usize).init(allocator); defer toremove.deinit(); @@ -321,6 +349,7 @@ pub fn main() !void { soundnode.fab.increment_tick(); _ = i; } + } // Incrementing passive ones too diff --git a/zigsonnum/soundnode.zig b/zigsonnum/soundnode.zig index e4cc0b0..8ca809e 100644 --- a/zigsonnum/soundnode.zig +++ b/zigsonnum/soundnode.zig @@ -83,6 +83,15 @@ pub const SoundNode = struct { self.r_amp = 0; } + + pub fn corrGain(self: *SoundNode, gainmult: f64) f64 { + + if (gainmult > 0) { + return self.gain * gainmult; + } else { + return self.gain; + } + } pub fn create(allocator: Allocator, uid: usize) !*SoundNode { @@ -112,7 +121,7 @@ pub const SoundNode = struct { .r_amp = 0, .out1 = 0, - .gain = 0, + .gain = 1, .basephase = 0, .phase = 0, .basefreq = 0, @@ -152,8 +161,10 @@ pub const SoundNode = struct { } 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 { diff --git a/zigsonnum/utility.zig b/zigsonnum/utility.zig index d20c551..0c1779e 100644 --- a/zigsonnum/utility.zig +++ b/zigsonnum/utility.zig @@ -4,6 +4,22 @@ const print = std.debug.print; pub const tau: f64 = 2 * 3.1415926535897932384626433832795028841971; pub const corrected_tau: f64 = tau / 44100; +const debug: bool = true; + +pub fn dbg(s: []const u8) void { + if (debug) { + print("{s}\n", .{s}); + } + +} + +pub fn idbg(s: anytype) void { + if (debug) { + print("{d}\n", .{s}); + } + +} + pub fn prnt(s: []const u8) void { print("{s}\n", .{s}); }