pin and bridge renamed to feed and copy; added whitenoise, mute and adsr

This commit is contained in:
aprilnightk 2025-09-18 00:38:04 +03:00
parent 3ec8cd4704
commit f2868d8dcd
8 changed files with 144 additions and 72 deletions

View file

@ -1,19 +1,24 @@
s.setup(s.sec(10))
ln = s.sec(10)
s.setup(ln)
m = 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.pulse(0, s.sec(10))
n.printstate(30000, 30000)
n.printstate(30001, 30001)
n.skewsine(0, ln)
s.wire(n, s.left)
s.wire(n, s.right)

View file

@ -3,11 +3,12 @@ import struct
OPCODES = {
'create': 0,
'pin': 1,
'feed': 1,
'endtick': 2,
'setpin': 3,
'relay': 4,
'bridge': 5,
'copy': 5,
'mute': 6,
'printstate': 9,
'setpos': 10,
@ -18,24 +19,11 @@ OPCODES = {
'sawtooth': 53,
'skewsine': 54,
'pulse': 55,
'whitenoise': 55,
'singenN': 100,
'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,
'adsr': 150,
}
class Activity:

View file

@ -79,7 +79,7 @@ class Sonnum:
for src_node in src_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):
@ -91,9 +91,9 @@ class Sonnum:
for src_node in src_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):
src_nodes = [src_nodes]
@ -103,4 +103,4 @@ class Sonnum:
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])
self.act('feed', 0, 0, src_node, trg_node, [src_pin, trg_pin])

View file

@ -21,6 +21,30 @@ class SoundNode:
def act(self, *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):
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):
self.act('printstate', start_tick, end_tick, self, None, [])
def bridge(self, start_tick, end_tick, in_pin, out_pin):
self.act('bridge', start_tick, end_tick, self, None, [in_pin, out_pin])
def copy(self, start_tick, end_tick, 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):
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):
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):
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):
self.act('mute', start_tick, end_tick, self, None, [])
def whitenoise(self, start_tick, end_tick, gainmult = 0.0, seed = 0.259624856928):
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])

View file

@ -73,7 +73,7 @@ pub fn sawtooth(self: *Activity) void {
}
// 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 {
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);
}
// 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);
}

View file

@ -8,7 +8,8 @@ const dbg = utility.dbg;
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 {
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 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.out10 = 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;
}

View file

@ -38,7 +38,8 @@ pub const Activity = struct {
switch (self.opcode) {
4 => { self.relay(); },
5 => { self.bridge(); },
5 => { self.copy(); },
6 => { self.mute(); },
10 => { spatial.setpos(self); },
@ -48,8 +49,10 @@ pub const Activity = struct {
53 => { basicsynths.sawtooth(self); },
54 => { basicsynths.skewsine(self); },
55 => { basicsynths.pulse(self); },
56 => { basicsynths.whitenoise(self); },
100 => { generators.singenN(self); },
150 => { generators.adsr(self); },
else => {},
@ -59,12 +62,12 @@ pub const Activity = struct {
pub fn relay(self: *Activity) void {
self.soundnode.add_r_amp(self.soundnode.in_wire);
self.soundnode.add_r_amp(self.soundnode.in_air);
self.soundnode.add_r_amp(self.soundnode.in_wire * self.soundnode.gain);
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 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;
}

View file

@ -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 {