diff --git a/mysynths/epiano.py b/mysynths/epiano.py new file mode 100644 index 0000000..ddd811a --- /dev/null +++ b/mysynths/epiano.py @@ -0,0 +1,61 @@ +class PianoString: + + def __init__(self, s, note): + + self.s = s + self.basefreq = self.s.note(note) + self.primary_gain = 0.4 + + self.mod = self.s.node() + self.node = self.s.node() + + self.node.setbasefreq(0, self.basefreq) + self.node.setgain(0, self.primary_gain) + + self.mod.setbasefreq(0, 10) + self.mod.setgain(0, 0.8) + self.mod.sine(0, self.s.end) + self.node.fmsetup(0, self.basefreq, 0.009) + self.node.fm(0, self.s.end) + self.node.setskew(0, 0.3) + + self.s.wire(self.mod, self.node) + self.s.air(self.node, [self.s.left, self.s.right]) + + def gain(self, starttick, gain): + + self.node.setgain(starttick, gain) + + def play(self, starttick, endtick): + + self.node.slidegain(starttick, endtick, self.primary_gain, 0) + self.node.sine(starttick, endtick, 0.5) + self.node.skewsine(starttick, endtick) + self.node.square(starttick, endtick, 0.2) + self.node.triangle(starttick, endtick, 0.4) + + + def playsec(self, start, end): + + self.play(self.s.sec(start), self.s.sec(end)) + +s.setup(s.sec(4)) + +""" +S = PianoString(s, "E4") +S.playsec(0,1) + +S2 = PianoString(s, "C#4") +S2.playsec(1,2) + +""" +n = s.node() +n.setgain(0, 0.4) +#n.whitenoise(0, s.sec(2), 0.8924587, 0.3) + +n.setadsrgain(0, 1) +n.setadsrsustain(0, 0.4) +n.adsr(0, s.sec(2), s.sec(0.03), s.sec(0.04), s.sec(0.3), s.sec(1.3), s.sec(2)) +n.sine(0, s.sec(2), 0.3) +n.triangle(0, s.sec(2)) +s.wire(n, [s.left, s.right]) diff --git a/pysonnum/activity.py b/pysonnum/activity.py index 057281c..3ab67e1 100644 --- a/pysonnum/activity.py +++ b/pysonnum/activity.py @@ -23,9 +23,14 @@ OPCODES = { 'slideskew': 18, 'slidepos': 19, 'pulse': 20, - 'setfmsettings': 21, + 'fmsetup': 21, 'fm': 22, 'am': 23, + 'mute': 24, + 'whitenoise': 25, + 'setadsrgain': 26, + 'setadsrsustain': 27, + 'adsr': 28, } class Activity: diff --git a/pysonnum/sonnum.py b/pysonnum/sonnum.py index d788695..a01c7f5 100644 --- a/pysonnum/sonnum.py +++ b/pysonnum/sonnum.py @@ -8,6 +8,17 @@ class Sonnum: self.c = compiler self.nodes = [] # {order: name} self.properties = dict() # {k: v} + + def setup(self, endtick): + + self.end = endtick + self.endtick(endtick) + + self.left = self.relay() + self.right = self.relay() + + self.left.setpos(0, -0.3, 0, 0) + self.right.setpos(0, 0.3, 0, 0) def add_node(self, name): diff --git a/pysonnum/soundnode.py b/pysonnum/soundnode.py index 292bfb8..ce707a8 100644 --- a/pysonnum/soundnode.py +++ b/pysonnum/soundnode.py @@ -33,23 +33,23 @@ class SoundNode: def setphase(self, start_tick, phase): self.act('setphase', start_tick, start_tick, self, None, [phase]) - def sine(self, start_tick, end_tick): - self.act('sine', start_tick, end_tick, self, None, []) + def sine(self, start_tick, end_tick, gainmult = 0.0): + self.act('sine', start_tick, end_tick, self, None, [gainmult]) - def triangle(self, start_tick, end_tick): - self.act('triangle', start_tick, end_tick, self, None, []) + def triangle(self, start_tick, end_tick, gainmult = 0.0): + self.act('triangle', start_tick, end_tick, self, None, [gainmult]) - def square(self, start_tick, end_tick): - self.act('square', start_tick, end_tick, self, None, []) + def square(self, start_tick, end_tick, gainmult = 0.0): + self.act('square', start_tick, end_tick, self, None, [gainmult]) - def sawtooth(self, start_tick, end_tick): - self.act('sawtooth', start_tick, end_tick, self, None, []) + 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): - self.act('skewsine', start_tick, end_tick, self, None, []) + def skewsine(self, start_tick, end_tick, gainmult = 0.0): + self.act('skewsine', start_tick, end_tick, self, None, [gainmult]) def slidebasefreq(self, start_tick, end_tick, startfreq, endfreq): self.act('slidebasefreq', start_tick, end_tick, self, None, [startfreq, endfreq]) @@ -66,14 +66,29 @@ class SoundNode: def slidepos(self, start_tick, end_tick, sx, sy, sz, ex, ey, ez): self.act('slidepos', start_tick, end_tick, self, None, [sx, sy, sz, ex, ey, ez]) - def pulse(self, start_tick, end_tick): - self.act('pulse', start_tick, end_tick, self, None, []) + def pulse(self, start_tick, end_tick, gainmult = 0.0): + self.act('pulse', start_tick, end_tick, self, None, [gainmult]) - def setfmsettings(self, start_tick, fmbasefreq, fmq): - self.act('setfmsettings', start_tick, start_tick, self, None, [fmbasefreq, fmq]) + def fmsetup(self, start_tick, fmbasefreq, fmq): + self.act('fmsetup', start_tick, start_tick, self, None, [fmbasefreq, fmq]) def fm(self, start_tick, end_tick): self.act('fm', start_tick, end_tick, self, None, []) def am(self, start_tick, end_tick): - self.act('am', start_tick, end_tick, self, None, []) \ No newline at end of file + self.act('am', start_tick, end_tick, self, None, []) + + def mute(self, start_tick, end_tick): + self.act('mute', start_tick, end_tick, self, None, []) + + def whitenoise(self, start_tick, end_tick, seed = 0.259624856928, gainmult = 0.0): + self.act('whitenoise', start_tick, end_tick, self, None, [seed, gainmult]) + + def setadsrgain(self, start_tick, adsrgain): + self.act('setadsrgain', start_tick, start_tick, self, None, [adsrgain]) + + def setadsrsustain(self, start_tick, adsrsustain): + self.act('setadsrsustain', start_tick, start_tick, self, None, [adsrsustain]) + + def adsr(self, start_tick, end_tick, attack_tick, hold_tick, decay_tick, sustain_tick, release_tick, gainmult = 0.0): + self.act('adsr', start_tick, end_tick, self, None, [attack_tick, hold_tick, decay_tick, sustain_tick, release_tick, gainmult]) \ No newline at end of file diff --git a/zigsonnum/activity.zig b/zigsonnum/activity.zig index 0b679a7..7c988cb 100644 --- a/zigsonnum/activity.zig +++ b/zigsonnum/activity.zig @@ -50,9 +50,14 @@ pub const Activity = struct { 18 => { try self.slideskew(); }, 19 => { self.slidepos(); }, 20 => { self.pulse(); }, - 21 => { try self.setfmsettings(); }, + 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 => {}, } } @@ -161,8 +166,14 @@ pub const Activity = struct { const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); const freq = self.soundnode.g("basefreq"); - const r_amp = self.soundnode.g("gain"); 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); @@ -174,9 +185,14 @@ pub const Activity = struct { const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); const freq = self.soundnode.g("basefreq"); - const r_amp = self.soundnode.g("gain"); 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; @@ -190,8 +206,13 @@ pub const Activity = struct { const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); const freq = self.soundnode.g("basefreq"); - const r_amp = self.soundnode.g("gain"); 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); @@ -208,8 +229,13 @@ pub const Activity = struct { const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); const freq = self.soundnode.g("basefreq"); - const r_amp = self.soundnode.g("gain"); 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; @@ -228,8 +254,13 @@ pub const Activity = struct { const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); const freq = self.soundnode.g("basefreq"); - const r_amp = self.soundnode.g("gain"); 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) { @@ -359,8 +390,13 @@ pub const Activity = struct { const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); const freq = self.soundnode.g("basefreq"); - const r_amp = self.soundnode.g("gain"); 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; @@ -375,7 +411,7 @@ pub const Activity = struct { } - pub fn setfmsettings(self: *Activity) !void { + 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]); @@ -453,7 +489,7 @@ pub const Activity = struct { try self.soundnode.s("phase", newphase); try self.soundnode.s("basefreq", instfreq); - + } @@ -508,7 +544,79 @@ pub const Activity = struct { } 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 current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); + const start_tick: f64 = @floatFromInt(self.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 <= start_tick + attack_tick) { + gain = adsrgain * current_tick / attack_tick; + } else if (current_tick <= start_tick + hold_tick) { + gain = adsrgain; + } else if (current_tick <= start_tick + decay_tick) { + gain = ((current_tick-hold_tick)*(adsrsustain-adsrgain)/(decay_tick - hold_tick)) + adsrgain; + } else if (current_tick <= start_tick + sustain_tick) { + gain = adsrsustain; + } else if (current_tick <= start_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