pin and bridge renamed to feed and copy; added whitenoise, mute and adsr
This commit is contained in:
parent
3ec8cd4704
commit
f2868d8dcd
8 changed files with 144 additions and 72 deletions
|
|
@ -1,19 +1,24 @@
|
||||||
s.setup(s.sec(10))
|
ln = s.sec(10)
|
||||||
|
s.setup(ln)
|
||||||
|
|
||||||
m = s.node()
|
m = s.node()
|
||||||
n = s.node()
|
n = s.node()
|
||||||
|
adsr = s.node()
|
||||||
|
|
||||||
s.pin(m, BASEFREQ, n, IN_BASEFREQ)
|
adsr.setpin(0, OUT8, 0.9)
|
||||||
|
adsr.setpin(0, OUT9, 0.4)
|
||||||
|
adsr.adsr(0, s.sec(6), s.sec(0.1), s.sec(0.2), s.sec(0.5), s.sec(0.5), s.sec(1.7))
|
||||||
|
|
||||||
m.singenN(0, s.sec(10), 50.4, 0, 0.003, 440)
|
adsr.feed(n, GAIN, IN_GAIN)
|
||||||
|
|
||||||
|
m.feed(n, BASEFREQ, IN_BASEFREQ)
|
||||||
|
m.singenN(0, ln, 50.4, 0, 0.003, 440)
|
||||||
|
|
||||||
|
n.copy(0, ln, IN_BASEFREQ, BASEFREQ)
|
||||||
|
n.copy(0, ln, IN_GAIN, GAIN)
|
||||||
|
|
||||||
n.bridge(0, s.sec(10), IN_BASEFREQ, BASEFREQ)
|
|
||||||
#n.setpin(0, BASEFREQ, 330)
|
|
||||||
n.setpin(0, OUT8, 0.3)
|
n.setpin(0, OUT8, 0.3)
|
||||||
n.pulse(0, s.sec(10))
|
n.skewsine(0, ln)
|
||||||
|
|
||||||
n.printstate(30000, 30000)
|
|
||||||
n.printstate(30001, 30001)
|
|
||||||
|
|
||||||
s.wire(n, s.left)
|
s.wire(n, s.left)
|
||||||
s.wire(n, s.right)
|
s.wire(n, s.right)
|
||||||
|
|
@ -3,11 +3,12 @@ import struct
|
||||||
OPCODES = {
|
OPCODES = {
|
||||||
|
|
||||||
'create': 0,
|
'create': 0,
|
||||||
'pin': 1,
|
'feed': 1,
|
||||||
'endtick': 2,
|
'endtick': 2,
|
||||||
'setpin': 3,
|
'setpin': 3,
|
||||||
'relay': 4,
|
'relay': 4,
|
||||||
'bridge': 5,
|
'copy': 5,
|
||||||
|
'mute': 6,
|
||||||
'printstate': 9,
|
'printstate': 9,
|
||||||
|
|
||||||
'setpos': 10,
|
'setpos': 10,
|
||||||
|
|
@ -18,24 +19,11 @@ OPCODES = {
|
||||||
'sawtooth': 53,
|
'sawtooth': 53,
|
||||||
'skewsine': 54,
|
'skewsine': 54,
|
||||||
'pulse': 55,
|
'pulse': 55,
|
||||||
|
'whitenoise': 55,
|
||||||
|
|
||||||
'singenN': 100,
|
'singenN': 100,
|
||||||
|
'adsr': 150,
|
||||||
'setskew': 12,
|
|
||||||
'slidebasefreq': 15,
|
|
||||||
'slidegain': 16,
|
|
||||||
'slidephase': 17,
|
|
||||||
'slideskew': 18,
|
|
||||||
'slidepos': 19,
|
|
||||||
'fmsetup': 21,
|
|
||||||
'fm': 22,
|
|
||||||
'am': 23,
|
|
||||||
'mute': 24,
|
|
||||||
'whitenoise': 25,
|
|
||||||
'setadsrgain': 26,
|
|
||||||
'setadsrsustain': 27,
|
|
||||||
'adsr': 28,
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Activity:
|
class Activity:
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ class Sonnum:
|
||||||
|
|
||||||
for src_node in src_nodes:
|
for src_node in src_nodes:
|
||||||
for trg_node in trg_nodes:
|
for trg_node in trg_nodes:
|
||||||
self.act('pin', 0, 0, src_node, trg_node, [0, 0])
|
self.act('feed', 0, 0, src_node, trg_node, [0, 0])
|
||||||
|
|
||||||
def air(self, src_nodes, trg_nodes):
|
def air(self, src_nodes, trg_nodes):
|
||||||
|
|
||||||
|
|
@ -91,9 +91,9 @@ class Sonnum:
|
||||||
|
|
||||||
for src_node in src_nodes:
|
for src_node in src_nodes:
|
||||||
for trg_node in trg_nodes:
|
for trg_node in trg_nodes:
|
||||||
self.act('pin', 0, 0, src_node, trg_node, [0, 1])
|
self.act('feed', 0, 0, src_node, trg_node, [0, 1])
|
||||||
|
|
||||||
def pin(self, src_nodes, src_pin, trg_nodes, trg_pin):
|
def feed(self, src_nodes, src_pin, trg_nodes, trg_pin):
|
||||||
|
|
||||||
if not isinstance(src_nodes, list):
|
if not isinstance(src_nodes, list):
|
||||||
src_nodes = [src_nodes]
|
src_nodes = [src_nodes]
|
||||||
|
|
@ -103,4 +103,4 @@ class Sonnum:
|
||||||
|
|
||||||
for src_node in src_nodes:
|
for src_node in src_nodes:
|
||||||
for trg_node in trg_nodes:
|
for trg_node in trg_nodes:
|
||||||
self.act('pin', 0, 0, src_node, trg_node, [src_pin, trg_pin])
|
self.act('feed', 0, 0, src_node, trg_node, [src_pin, trg_pin])
|
||||||
|
|
@ -21,6 +21,30 @@ class SoundNode:
|
||||||
def act(self, *args):
|
def act(self, *args):
|
||||||
self.c.add_activity(*args)
|
self.c.add_activity(*args)
|
||||||
|
|
||||||
|
def feed(self, trg_nodes, src_pin, trg_pin):
|
||||||
|
|
||||||
|
if not isinstance(trg_nodes, list):
|
||||||
|
trg_nodes = [trg_nodes]
|
||||||
|
|
||||||
|
for trg_node in trg_nodes:
|
||||||
|
self.act('feed', 0, 0, self, trg_node, [src_pin, trg_pin])
|
||||||
|
|
||||||
|
def wire(self, trg_nodes):
|
||||||
|
|
||||||
|
if not isinstance(trg_nodes, list):
|
||||||
|
trg_nodes = [trg_nodes]
|
||||||
|
|
||||||
|
for trg_node in trg_nodes:
|
||||||
|
self.act('feed', 0, 0, self, trg_node, [0, 0])
|
||||||
|
|
||||||
|
def air(self, trg_nodes):
|
||||||
|
|
||||||
|
if not isinstance(trg_nodes, list):
|
||||||
|
trg_nodes = [trg_nodes]
|
||||||
|
|
||||||
|
for trg_node in trg_nodes:
|
||||||
|
self.act('feed', 0, 0, self, trg_node, [0, 1])
|
||||||
|
|
||||||
def setpos(self, start_tick, x, y, z):
|
def setpos(self, start_tick, x, y, z):
|
||||||
self.act('setpos', start_tick, start_tick, self, None, [x, y, z])
|
self.act('setpos', start_tick, start_tick, self, None, [x, y, z])
|
||||||
|
|
||||||
|
|
@ -30,8 +54,8 @@ class SoundNode:
|
||||||
def printstate(self, start_tick, end_tick):
|
def printstate(self, start_tick, end_tick):
|
||||||
self.act('printstate', start_tick, end_tick, self, None, [])
|
self.act('printstate', start_tick, end_tick, self, None, [])
|
||||||
|
|
||||||
def bridge(self, start_tick, end_tick, in_pin, out_pin):
|
def copy(self, start_tick, end_tick, in_pin, out_pin):
|
||||||
self.act('bridge', start_tick, end_tick, self, None, [in_pin, out_pin])
|
self.act('copy', start_tick, end_tick, self, None, [in_pin, out_pin])
|
||||||
|
|
||||||
def sine(self, start_tick, end_tick, gainmult = 0.0):
|
def sine(self, start_tick, end_tick, gainmult = 0.0):
|
||||||
self.act('sine', start_tick, end_tick, self, None, [gainmult])
|
self.act('sine', start_tick, end_tick, self, None, [gainmult])
|
||||||
|
|
@ -51,44 +75,14 @@ class SoundNode:
|
||||||
def skewsine(self, start_tick, end_tick, gainmult = 0.0):
|
def skewsine(self, start_tick, end_tick, gainmult = 0.0):
|
||||||
self.act('skewsine', start_tick, end_tick, self, None, [gainmult])
|
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])
|
|
||||||
|
|
||||||
def slidegain(self, start_tick, end_tick, startgain, endgain):
|
|
||||||
self.act('slidegain', start_tick, end_tick, self, None, [startgain, endgain])
|
|
||||||
|
|
||||||
def slidephase(self, start_tick, end_tick, startphase, endphase):
|
|
||||||
self.act('slidephase', start_tick, end_tick, self, None, [startphase, endphase])
|
|
||||||
|
|
||||||
def slideskew(self, start_tick, end_tick, startskew, endskew):
|
|
||||||
self.act('slideskew', start_tick, end_tick, self, None, [startskew, endskew])
|
|
||||||
|
|
||||||
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, gainmult = 0.0):
|
def pulse(self, start_tick, end_tick, gainmult = 0.0):
|
||||||
self.act('pulse', start_tick, end_tick, self, None, [gainmult])
|
self.act('pulse', start_tick, end_tick, self, None, [gainmult])
|
||||||
|
|
||||||
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, [])
|
|
||||||
|
|
||||||
def mute(self, start_tick, end_tick):
|
def mute(self, start_tick, end_tick):
|
||||||
self.act('mute', start_tick, end_tick, self, None, [])
|
self.act('mute', start_tick, end_tick, self, None, [])
|
||||||
|
|
||||||
def whitenoise(self, start_tick, end_tick, gainmult = 0.0, seed = 0.259624856928):
|
def whitenoise(self, start_tick, end_tick, gainmult = 0.0, seed = 0.259624856928):
|
||||||
self.act('whitenoise', start_tick, end_tick, self, None, [seed, gainmult])
|
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):
|
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])
|
self.act('adsr', start_tick, end_tick, self, None, [attack_tick, hold_tick, decay_tick, sustain_tick, release_tick, gainmult])
|
||||||
|
|
@ -73,7 +73,7 @@ pub fn sawtooth(self: *Activity) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Produces a skewed sine wave to R_AMP pin
|
// Produces a skewed sine wave to R_AMP pin
|
||||||
// Skeweness factor is taken from OUT8 pin
|
// Skewness factor is taken from OUT8 pin
|
||||||
pub fn skewsine(self: *Activity) void {
|
pub fn skewsine(self: *Activity) void {
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
||||||
|
|
@ -126,3 +126,22 @@ pub fn pulse(self: *Activity) void {
|
||||||
self.soundnode.add_r_amp(final_amp);
|
self.soundnode.add_r_amp(final_amp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Whitenoise
|
||||||
|
// Seed is taken from OUT8
|
||||||
|
//
|
||||||
|
pub fn whitenoise(self: *Activity) void {
|
||||||
|
|
||||||
|
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
||||||
|
|
||||||
|
const seed = self.soundnode.out8;
|
||||||
|
const gain = self.soundnode.corrGain(self.operands[0]);
|
||||||
|
|
||||||
|
const w = (seed*current_tick) / math.sin(current_tick);
|
||||||
|
const amp = (2 * (w - @floor(w))) - 1;
|
||||||
|
|
||||||
|
const final_amp = gain * amp;
|
||||||
|
|
||||||
|
self.soundnode.fab.add_r_amp(final_amp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,8 @@ const dbg = utility.dbg;
|
||||||
const idbg = utility.idbg;
|
const idbg = utility.idbg;
|
||||||
|
|
||||||
|
|
||||||
// Produces a sine wave to r_amp pin
|
// Produces a sine wave (range N)
|
||||||
|
// y = M * sin(TF + P) + L
|
||||||
pub fn singenN(self: *Activity) void {
|
pub fn singenN(self: *Activity) void {
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
||||||
|
|
@ -17,10 +18,56 @@ pub fn singenN(self: *Activity) void {
|
||||||
const freq = self.operands[2];
|
const freq = self.operands[2];
|
||||||
const ylevel = self.operands[3];
|
const ylevel = self.operands[3];
|
||||||
|
|
||||||
const y = magnitude * math.sin(current_tick * freq + phase) + ylevel;
|
var y = magnitude * math.sin(current_tick * freq + phase) + ylevel;
|
||||||
|
|
||||||
|
if (y < 0) {
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
self.soundnode.basefreq = y;
|
self.soundnode.basefreq = y;
|
||||||
self.soundnode.out10 = y;
|
self.soundnode.out10 = y;
|
||||||
self.soundnode.out11 = y;
|
self.soundnode.out11 = y;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generates a linear ADSR envelope (range 0) to GAIN
|
||||||
|
// Takes attack gain from OUT8
|
||||||
|
// Takes sustain gain from OUT9
|
||||||
|
// Tick count starts from 0, as if start_tick was 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.out8;
|
||||||
|
const adsrsustain = self.soundnode.out9;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.soundnode.gain = gain;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ pub const Activity = struct {
|
||||||
switch (self.opcode) {
|
switch (self.opcode) {
|
||||||
|
|
||||||
4 => { self.relay(); },
|
4 => { self.relay(); },
|
||||||
5 => { self.bridge(); },
|
5 => { self.copy(); },
|
||||||
|
6 => { self.mute(); },
|
||||||
|
|
||||||
10 => { spatial.setpos(self); },
|
10 => { spatial.setpos(self); },
|
||||||
|
|
||||||
|
|
@ -48,8 +49,10 @@ pub const Activity = struct {
|
||||||
53 => { basicsynths.sawtooth(self); },
|
53 => { basicsynths.sawtooth(self); },
|
||||||
54 => { basicsynths.skewsine(self); },
|
54 => { basicsynths.skewsine(self); },
|
||||||
55 => { basicsynths.pulse(self); },
|
55 => { basicsynths.pulse(self); },
|
||||||
|
56 => { basicsynths.whitenoise(self); },
|
||||||
|
|
||||||
100 => { generators.singenN(self); },
|
100 => { generators.singenN(self); },
|
||||||
|
150 => { generators.adsr(self); },
|
||||||
|
|
||||||
else => {},
|
else => {},
|
||||||
|
|
||||||
|
|
@ -59,12 +62,12 @@ pub const Activity = struct {
|
||||||
|
|
||||||
pub fn relay(self: *Activity) void {
|
pub fn relay(self: *Activity) void {
|
||||||
|
|
||||||
self.soundnode.add_r_amp(self.soundnode.in_wire);
|
self.soundnode.add_r_amp(self.soundnode.in_wire * self.soundnode.gain);
|
||||||
self.soundnode.add_r_amp(self.soundnode.in_air);
|
self.soundnode.add_r_amp(self.soundnode.in_air * self.soundnode.gain);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bridge(self: *Activity) void {
|
pub fn copy(self: *Activity) void {
|
||||||
|
|
||||||
const in_pin: usize = @intFromFloat(self.operands[0]);
|
const in_pin: usize = @intFromFloat(self.operands[0]);
|
||||||
const out_pin: usize = @intFromFloat(self.operands[1]);
|
const out_pin: usize = @intFromFloat(self.operands[1]);
|
||||||
|
|
@ -119,6 +122,12 @@ pub const Activity = struct {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mute(self: *Activity) void {
|
||||||
|
|
||||||
|
self.soundnode.fab.set_r_amp(0);
|
||||||
|
self.soundnode.r_amp = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,16 @@ pub const FreqAmpBuffer = struct {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_r_amp(self: *FreqAmpBuffer, r_amp: f64) void {
|
||||||
|
|
||||||
|
self.fal_array[self.current_index] = r_amp;
|
||||||
|
|
||||||
|
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 add_r_amp(self: *FreqAmpBuffer, r_amp: f64) void {
|
pub fn add_r_amp(self: *FreqAmpBuffer, r_amp: f64) void {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue