Compare commits
No commits in common. "89952cf8f672006a0b598f4985955b6bf5fbf4c0" and "a32d3a5da123c3695926a3b8cb421762bd5a0c96" have entirely different histories.
89952cf8f6
...
a32d3a5da1
16 changed files with 865 additions and 1063 deletions
|
|
@ -2,148 +2,84 @@ import random
|
||||||
|
|
||||||
class PianoString:
|
class PianoString:
|
||||||
|
|
||||||
def __init__(self, s, piano, notename, note_no, string_no):
|
def __init__(self, s, note, i):
|
||||||
|
|
||||||
self.s = s
|
self.s = s
|
||||||
self.piano = piano
|
|
||||||
self.note = notename
|
|
||||||
self.note_no = note_no
|
|
||||||
self.string_no = string_no
|
|
||||||
|
|
||||||
self.xshift = [-0.002, 0, 0.002][string_no]
|
|
||||||
self.x = (1/24.0)*note_no - 1.5 + self.xshift
|
|
||||||
|
|
||||||
if string_no == 1:
|
|
||||||
overtones = 10
|
|
||||||
else:
|
|
||||||
overtones = 8
|
|
||||||
|
|
||||||
self.node = self.s.node(overtones)
|
|
||||||
|
|
||||||
for reflector in self.piano.reflectors:
|
|
||||||
pass
|
|
||||||
#;self.node -> reflector
|
|
||||||
|
|
||||||
;0 self.node.@air_lr()
|
|
||||||
|
|
||||||
;0 self.node.setpos(self.x, 0, 0)
|
|
||||||
;0 self.node.@setgain(0.5)
|
|
||||||
|
|
||||||
fm_mod = self.piano.fm_mods[self.string_no]
|
|
||||||
;fm_mod:0 >> self.node:10
|
|
||||||
|
|
||||||
;0 self.node.setpin(40, 0.9)
|
|
||||||
;0 self.node.setpin(41, 0.4)
|
|
||||||
;0 self.node.setpin(35, 0.3)
|
|
||||||
|
|
||||||
for overtone in range(overtones):
|
|
||||||
|
|
||||||
;0 self.node.@setfreq(overtone, note(self.note)*(overtone+1))
|
|
||||||
;0 self.node.@setfreqgain(overtone, 0.1/(overtone**1.5+1))
|
|
||||||
|
|
||||||
def play_string(self, startsec, endsec, gainmult):
|
|
||||||
|
|
||||||
for overtone in range(0, 8):
|
|
||||||
ovfreq = note(self.note)*(overtone+1)
|
|
||||||
dispersion = (8-overtone) * 0.1
|
|
||||||
;startsec-endsec self.node:10:-1/1 ::> fp(overtone):ovfreq-dispersion/ovfreq+dispersion
|
|
||||||
|
|
||||||
attack = sec(0.05)
|
|
||||||
hold = sec(0.1)
|
|
||||||
decay = sec(0.5)
|
|
||||||
sustain = sec(endsec - startsec)
|
|
||||||
release = sec(endsec - startsec + 0.2)
|
|
||||||
|
|
||||||
;startsec-endsec+0.2 self.node.adsr(attack, hold, decay, sustain, release, gainmult)
|
|
||||||
|
|
||||||
|
|
||||||
#;startsec-endsec+0.2 self.node.sine(0.3)
|
|
||||||
#;startsec-endsec+0.2 self.node.skewsine(35, 0.1)
|
|
||||||
#;startsec-endsec+0.2 self.node.square(0.04)
|
|
||||||
#;startsec-endsec+0.2 self.node.triangle(0.4)
|
|
||||||
;startsec-endsec+0.2 self.node.residualsines(3, 0.00002)
|
|
||||||
|
|
||||||
class Piano:
|
|
||||||
|
|
||||||
def __init__(self, s):
|
|
||||||
|
|
||||||
self.s = s
|
|
||||||
|
|
||||||
notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#','G','G#','A','A#','B']
|
|
||||||
octaves = '3456'
|
|
||||||
|
|
||||||
gamma = []
|
|
||||||
|
|
||||||
for o in octaves:
|
|
||||||
for n in notes:
|
|
||||||
gamma.append(n+o)
|
|
||||||
|
|
||||||
self.fm_mods = []
|
|
||||||
|
|
||||||
self.reflectors = []
|
|
||||||
|
|
||||||
for i in range(0, 7):
|
|
||||||
|
|
||||||
self.reflectors.append(self.s.relay())
|
|
||||||
;0 self.reflectors[-1].@air_lr()
|
|
||||||
;0 self.reflectors[-1].@setgain(0.4)
|
|
||||||
;0 self.reflectors[-1].setpos(0,-1.1*i,-1.1*i)
|
|
||||||
|
|
||||||
for i in range(0,3):
|
|
||||||
|
|
||||||
fm_mod = self.s.node(1)
|
|
||||||
;0 fm_mod.@setfreq(0, 4*i)
|
|
||||||
;0-tick(self.s.end) fm_mod.sine()
|
|
||||||
|
|
||||||
self.fm_mods.append(fm_mod)
|
|
||||||
|
|
||||||
self.strings = dict() # {note: []}
|
|
||||||
|
|
||||||
for i in range(0, len(gamma)):
|
|
||||||
note = gamma[i]
|
|
||||||
|
|
||||||
self.strings[note] = []
|
|
||||||
self.strings[note].append(self.s.PianoString(s, self, note, i, 0))
|
|
||||||
self.strings[note].append(self.s.PianoString(s, self, note, i, 1))
|
|
||||||
self.strings[note].append(self.s.PianoString(s, self, note, i, 2))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_nodes(self, note):
|
|
||||||
|
|
||||||
if note in self.strings:
|
|
||||||
return self.strings[note]
|
|
||||||
|
|
||||||
def play(self, note, startsec, endsec, gainmult):
|
|
||||||
|
|
||||||
for node in self.get_nodes(note):
|
|
||||||
node.play_string(startsec, endsec, gainmult)
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
s.setup(8)
|
self.basefreq = self.s.note(note)
|
||||||
s.PianoString = PianoString
|
self.primary_gain = 0.4
|
||||||
|
|
||||||
|
self.mod = self.s.node()
|
||||||
|
self.node = self.s.node()
|
||||||
|
|
||||||
P = Piano(s)
|
self.node.setpos(0, -10.0+i, 0, 0)
|
||||||
|
|
||||||
|
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.node.fmsetup(0, self.basefreq, 0.009)
|
||||||
|
self.node.setskew(0, 0.3)
|
||||||
|
|
||||||
|
self.node.setadsrgain(0, 1)
|
||||||
|
self.node.setadsrsustain(0, 0.2)
|
||||||
|
|
||||||
if False:
|
self.s.wire(self.mod, self.node)
|
||||||
P.play("C4", 0, 7, 0.6)
|
self.s.air(self.node, [self.s.left, self.s.right])
|
||||||
else:
|
|
||||||
P.play("C4", 0, 2, 0.6)
|
def gain(self, starttick, gain):
|
||||||
|
|
||||||
|
self.node.setgain(starttick, gain)
|
||||||
|
|
||||||
|
def play(self, starttick, endtick):
|
||||||
|
|
||||||
|
keyhold_endtick = endtick
|
||||||
|
endtick += self.s.sec(0.3)
|
||||||
|
|
||||||
|
self.node.adsr(starttick, endtick,
|
||||||
|
self.s.sec(0.03),
|
||||||
|
self.s.sec(0.03),
|
||||||
|
self.s.sec(0.36),
|
||||||
|
keyhold_endtick - starttick,
|
||||||
|
keyhold_endtick - starttick + self.s.sec(0.3))
|
||||||
|
|
||||||
|
#self.mod.sine(starttick, endtick)
|
||||||
|
#self.node.fm(starttick, endtick)
|
||||||
|
self.node.sine(starttick, endtick, 0.2)
|
||||||
|
self.node.skewsine(starttick, endtick, 0.3)
|
||||||
|
self.node.square(starttick, endtick, 0.04)
|
||||||
|
|
||||||
|
self.node.adsr(starttick, endtick,
|
||||||
|
self.s.sec(0.067),
|
||||||
|
self.s.sec(0.07),
|
||||||
|
self.s.sec(0.09),
|
||||||
|
self.s.sec(0.1),
|
||||||
|
self.s.sec(0.2))
|
||||||
|
|
||||||
|
self.node.whitenoise(starttick, endtick, 0.01)
|
||||||
|
self.node.triangle(starttick, endtick, 0.2)
|
||||||
|
|
||||||
|
|
||||||
|
def playsec(self, start, end):
|
||||||
|
|
||||||
|
self.play(self.s.sec(start), self.s.sec(end))
|
||||||
|
|
||||||
|
|
||||||
|
notes = 'CDEFGAB'
|
||||||
|
octaves = '345'
|
||||||
|
|
||||||
|
gamma = []
|
||||||
|
|
||||||
|
for o in octaves:
|
||||||
|
for n in notes:
|
||||||
|
gamma.append(n+o)
|
||||||
|
s.setup(s.sec(60))
|
||||||
|
|
||||||
|
for i in range(0, len(gamma)):
|
||||||
|
note = gamma[i]
|
||||||
|
|
||||||
P.play("E4", 0.3, 2, 0.6)
|
S = PianoString(s, note, i)
|
||||||
P.play("G4", 0.6, 2, 0.6)
|
|
||||||
|
|
||||||
P.play("C4", 2, 3, 0.6)
|
S.playsec(i, i+1.4)
|
||||||
P.play("A4", 2, 3, 0.6)
|
|
||||||
P.play("F4", 2, 3, 0.6)
|
|
||||||
|
|
||||||
P.play("B3", 3, 4, 0.6)
|
|
||||||
P.play("G4", 3, 4, 0.6)
|
|
||||||
P.play("D4", 3, 4, 0.6)
|
|
||||||
|
|
||||||
P.play("C4", 4, 5, 0.6)
|
|
||||||
P.play("E4", 4, 5, 0.6)
|
|
||||||
P.play("A3", 4, 5, 0.6)
|
|
||||||
P.play("C5", 4, 5, 0.6)
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,9 @@
|
||||||
ln = s.sec(10)
|
s.setup(s.sec(10))
|
||||||
s.setup(ln)
|
|
||||||
|
|
||||||
m = s.node()
|
|
||||||
n = s.node()
|
n = s.node()
|
||||||
adsr = s.node()
|
|
||||||
|
|
||||||
adsr.setpin(0, OUT8, 0.9)
|
n.setpin(0, s.BASEFREQ, s.note("D4"))
|
||||||
adsr.setpin(0, OUT9, 0.4)
|
n.sine(0, s.sec(10))
|
||||||
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))
|
|
||||||
|
|
||||||
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.setpin(0, OUT8, 0.3)
|
|
||||||
n.skewsine(0, ln)
|
|
||||||
|
|
||||||
s.wire(n, s.left)
|
s.wire(n, s.left)
|
||||||
s.wire(n, s.right)
|
s.wire(n, s.right)
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
s.setup(10)
|
|
||||||
|
|
||||||
;0 s.left.@setgain(0.7)
|
|
||||||
;0 s.right.@setgain(0.7)
|
|
||||||
|
|
||||||
sn = s.node(1)
|
|
||||||
|
|
||||||
;0 sn.@setfreq(0, 4)
|
|
||||||
;0-10 sn.sine()
|
|
||||||
|
|
||||||
sn2 = s.node(3)
|
|
||||||
|
|
||||||
;sn:0 >> sn2:10
|
|
||||||
|
|
||||||
;0 sn2.@wire_lr()
|
|
||||||
;0 sn2.@setfreq(0, note("C4"))
|
|
||||||
;0 sn2.@setfreq(1,800)
|
|
||||||
|
|
||||||
;0-10 sn2:10:-1/1 ::> fp(0):note("A5")-10/note("A5")+10
|
|
||||||
;0-10 sn2:10:-1/1 ::> fp(0):note("E4")-10/note("E4")+10
|
|
||||||
;0-10 sn2:10:-1/1 ::> fp(1):note("C6")-10/note("C6")+10
|
|
||||||
|
|
||||||
;0 sn2.setpin(40, 0.9)
|
|
||||||
;0 sn2.setpin(41, 0.4)
|
|
||||||
|
|
||||||
;0-10 sn2:10:-1/1 ::> 35:0.1/0.9
|
|
||||||
;0-10 sn2.adsr(sec(0.1), sec(0.2), sec(0.3), sec(0.4), sec(0.5))
|
|
||||||
|
|
||||||
;0-10 sn2.triangle(0.4)
|
|
||||||
;0-10 sn2.sine(0.5)
|
|
||||||
;0-10 sn2.sawtooth(0.04)
|
|
||||||
;0-10 sn2.whitenoise(0.004)
|
|
||||||
|
|
@ -1,33 +1,38 @@
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
OPCODES = dict()
|
OPCODES = {
|
||||||
OPCODES['create'] = 0
|
|
||||||
OPCODES['endtick'] = 2
|
|
||||||
OPCODES['link'] = 1
|
|
||||||
OPCODES['setpin'] = 3
|
|
||||||
OPCODES['unlink'] = 8
|
|
||||||
OPCODES['printstate'] = 9
|
|
||||||
|
|
||||||
with open("zigsonnum/activity.zig", 'r') as zigfl:
|
|
||||||
|
|
||||||
zone = False
|
'create': 0,
|
||||||
for ln in zigfl.read().split('\n'):
|
'pin': 1,
|
||||||
|
'endtick': 2,
|
||||||
|
'setpin': 3,
|
||||||
|
'relay': 4,
|
||||||
|
|
||||||
|
'setpos': 10,
|
||||||
|
|
||||||
|
'sine': 50,
|
||||||
|
'triangle': 51,
|
||||||
|
|
||||||
if 'STARTOPCODES' in ln:
|
'square': 10,
|
||||||
zone = True
|
'sawtooth': 11,
|
||||||
|
'setskew': 12,
|
||||||
elif 'ENDOPCODES' in ln:
|
'skewsine': 14,
|
||||||
zone = False
|
'slidebasefreq': 15,
|
||||||
|
'slidegain': 16,
|
||||||
elif zone and '=>' in ln:
|
'slidephase': 17,
|
||||||
parts = ln.split('=>')
|
'slideskew': 18,
|
||||||
num = parts[0].strip()
|
'slidepos': 19,
|
||||||
name = parts[1].split('(')[0].split('.')[1]
|
'pulse': 20,
|
||||||
try:
|
'fmsetup': 21,
|
||||||
OPCODES[name] = int(num)
|
'fm': 22,
|
||||||
except:
|
'am': 23,
|
||||||
pass
|
'mute': 24,
|
||||||
|
'whitenoise': 25,
|
||||||
|
'setadsrgain': 26,
|
||||||
|
'setadsrsustain': 27,
|
||||||
|
'adsr': 28,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class Activity:
|
class Activity:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
from .sonnum import Sonnum
|
from .sonnum import Sonnum
|
||||||
from .activity import Activity
|
from .activity import Activity
|
||||||
from .soundnode import *
|
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SonnumCompiler:
|
class SonnumCompiler:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
@ -31,7 +28,8 @@ class SonnumCompiler:
|
||||||
self.activities.append(a)
|
self.activities.append(a)
|
||||||
|
|
||||||
def transpile_snm_to_py(self, snm_src):
|
def transpile_snm_to_py(self, snm_src):
|
||||||
|
return snm_src
|
||||||
|
|
||||||
py_src = []
|
py_src = []
|
||||||
|
|
||||||
for ln in snm_src.split('\n'):
|
for ln in snm_src.split('\n'):
|
||||||
|
|
@ -45,99 +43,59 @@ class SonnumCompiler:
|
||||||
|
|
||||||
if ln.startswith(';'):
|
if ln.startswith(';'):
|
||||||
|
|
||||||
if '=>' in ln:
|
if ln.endswith('*'):
|
||||||
|
|
||||||
|
name = self.sanitize_operand(ln[1:-1])
|
||||||
|
ln = f"i_create_simple(self, self.sonnum, '{name}')"
|
||||||
|
|
||||||
|
elif ln.endswith('!'):
|
||||||
|
|
||||||
|
ticklen = self.sanitize_operand(ln[1:-1])
|
||||||
|
ln = f"i_end_tick(self, self.sonnum, {ticklen})"
|
||||||
|
|
||||||
|
elif ln.endswith('@'):
|
||||||
|
|
||||||
|
name = self.sanitize_operand(ln[1:-1])
|
||||||
|
ln = f"i_create_relay(self, self.sonnum, '{name}')"
|
||||||
|
|
||||||
|
elif '=>' in ln:
|
||||||
name_src, name_trg = ln[1:].split('=>')
|
name_src, name_trg = ln[1:].split('=>')
|
||||||
ln = f'{name_src}.act("link", 0, 0, {name_src}, {name_trg}, [0, 1])'
|
ln = f"i_wire(self, self.sonnum, '{name_src}', '{name_trg}')"
|
||||||
|
|
||||||
elif '->' in ln:
|
elif '->' in ln:
|
||||||
|
|
||||||
name_src, name_trg = ln[1:].split('->')
|
name_src, name_trg = ln[1:].split('->')
|
||||||
ln = f'{name_src}.act("link", 0, 0, {name_src}, {name_trg}, [0, 2])'
|
ln = f"i_air(self, self.sonnum, '{name_src}', '{name_trg}')"
|
||||||
|
|
||||||
elif '=/>' in ln:
|
|
||||||
|
|
||||||
name_src, name_trg = ln[1:].split('=/>')
|
|
||||||
ln = f'{name_src}.act("unlink", 0, 0, {name_src}, {name_trg}, [0, 1])'
|
|
||||||
|
|
||||||
elif '-/>' in ln:
|
|
||||||
|
|
||||||
name_src, name_trg = ln[1:].split('-/>')
|
|
||||||
ln = f'{name_src}.act("unlink", 0, 0, {name_src}, {name_trg}, [0, 2])'
|
|
||||||
|
|
||||||
elif '>>' in ln:
|
|
||||||
|
|
||||||
name_src, name_trg = ln[1:].split('>>')
|
|
||||||
name_src, pin_src = name_src.split(':')
|
|
||||||
name_trg, pin_trg = name_trg.split(':')
|
|
||||||
ln = f'{name_src}.act("link", 0, 0, {name_src}, {name_trg}, [{pin_src}, {pin_trg}])'
|
|
||||||
|
|
||||||
elif '::>' in ln:
|
|
||||||
tickdata, cmd = ln[1:].split(' ',1)
|
|
||||||
|
|
||||||
if '-' in tickdata:
|
|
||||||
starttick, endtick = tickdata.split('-', 1)
|
|
||||||
else:
|
|
||||||
starttick = tickdata
|
|
||||||
endtick = starttick
|
|
||||||
name_src, name_trg = cmd.split('::>')
|
|
||||||
name_src, pin_src, rangepair_src = name_src.split(':')
|
|
||||||
pin_trg, rangepair_trg = name_trg.split(':')
|
|
||||||
from_src, from_trg = rangepair_src.split('/')
|
|
||||||
to_src, to_trg = rangepair_trg.split('/')
|
|
||||||
ln = f'{name_src}.act("rerange", sec({starttick}), sec({endtick}), {name_src}, {name_src}, [{pin_src}, {pin_trg}, {from_src}, {from_trg}, {to_src}, {to_trg}])'
|
|
||||||
|
|
||||||
elif ':>' in ln:
|
|
||||||
tickdata, cmd = ln[1:].split(' ',1)
|
|
||||||
|
|
||||||
if '-' in tickdata:
|
|
||||||
starttick, endtick = tickdata.split('-', 1)
|
|
||||||
else:
|
|
||||||
starttick = tickdata
|
|
||||||
endtick = starttick
|
|
||||||
name_src, pin_trg = cmd.split(':>')
|
|
||||||
name_src, pin_src = name_src.split(':')
|
|
||||||
ln = f'{name_src}.act("copy", sec({starttick}), sec({endtick}), {name_src}, None, [{pin_src}, {pin_trg}])'
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
ln = ln[1:]
|
if '; ' in ln:
|
||||||
tickdata, cmd = ln.split(' ',1)
|
|
||||||
|
tickdata, ln = ln[1:].split('; ',1)
|
||||||
if '-' in tickdata:
|
|
||||||
starttick, endtick = tickdata.split('-', 1)
|
if '-' in tickdata:
|
||||||
|
starttick, endtick = tickdata.split('-', 1)
|
||||||
|
else:
|
||||||
|
starttick = tickdata
|
||||||
|
endtick = starttick
|
||||||
|
|
||||||
|
starttick = self.sanitize_operand(starttick)
|
||||||
|
endtick = self.sanitize_operand(endtick)
|
||||||
|
|
||||||
|
lst = ln.split(' ')
|
||||||
|
src_node_name = lst.pop(0)
|
||||||
|
instr = lst.pop(0)
|
||||||
|
operands = [self.sanitize_operand(op) for op in lst]
|
||||||
|
ln = f"i_{instr}(self, self.sonnum, {starttick}, {endtick}, '{src_node_name}', "+', '.join(operands)+")"
|
||||||
else:
|
else:
|
||||||
starttick = tickdata
|
pass
|
||||||
endtick = starttick
|
|
||||||
|
|
||||||
cmdcore, cmdargs = cmd.split('(', 1)
|
|
||||||
cmdargs = cmdargs[:-1]
|
|
||||||
|
|
||||||
cmdparts = cmdcore.split('.')
|
|
||||||
operand = cmdparts.pop(-1)
|
|
||||||
nodenames = '.'.join(cmdparts)
|
|
||||||
print(operand, nodenames)
|
|
||||||
if '>' in nodenames:
|
|
||||||
src_nodename, trg_nodename = nodenames.split('>')
|
|
||||||
else:
|
|
||||||
src_nodename = nodenames
|
|
||||||
trg_nodename = nodenames
|
|
||||||
|
|
||||||
if operand.startswith('@'):
|
|
||||||
operand = operand[1:]
|
|
||||||
ln = f'{src_nodename}.{operand}(sec({starttick}), sec({endtick}), [{cmdargs}])'
|
|
||||||
|
|
||||||
else:
|
|
||||||
ln = f'{src_nodename}.act("{operand}", sec({starttick}), sec({endtick}), {src_nodename}, {trg_nodename}, [{cmdargs}])'
|
|
||||||
|
|
||||||
ln = tablevel*'\t' + ln
|
ln = tablevel*'\t' + ln
|
||||||
py_src.append(ln)
|
py_src.append(ln)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
ln = tablevel*'\t' + ln
|
ln = tablevel*'\t' + ln
|
||||||
py_src.append(ln)
|
py_src.append(ln)
|
||||||
|
|
||||||
print('\n'.join(py_src))
|
|
||||||
return '\n'.join(py_src)
|
return '\n'.join(py_src)
|
||||||
|
|
||||||
def run_transpiled_code(self, py_src):
|
def run_transpiled_code(self, py_src):
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,20 @@ from .soundnode import SoundNode
|
||||||
from .notes import *
|
from .notes import *
|
||||||
|
|
||||||
class Sonnum:
|
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):
|
def __init__(self, compiler):
|
||||||
|
|
||||||
self.c = compiler
|
self.c = compiler
|
||||||
|
|
@ -11,21 +24,19 @@ class Sonnum:
|
||||||
|
|
||||||
def setup(self, endtick):
|
def setup(self, endtick):
|
||||||
|
|
||||||
endtick = self.sec(endtick)
|
|
||||||
self.end = endtick
|
self.end = endtick
|
||||||
self.endtick(endtick)
|
self.endtick(endtick)
|
||||||
|
|
||||||
self.left = self.relay()
|
self.left = self.relay()
|
||||||
self.right = self.relay()
|
self.right = self.relay()
|
||||||
|
|
||||||
self.left.act("setpos", 0, 0, self.left, None, [-0.3, 0, 0])
|
self.left.setpos(0, -0.3, 0, 0)
|
||||||
self.right.act("setpos", 0, 0, self.right, None, [0.3, 0, 0])
|
self.right.setpos(0, 0.3, 0, 0)
|
||||||
|
|
||||||
def add_node(self, name, freq_q):
|
def add_node(self, name):
|
||||||
|
|
||||||
order = len(self.nodes)
|
order = len(self.nodes)
|
||||||
node = SoundNode(self, order, name)
|
node = SoundNode(self, order, name)
|
||||||
node.freq_q = freq_q
|
|
||||||
self.nodes.append(node)
|
self.nodes.append(node)
|
||||||
|
|
||||||
return node
|
return node
|
||||||
|
|
@ -45,11 +56,10 @@ class Sonnum:
|
||||||
def act(self, *args):
|
def act(self, *args):
|
||||||
self.c.add_activity(*args)
|
self.c.add_activity(*args)
|
||||||
|
|
||||||
def node(self, freq_q = 1):
|
def node(self):
|
||||||
|
|
||||||
node = self.add_node("", freq_q)
|
node = self.add_node("")
|
||||||
fakenode = SoundNode(self, freq_q, '')
|
self.act('create', 0, 0, node, None, [])
|
||||||
self.act('create', 0, 0, node, fakenode, [])
|
|
||||||
|
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
@ -61,7 +71,7 @@ class Sonnum:
|
||||||
|
|
||||||
def relay(self):
|
def relay(self):
|
||||||
|
|
||||||
node = self.add_node("", 0)
|
node = self.add_node("")
|
||||||
self.act('create', 0, 0, node, None, [])
|
self.act('create', 0, 0, node, None, [])
|
||||||
self.act('relay', 0, self.g('endtick'), node, None, [])
|
self.act('relay', 0, self.g('endtick'), node, None, [])
|
||||||
|
|
||||||
|
|
@ -82,7 +92,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('feed', 0, 0, src_node, trg_node, [0, 0])
|
self.act('pin', 0, 0, src_node, trg_node, [0, 0])
|
||||||
|
|
||||||
def air(self, src_nodes, trg_nodes):
|
def air(self, src_nodes, trg_nodes):
|
||||||
|
|
||||||
|
|
@ -94,9 +104,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('feed', 0, 0, src_node, trg_node, [0, 1])
|
self.act('pin', 0, 0, src_node, trg_node, [0, 1])
|
||||||
|
|
||||||
def feed(self, src_nodes, src_pin, trg_nodes, trg_pin):
|
def pin(self, src_nodes, trg_nodes, src_pin, trg_pin):
|
||||||
|
|
||||||
if not isinstance(src_nodes, list):
|
if not isinstance(src_nodes, list):
|
||||||
src_nodes = [src_nodes]
|
src_nodes = [src_nodes]
|
||||||
|
|
@ -106,4 +116,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('feed', 0, 0, src_node, trg_node, [src_pin, trg_pin])
|
self.act('pin', 0, 0, src_node, trg_node, [src_pin, trg_pin])
|
||||||
|
|
@ -1,41 +1,3 @@
|
||||||
from .notes import *
|
|
||||||
|
|
||||||
R_AMP = 0
|
|
||||||
WIRE_IN = 1
|
|
||||||
AIR_IN = 2
|
|
||||||
GAIN = 32
|
|
||||||
PHASE = 33
|
|
||||||
X = 61
|
|
||||||
Y = 62
|
|
||||||
Z = 63
|
|
||||||
|
|
||||||
def freqpin(freq_no):
|
|
||||||
return 64+freq_no
|
|
||||||
|
|
||||||
def gainpin(freq_no):
|
|
||||||
return 112+freq_no
|
|
||||||
|
|
||||||
def shiftpin(freq_no):
|
|
||||||
return 160+freq_no
|
|
||||||
|
|
||||||
def fp(freq_no):
|
|
||||||
return 64+freq_no
|
|
||||||
|
|
||||||
def gp(freq_no):
|
|
||||||
return 112+freq_no
|
|
||||||
|
|
||||||
def sp(freq_no):
|
|
||||||
return 160+freq_no
|
|
||||||
|
|
||||||
def sec(seconds):
|
|
||||||
return seconds * 44100
|
|
||||||
|
|
||||||
def note(note):
|
|
||||||
return note_to_freq(note)
|
|
||||||
|
|
||||||
def tick(ticks):
|
|
||||||
return ticks / 44100.0
|
|
||||||
|
|
||||||
class SoundNode:
|
class SoundNode:
|
||||||
|
|
||||||
def __init__(self, sonnum, order, name):
|
def __init__(self, sonnum, order, name):
|
||||||
|
|
@ -59,33 +21,65 @@ class SoundNode:
|
||||||
def act(self, *args):
|
def act(self, *args):
|
||||||
self.c.add_activity(*args)
|
self.c.add_activity(*args)
|
||||||
|
|
||||||
def wire_lr(self, *args):
|
def setpos(self, start_tick, x, y, z):
|
||||||
self.act("link", 0, 0, self, self.s.left, [0, 1])
|
self.act('setpos', start_tick, start_tick, self, None, [x, y, z])
|
||||||
self.act("link", 0, 0, self, self.s.right, [0, 1])
|
|
||||||
|
|
||||||
def air_lr(self, *args):
|
def setpin(self, start_tick, pin_no, value):
|
||||||
self.act("link", 0, 0, self, self.s.left, [0, 2])
|
self.act('setpin', start_tick, start_tick, self, None, [pin_no, value])
|
||||||
self.act("link", 0, 0, self, self.s.right, [0, 2])
|
|
||||||
|
|
||||||
def setfreq(self, starttick, endtick, args):
|
def sine(self, start_tick, end_tick, gainmult = 0.0):
|
||||||
freq_no = args[0]
|
self.act('sine', start_tick, end_tick, self, None, [gainmult])
|
||||||
freq = args[1]
|
|
||||||
self.act("setpin", starttick, endtick, self, None, [freqpin(freq_no), freq])
|
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, gainmult = 0.0):
|
||||||
|
self.act('square', start_tick, end_tick, self, None, [gainmult])
|
||||||
|
|
||||||
def setfreqgain(self, starttick, endtick, args):
|
def sawtooth(self, start_tick, end_tick, gainmult = 0.0):
|
||||||
freq_no = args[0]
|
self.act('sawtooth', start_tick, end_tick, self, None, [gainmult])
|
||||||
gain = args[1]
|
|
||||||
self.act("setpin", starttick, endtick, self, None, [gainpin(freq_no), gain])
|
|
||||||
|
|
||||||
def setfreqshift(self, starttick, endtick, args):
|
def skewsine(self, start_tick, end_tick, gainmult = 0.0):
|
||||||
freq_no = args[0]
|
self.act('skewsine', start_tick, end_tick, self, None, [gainmult])
|
||||||
shift = args[1]
|
|
||||||
self.act("setpin", starttick, endtick, self, None, [shiftpin(freq_no), shift])
|
def slidebasefreq(self, start_tick, end_tick, startfreq, endfreq):
|
||||||
|
self.act('slidebasefreq', start_tick, end_tick, self, None, [startfreq, endfreq])
|
||||||
|
|
||||||
def setgain(self, starttick, endtick, args):
|
def slidegain(self, start_tick, end_tick, startgain, endgain):
|
||||||
gain = args[0]
|
self.act('slidegain', start_tick, end_tick, self, None, [startgain, endgain])
|
||||||
self.act("setpin", starttick, endtick, self, None, [GAIN, gain])
|
|
||||||
|
|
||||||
def setphase(self, starttick, endtick, phase):
|
def slidephase(self, start_tick, end_tick, startphase, endphase):
|
||||||
phase = args[0]
|
self.act('slidephase', start_tick, end_tick, self, None, [startphase, endphase])
|
||||||
self.act("setpin", starttick, endtick, self, None, [PHASE, gain])
|
|
||||||
|
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])
|
||||||
|
|
@ -12,26 +12,12 @@ const idbg = utility.idbg;
|
||||||
pub fn sine(self: *Activity) void {
|
pub fn sine(self: *Activity) void {
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
||||||
const maingain = self.soundnode.corrGain(self.operands[0]);
|
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;
|
||||||
|
|
||||||
var final_amp: f64 = 0;
|
self.soundnode.add_r_amp(final_amp);
|
||||||
|
|
||||||
const max_freq_pin = 64 + self.soundnode.freq_q;
|
|
||||||
for (64..max_freq_pin) |freq_pin| {
|
|
||||||
|
|
||||||
if (self.soundnode.pins[freq_pin] > 0) {
|
|
||||||
const gain = self.soundnode.pins[freq_pin + 48];
|
|
||||||
const shift = self.soundnode.pins[freq_pin + 96];
|
|
||||||
const phase = self.soundnode.pins[freq_pin + 144];
|
|
||||||
|
|
||||||
const totalphase = self.soundnode.pins[33] + shift + phase;
|
|
||||||
|
|
||||||
const amp = math.sin(utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau);
|
|
||||||
final_amp += maingain * gain * amp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.soundnode.add_r_amp(final_amp);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,28 +25,15 @@ pub fn sine(self: *Activity) void {
|
||||||
pub fn triangle(self: *Activity) void {
|
pub fn triangle(self: *Activity) void {
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
||||||
const maingain = self.soundnode.corrGain(self.operands[0]);
|
|
||||||
|
|
||||||
var final_amp: f64 = 0;
|
|
||||||
|
|
||||||
const max_freq_pin = 64 + self.soundnode.freq_q;
|
|
||||||
for (64..max_freq_pin) |freq_pin| {
|
|
||||||
|
|
||||||
if (self.soundnode.pins[freq_pin] > 0) {
|
const gain = self.soundnode.corrGain(self.operands[0]);
|
||||||
const gain = self.soundnode.pins[freq_pin + 48];
|
|
||||||
const shift = self.soundnode.pins[freq_pin + 96];
|
|
||||||
const phase = self.soundnode.pins[freq_pin + 144];
|
|
||||||
|
|
||||||
const totalphase = self.soundnode.pins[33] + shift + phase;
|
|
||||||
|
|
||||||
const period = 44100 / self.soundnode.pins[freq_pin];
|
|
||||||
const tp = (current_tick - (period * totalphase)) / period;
|
|
||||||
|
|
||||||
const amp = @abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1;
|
|
||||||
final_amp += maingain * gain * amp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
self.soundnode.add_r_amp(final_amp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -69,31 +42,15 @@ pub fn triangle(self: *Activity) void {
|
||||||
pub fn square(self: *Activity) void {
|
pub fn square(self: *Activity) void {
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
||||||
const maingain = self.soundnode.corrGain(self.operands[0]);
|
|
||||||
|
|
||||||
var final_amp: f64 = 0;
|
const gain = self.soundnode.corrGain(self.operands[0]);
|
||||||
|
|
||||||
const max_freq_pin = 64 + self.soundnode.freq_q;
|
const sin = math.sin(utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau);
|
||||||
for (64..max_freq_pin) |freq_pin| {
|
|
||||||
|
|
||||||
if (self.soundnode.pins[freq_pin] > 0) {
|
|
||||||
const gain = self.soundnode.pins[freq_pin + 48];
|
|
||||||
const shift = self.soundnode.pins[freq_pin + 96];
|
|
||||||
const phase = self.soundnode.pins[freq_pin + 144];
|
|
||||||
|
|
||||||
const totalphase = self.soundnode.pins[33] + shift + phase;
|
|
||||||
|
|
||||||
const sin = math.sin(utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau);
|
|
||||||
|
|
||||||
if (sin > 0) {
|
|
||||||
final_amp += maingain * gain;
|
|
||||||
} else {
|
|
||||||
final_amp += -(maingain * gain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.soundnode.add_r_amp(final_amp);
|
|
||||||
|
|
||||||
|
if (sin > 0) {
|
||||||
|
self.soundnode.add_r_amp(gain);
|
||||||
|
} else {
|
||||||
|
self.soundnode.add_r_amp(-gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -102,171 +59,49 @@ pub fn square(self: *Activity) void {
|
||||||
pub fn sawtooth(self: *Activity) void {
|
pub fn sawtooth(self: *Activity) void {
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
||||||
const maingain = self.soundnode.corrGain(self.operands[0]);
|
|
||||||
|
|
||||||
var final_amp: f64 = 0;
|
|
||||||
|
|
||||||
const max_freq_pin = 64 + self.soundnode.freq_q;
|
|
||||||
for (64..max_freq_pin) |freq_pin| {
|
|
||||||
|
|
||||||
if (self.soundnode.pins[freq_pin] > 0) {
|
const gain = self.soundnode.corrGain(self.operands[0]);
|
||||||
const gain = self.soundnode.pins[freq_pin + 48];
|
|
||||||
const shift = self.soundnode.pins[freq_pin + 96];
|
|
||||||
const phase = self.soundnode.pins[freq_pin + 144];
|
|
||||||
|
|
||||||
const totalphase = self.soundnode.pins[33] + shift + phase;
|
|
||||||
|
|
||||||
const period = 44100 / self.soundnode.pins[freq_pin];
|
|
||||||
const tp = (current_tick - (period * totalphase)) / period;
|
|
||||||
|
|
||||||
const amp = 2 * (tp - @floor(0.5+tp));
|
|
||||||
final_amp += maingain * gain * amp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
self.soundnode.add_r_amp(final_amp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Produces a skewed sine wave to R_AMP pin
|
// Produces a skewed sine wave to R_AMP pin
|
||||||
// Operand 1 is pin number containing skewness factor
|
// Skeweness 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);
|
||||||
|
const gain = self.soundnode.corrGain(self.operands[0]);
|
||||||
|
|
||||||
const skew = self.soundnode.pins[@intFromFloat(self.operands[0])];
|
const skew = self.soundnode.out8;
|
||||||
const maingain = self.soundnode.corrGain(self.operands[1]);
|
var amp: f64 = 0;
|
||||||
|
|
||||||
var final_amp: f64 = 0;
|
if (skew == 0) {
|
||||||
|
|
||||||
const max_freq_pin = 64 + self.soundnode.freq_q;
|
amp = math.sin(utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau);
|
||||||
for (64..max_freq_pin) |freq_pin| {
|
|
||||||
|
} 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);
|
||||||
|
|
||||||
if (self.soundnode.pins[freq_pin] > 0) {
|
|
||||||
const gain = self.soundnode.pins[freq_pin + 48];
|
|
||||||
const shift = self.soundnode.pins[freq_pin + 96];
|
|
||||||
const phase = self.soundnode.pins[freq_pin + 144];
|
|
||||||
|
|
||||||
const totalphase = self.soundnode.pins[33] + shift + phase;
|
|
||||||
|
|
||||||
if (skew == 0) {
|
|
||||||
|
|
||||||
final_amp += maingain * gain * (math.sin(utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau));
|
|
||||||
|
|
||||||
} else if (skew > 0) {
|
|
||||||
|
|
||||||
const m = (utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau);
|
|
||||||
const sincos = skew * math.sin(m) / (1 - skew*math.cos(m));
|
|
||||||
final_amp += maingain * gain * (1/skew) * math.atan(sincos);
|
|
||||||
|
|
||||||
} else if (skew < 0) {
|
|
||||||
|
|
||||||
const m = (utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau);
|
|
||||||
const sincos = skew * math.cos(m) / (1 + skew*math.sin(m));
|
|
||||||
final_amp += maingain * gain * (1/skew) * math.atan(sincos);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const final_amp = gain * amp;
|
||||||
|
|
||||||
self.soundnode.add_r_amp(final_amp);
|
self.soundnode.add_r_amp(final_amp);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Produces a pulse wave to r_amp pin
|
|
||||||
// Operand 1 is pin number containing pulse shift
|
|
||||||
pub fn pulse(self: *Activity) void {
|
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
|
||||||
|
|
||||||
const pulse_shift = self.soundnode.pins[@intFromFloat(self.operands[0])];
|
|
||||||
const maingain = self.soundnode.corrGain(self.operands[1]);
|
|
||||||
|
|
||||||
var final_amp: f64 = 0;
|
|
||||||
|
|
||||||
const max_freq_pin = 64 + self.soundnode.freq_q;
|
|
||||||
for (64..max_freq_pin) |freq_pin| {
|
|
||||||
|
|
||||||
if (self.soundnode.pins[freq_pin] > 0) {
|
|
||||||
const gain = self.soundnode.pins[freq_pin + 48];
|
|
||||||
const shift = self.soundnode.pins[freq_pin + 96];
|
|
||||||
const phase = self.soundnode.pins[freq_pin + 114];
|
|
||||||
|
|
||||||
const totalphase = self.soundnode.pins[33] + shift + phase;
|
|
||||||
|
|
||||||
const period = 44100 / self.soundnode.pins[freq_pin];
|
|
||||||
const tp = (current_tick - (period * totalphase)) / period;
|
|
||||||
const tp_detract = (current_tick - (period * (pulse_shift + totalphase))) / period;
|
|
||||||
|
|
||||||
const amp = 2 * (tp - @floor(0.5 + tp));
|
|
||||||
const amp_detract = 2 * (tp_detract - @floor(0.5+tp_detract));
|
|
||||||
|
|
||||||
final_amp += maingain * gain * (amp - amp_detract);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.pins[@intFromFloat(self.operands[0])];
|
|
||||||
const maingain = self.soundnode.corrGain(self.operands[1]);
|
|
||||||
|
|
||||||
const w = (seed*current_tick) / math.sin(current_tick);
|
|
||||||
const amp = (2 * (w - @floor(w))) - 1;
|
|
||||||
|
|
||||||
const final_amp = maingain * amp;
|
|
||||||
|
|
||||||
self.soundnode.fab.add_r_amp(final_amp);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Produces a sine wave to r_amp pin
|
|
||||||
pub fn residualsines(self: *Activity) void {
|
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
|
||||||
const maingain = self.soundnode.corrGain(self.operands[1]);
|
|
||||||
|
|
||||||
const resolution: usize = @intFromFloat(self.operands[0]);
|
|
||||||
|
|
||||||
var final_amp: f64 = 0;
|
|
||||||
|
|
||||||
const max_freq_pin = 64 + self.soundnode.freq_q;
|
|
||||||
for (64..max_freq_pin) |freq_pin| {
|
|
||||||
|
|
||||||
if (self.soundnode.pins[freq_pin] > 0) {
|
|
||||||
|
|
||||||
const gain = self.soundnode.pins[freq_pin + 48];
|
|
||||||
const shift = self.soundnode.pins[freq_pin + 96];
|
|
||||||
const phase = self.soundnode.pins[freq_pin + 144];
|
|
||||||
|
|
||||||
const totalphase = self.soundnode.pins[33] + shift + phase;
|
|
||||||
|
|
||||||
for (0..resolution) |residual| {
|
|
||||||
|
|
||||||
const fresidual = @as(f64,@floatFromInt(residual))+1;
|
|
||||||
const res_gain = 1 / math.pow(f64, gain, fresidual);
|
|
||||||
|
|
||||||
var amp = math.sin(utility.corrected_tau * (self.soundnode.pins[freq_pin]-fresidual) * current_tick - totalphase * utility.tau);
|
|
||||||
|
|
||||||
final_amp += maingain * res_gain * amp;
|
|
||||||
|
|
||||||
|
|
||||||
amp = math.sin(utility.corrected_tau * (self.soundnode.pins[freq_pin]+fresidual) * current_tick - totalphase * utility.tau);
|
|
||||||
|
|
||||||
final_amp += maingain * res_gain * amp;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.soundnode.add_r_amp(final_amp);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
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 (range N)
|
|
||||||
// y = M * sin(TF + P) + L
|
|
||||||
pub fn singenN(self: *Activity) void {
|
|
||||||
|
|
||||||
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
|
||||||
const magnitude = self.operands[0];
|
|
||||||
const phase = self.operands[1];
|
|
||||||
const freq = self.operands[2];
|
|
||||||
const ylevel = self.operands[3];
|
|
||||||
|
|
||||||
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 pin 40
|
|
||||||
// Takes sustain gain from pin 41
|
|
||||||
// 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.pins[40];
|
|
||||||
var adsrsustain = self.soundnode.pins[41];
|
|
||||||
|
|
||||||
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;
|
|
||||||
adsrsustain *= 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.pins[32] = gain;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -9,9 +9,9 @@ const idbg = utility.idbg;
|
||||||
|
|
||||||
pub fn setpos(self: *Activity) void {
|
pub fn setpos(self: *Activity) void {
|
||||||
|
|
||||||
self.soundnode.pins[61] = @as(f32, @floatCast(self.operands[0]));
|
self.soundnode.x = @as(f32, @floatCast(self.operands[0]));
|
||||||
self.soundnode.pins[62] = @as(f32, @floatCast(self.operands[1]));
|
self.soundnode.y = @as(f32, @floatCast(self.operands[1]));
|
||||||
self.soundnode.pins[63] = @as(f32, @floatCast(self.operands[2]));
|
self.soundnode.z = @as(f32, @floatCast(self.operands[2]));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ const utility = @import("utility.zig");
|
||||||
|
|
||||||
const basicsynths = @import ("activities/basicsynths.zig");
|
const basicsynths = @import ("activities/basicsynths.zig");
|
||||||
const spatial = @import ("activities/spatial.zig");
|
const spatial = @import ("activities/spatial.zig");
|
||||||
const generators = @import ("activities/generators.zig");
|
|
||||||
|
|
||||||
pub const Activity = struct {
|
pub const Activity = struct {
|
||||||
|
|
||||||
|
|
@ -34,117 +33,20 @@ pub const Activity = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn do(self: *Activity) !void {
|
pub fn do(self: *Activity) !void {
|
||||||
|
|
||||||
switch (self.opcode) {
|
switch (self.opcode) {
|
||||||
//STARTOPCODES
|
|
||||||
4 => { self.relay(); },
|
4 => { self.relay(); },
|
||||||
5 => { self.copy(); },
|
|
||||||
6 => { self.mute(); },
|
|
||||||
7 => { self.rerange(); },
|
|
||||||
|
|
||||||
10 => { spatial.setpos(self); },
|
10 => { spatial.setpos(self); },
|
||||||
|
|
||||||
50 => { basicsynths.sine(self); },
|
50 => { basicsynths.sine(self); },
|
||||||
51 => { basicsynths.triangle(self); },
|
51 => { basicsynths.triangle(self); },
|
||||||
52 => { basicsynths.square(self); },
|
|
||||||
53 => { basicsynths.sawtooth(self); },
|
|
||||||
54 => { basicsynths.skewsine(self); },
|
|
||||||
55 => { basicsynths.pulse(self); },
|
|
||||||
56 => { basicsynths.whitenoise(self); },
|
|
||||||
57 => { basicsynths.residualsines(self); },
|
|
||||||
|
|
||||||
//100 => { generators.singenN(self); },
|
|
||||||
150 => { generators.adsr(self); },
|
|
||||||
//ENDOPCODES
|
|
||||||
else => {},
|
else => {},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relay(self: *Activity) void {
|
pub fn relay(self: *Activity) void {
|
||||||
|
|
||||||
self.soundnode.add_r_amp(self.soundnode.pins[1] * self.soundnode.pins[32]);
|
self.soundnode.add_r_amp(self.soundnode.in_wire);
|
||||||
self.soundnode.add_r_amp(self.soundnode.pins[2] * self.soundnode.pins[32]);
|
self.soundnode.add_r_amp(self.soundnode.in_air);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy(self: *Activity) void {
|
|
||||||
|
|
||||||
const from_pin: usize = @intFromFloat(self.operands[0]);
|
|
||||||
const to_pin: usize = @intFromFloat(self.operands[1]);
|
|
||||||
|
|
||||||
// Special case: setting freq results in setting calculating new phase too
|
|
||||||
if (to_pin >= 64 and to_pin < 112) {
|
|
||||||
|
|
||||||
const freq_no = to_pin - 64;
|
|
||||||
|
|
||||||
const fcurrent_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
|
||||||
const prevphase = self.soundnode.pins[208 + freq_no];
|
|
||||||
const prevfreq = self.soundnode.pins[to_pin];
|
|
||||||
|
|
||||||
const newfreq = self.soundnode.pins[from_pin];
|
|
||||||
self.soundnode.pins[to_pin] = newfreq;
|
|
||||||
|
|
||||||
const c = fcurrent_tick / 44100;
|
|
||||||
|
|
||||||
const pp = prevphase + c * (newfreq - prevfreq) + @floor(c * prevfreq - prevphase);
|
|
||||||
|
|
||||||
self.soundnode.pins[208 + freq_no] = pp - @floor(pp);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
self.soundnode.pins[to_pin] = self.soundnode.pins[from_pin];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rerange(self: *Activity) void {
|
|
||||||
|
|
||||||
const from_pin: usize = @intFromFloat(self.operands[0]);
|
|
||||||
const to_pin: usize = @intFromFloat(self.operands[1]);
|
|
||||||
|
|
||||||
const from_lo = self.operands[2];
|
|
||||||
const from_hi = self.operands[3];
|
|
||||||
const to_lo = self.operands[4];
|
|
||||||
const to_hi = self.operands[5];
|
|
||||||
|
|
||||||
// Special case: setting freq results in setting calculating new phase too
|
|
||||||
if (to_pin >= 64 and to_pin < 112) {
|
|
||||||
|
|
||||||
const freq_no = to_pin - 64;
|
|
||||||
|
|
||||||
const fcurrent_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
|
|
||||||
const prevphase = self.soundnode.pins[208 + freq_no];
|
|
||||||
const prevfreq = self.soundnode.pins[to_pin];
|
|
||||||
|
|
||||||
//const newfreq = self.soundnode.pins[from_pin];
|
|
||||||
|
|
||||||
const share = (self.soundnode.pins[from_pin] - from_lo) / (from_hi - from_lo);
|
|
||||||
const newfreq = to_lo + ((to_hi - to_lo) * share);
|
|
||||||
//print("ORIG {d} SHARE {d} NEWFREQ {d} ", .{self.soundnode.pins[from_pin], share, newfreq});
|
|
||||||
|
|
||||||
self.soundnode.pins[to_pin] = newfreq;
|
|
||||||
|
|
||||||
const c = fcurrent_tick / 44100;
|
|
||||||
const pp = prevphase + c * (newfreq - prevfreq) + @floor(c * prevfreq - prevphase);
|
|
||||||
|
|
||||||
//print("OLDPHASE {d} NEWPHASE {d} :: ", .{self.soundnode.pins[208 + freq_no], pp - @floor(pp)});
|
|
||||||
self.soundnode.pins[208 + freq_no] = pp - @floor(pp);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const share = (self.soundnode.pins[from_pin] - from_lo) / (from_hi - from_lo);
|
|
||||||
self.soundnode.pins[to_pin] = to_lo + ((to_hi - to_lo) * share);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mute(self: *Activity) void {
|
|
||||||
|
|
||||||
self.soundnode.fab.set_r_amp(0);
|
|
||||||
self.soundnode.pins[0] = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -43,16 +43,6 @@ 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 {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
const print = std.debug.print;
|
|
||||||
const SoundNode = @import("soundnode.zig").SoundNode;
|
|
||||||
const Allocator = std.mem.Allocator;
|
|
||||||
|
|
||||||
|
|
||||||
pub const Link = struct {
|
|
||||||
|
|
||||||
allocator: Allocator,
|
|
||||||
|
|
||||||
src_node: *SoundNode,
|
|
||||||
trg_node: *SoundNode,
|
|
||||||
|
|
||||||
src_pin: usize = 0,
|
|
||||||
trg_pin: usize = 0,
|
|
||||||
|
|
||||||
active: u8 = 0,
|
|
||||||
|
|
||||||
pub fn create(allocator: Allocator,
|
|
||||||
src_node: *SoundNode,
|
|
||||||
trg_node: *SoundNode,
|
|
||||||
src_pin: usize,
|
|
||||||
trg_pin: usize) !*Link {
|
|
||||||
|
|
||||||
const link = try allocator.create(Link);
|
|
||||||
|
|
||||||
link.* = .{
|
|
||||||
.allocator = allocator,
|
|
||||||
.src_node = src_node,
|
|
||||||
.trg_node = trg_node,
|
|
||||||
.src_pin = src_pin,
|
|
||||||
.trg_pin = trg_pin,
|
|
||||||
.active = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn propagate(self: *Link) void {
|
|
||||||
|
|
||||||
// Special case for air_in (pin 2)
|
|
||||||
if (self.trg_pin == 2) {
|
|
||||||
|
|
||||||
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));
|
|
||||||
self.trg_node.pins[2] += (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special case: setting freq results in setting calculating new phase too
|
|
||||||
} else if (self.trg_pin >= 64 and self.trg_pin < 112) {
|
|
||||||
|
|
||||||
const freq_no = self.trg_pin - 64;
|
|
||||||
|
|
||||||
const fcurrent_tick: f64 = @floatFromInt(self.src_node.fab.current_tick);
|
|
||||||
const prevphase = self.trg_node.pins[208 + freq_no];
|
|
||||||
const prevfreq = self.trg_node.pins[self.trg_pin];
|
|
||||||
|
|
||||||
const newfreq = self.src_node.pins[self.src_pin];
|
|
||||||
self.trg_node.pins[self.trg_pin] = newfreq;
|
|
||||||
|
|
||||||
const c = fcurrent_tick / 44100;
|
|
||||||
|
|
||||||
const pp = prevphase + c * (newfreq - prevfreq) + @floor(c * prevfreq - prevphase);
|
|
||||||
|
|
||||||
self.trg_node.pins[208 + freq_no] = pp - @floor(pp);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
self.trg_node.pins[self.trg_pin] += self.src_node.pins[self.src_pin];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
265
zigsonnum/pin.zig
Normal file
265
zigsonnum/pin.zig
Normal file
|
|
@ -0,0 +1,265 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const print = std.debug.print;
|
||||||
|
const SoundNode = @import("soundnode.zig").SoundNode;
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
|
||||||
|
pub const Pin = struct {
|
||||||
|
|
||||||
|
allocator: Allocator,
|
||||||
|
|
||||||
|
src_node: *SoundNode,
|
||||||
|
trg_node: *SoundNode,
|
||||||
|
|
||||||
|
src_pin: usize = 0,
|
||||||
|
trg_pin: usize = 0,
|
||||||
|
|
||||||
|
active: u8 = 0,
|
||||||
|
|
||||||
|
pub fn create(allocator: Allocator,
|
||||||
|
src_node: *SoundNode,
|
||||||
|
trg_node: *SoundNode,
|
||||||
|
src_pin: usize,
|
||||||
|
trg_pin: usize) !*Pin {
|
||||||
|
|
||||||
|
const pin = try allocator.create(Pin);
|
||||||
|
|
||||||
|
pin.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.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 => {},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -6,7 +6,7 @@ const ArrayList = std.ArrayList;
|
||||||
const Endian = std.builtin.Endian;
|
const Endian = std.builtin.Endian;
|
||||||
|
|
||||||
const SoundNode = @import("soundnode.zig").SoundNode;
|
const SoundNode = @import("soundnode.zig").SoundNode;
|
||||||
const Link = @import ("link.zig").Link;
|
const Pin = @import ("pin.zig").Pin;
|
||||||
const Activity = @import("activity.zig").Activity;
|
const Activity = @import("activity.zig").Activity;
|
||||||
const SoundSettings = @import("settings.zig").SoundSettings;
|
const SoundSettings = @import("settings.zig").SoundSettings;
|
||||||
const utility = @import("utility.zig");
|
const utility = @import("utility.zig");
|
||||||
|
|
@ -155,13 +155,10 @@ pub fn main() !void {
|
||||||
if (tick%44100 == 0) {
|
if (tick%44100 == 0) {
|
||||||
print("{d}-- ", .{tick/44100});
|
print("{d}-- ", .{tick/44100});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (a_soundnodes.items, 0..) |soundnode, i| {
|
|
||||||
//print("TICK {d} I {d} ", .{tick, i});
|
|
||||||
@memset(soundnode.pins[0..32], 0);
|
|
||||||
_ = i;
|
|
||||||
|
|
||||||
|
for (soundnodes.items, 0..) |soundnode, i| {
|
||||||
|
soundnode.nullizeStartTick();
|
||||||
|
_ = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tick == nextopcodetick) {
|
if (tick == nextopcodetick) {
|
||||||
|
|
@ -226,11 +223,7 @@ pub fn main() !void {
|
||||||
0 => {
|
0 => {
|
||||||
|
|
||||||
const uid: usize = @as(usize, src_node);
|
const uid: usize = @as(usize, src_node);
|
||||||
const freq_q: u8 = @truncate(trg_node);
|
const sn = try SoundNode.create(allocator, uid);
|
||||||
|
|
||||||
const sn = try SoundNode.create(allocator, uid, freq_q);
|
|
||||||
sn.pins[32]=1;
|
|
||||||
|
|
||||||
//print("Added node {s} at tick {d}\n", .{nodename, tick});
|
//print("Added node {s} at tick {d}\n", .{nodename, tick});
|
||||||
try soundnodes.append(sn);
|
try soundnodes.append(sn);
|
||||||
try p_soundnodes.append(sn);
|
try p_soundnodes.append(sn);
|
||||||
|
|
@ -245,8 +238,8 @@ pub fn main() !void {
|
||||||
const src_pin: usize = @intFromFloat(op1);
|
const src_pin: usize = @intFromFloat(op1);
|
||||||
const trg_pin: usize = @intFromFloat(op2);
|
const trg_pin: usize = @intFromFloat(op2);
|
||||||
|
|
||||||
const link = try Link.create(allocator, src, trg, src_pin, trg_pin);
|
const pin = try Pin.create(allocator, src, trg, src_pin, trg_pin);
|
||||||
try trg.links.append(link);
|
try trg.pins.append(pin);
|
||||||
},
|
},
|
||||||
|
|
||||||
2 => {
|
2 => {
|
||||||
|
|
@ -265,42 +258,26 @@ pub fn main() !void {
|
||||||
const sn = soundnodes.items[src_node];
|
const sn = soundnodes.items[src_node];
|
||||||
const sn_pin: usize = @intFromFloat(op1);
|
const sn_pin: usize = @intFromFloat(op1);
|
||||||
|
|
||||||
sn.pins[sn_pin] = op2;
|
switch (sn_pin) {
|
||||||
|
|
||||||
},
|
0 => { sn.r_amp = op2; },
|
||||||
|
1 => { sn.out1 = op2; },
|
||||||
9 => {
|
2 => { sn.gain = op2; },
|
||||||
|
3 => { sn.basephase = op2; },
|
||||||
const sn = soundnodes.items[src_node];
|
4 => { sn.phase = op2; },
|
||||||
sn.wantprint = true;
|
5 => { sn.basefreq = op2; },
|
||||||
|
6 => { sn.out6 = op2; },
|
||||||
},
|
7 => { sn.out7 = op2; },
|
||||||
|
8 => { sn.out8 = op2; },
|
||||||
8 => {
|
9 => { sn.out9 = op2; },
|
||||||
const src = soundnodes.items[src_node];
|
10 => { sn.out10 = op2; },
|
||||||
const trg = soundnodes.items[trg_node];
|
11 => { sn.out11 = op2; },
|
||||||
//print("Wired nodes at tick {d}\n", .{tick});
|
else => {},
|
||||||
|
|
||||||
const src_pin: usize = @intFromFloat(op1);
|
|
||||||
const trg_pin: usize = @intFromFloat(op2);
|
|
||||||
|
|
||||||
var found: bool = false;
|
|
||||||
var toremove: u64 = 0;
|
|
||||||
|
|
||||||
for (trg.links.items, 0..) |link, j| {
|
|
||||||
if (link.src_node == src and link.trg_node == trg and link.src_pin == src_pin and link.trg_pin == trg_pin) {
|
|
||||||
toremove = j;
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
|
||||||
_ = trg.links.orderedRemove(toremove);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
else => {
|
else => {
|
||||||
|
|
||||||
const soundnode = soundnodes.items[src_node];
|
const soundnode = soundnodes.items[src_node];
|
||||||
|
|
@ -310,10 +287,9 @@ pub fn main() !void {
|
||||||
try soundnode.activities.append(a);
|
try soundnode.activities.append(a);
|
||||||
|
|
||||||
if (soundnode.activities.items.len == 1 and soundnode.active == 0) {
|
if (soundnode.activities.items.len == 1 and soundnode.active == 0) {
|
||||||
|
|
||||||
soundnode.active = 1;
|
soundnode.active = 1;
|
||||||
try reactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode);
|
try reactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
@ -325,65 +301,55 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//All but left and right
|
//All but left and right
|
||||||
|
|
||||||
var iter: usize = 1;
|
if (a_soundnodes.items.len > 2) {
|
||||||
//while (iter < 0) {
|
|
||||||
|
|
||||||
while (iter < a_soundnodes.items.len - 1) {
|
|
||||||
|
|
||||||
iter += 1;
|
for (a_soundnodes.items[2..], 0..) |soundnode, i| {
|
||||||
const soundnode = a_soundnodes.items[iter];
|
|
||||||
|
for (soundnode.pins.items, 0..) |pin, j| {
|
||||||
|
|
||||||
|
if (pin.src_node.active == 1 or pin.trg_pin == 1) {
|
||||||
|
pin.propagate();
|
||||||
|
}
|
||||||
|
_ = 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.links.items, 0..) |link, j| {
|
_ = soundnode.activities.swapRemove(activity_ind);
|
||||||
|
|
||||||
if (link.src_node.active == 1 or link.trg_pin == 1) {
|
if (soundnode.activities.items.len == 0 and soundnode.active == 1) {
|
||||||
link.propagate();
|
|
||||||
|
|
||||||
}
|
|
||||||
_ = 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (soundnode.wantprint == true) {
|
|
||||||
soundnode.wantprint = false;
|
|
||||||
soundnode.printState();
|
|
||||||
}
|
|
||||||
|
|
||||||
var j: usize = toremove.items.len;
|
|
||||||
|
|
||||||
if (j == 0) {
|
|
||||||
soundnode.fab.increment_tick();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (j > 0) {
|
|
||||||
|
|
||||||
j -= 1;
|
|
||||||
const activity_ind = toremove.items[j];
|
|
||||||
|
|
||||||
_ = soundnode.activities.swapRemove(activity_ind);
|
soundnode.active = 0;
|
||||||
|
try deactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode);
|
||||||
if (soundnode.activities.items.len == 0 and soundnode.active == 1) {
|
|
||||||
|
}
|
||||||
soundnode.active = 0;
|
|
||||||
try deactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode);
|
|
||||||
|
|
||||||
//print("DEACTIVATING {d} AT TICK {d} ", .{soundnode.uid, tick});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
soundnode.fab.increment_tick();
|
||||||
|
_ = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incrementing passive ones too
|
// Incrementing passive ones too
|
||||||
|
|
@ -391,22 +357,15 @@ pub fn main() !void {
|
||||||
for (p_soundnodes.items, 0..) |soundnode, i| {
|
for (p_soundnodes.items, 0..) |soundnode, i| {
|
||||||
soundnode.fab.increment_tick();
|
soundnode.fab.increment_tick();
|
||||||
_ = i;
|
_ = i;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Left and right
|
//Left and right
|
||||||
|
|
||||||
iter = 0;
|
for (soundnodes.items[0..2], 0..) |soundnode, i| {
|
||||||
|
|
||||||
//while (iter < 0) {
|
for (soundnode.pins.items, 0..) |pin, jz| {
|
||||||
while (iter < 2) {
|
if (pin.src_node.active == 1 or pin.trg_pin == 1) {
|
||||||
|
pin.propagate();
|
||||||
const soundnode = soundnodes.items[iter];
|
|
||||||
iter += 1;
|
|
||||||
|
|
||||||
for (soundnode.links.items, 0..) |link, jz| {
|
|
||||||
if (link.src_node.active == 1 or link.trg_pin == 1) {
|
|
||||||
link.propagate();
|
|
||||||
}
|
}
|
||||||
_ = jz;
|
_ = jz;
|
||||||
}
|
}
|
||||||
|
|
@ -424,11 +383,6 @@ pub fn main() !void {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (soundnode.wantprint == true) {
|
|
||||||
soundnode.wantprint = false;
|
|
||||||
soundnode.printState();
|
|
||||||
}
|
|
||||||
|
|
||||||
var j: usize = toremove.items.len;
|
var j: usize = toremove.items.len;
|
||||||
|
|
||||||
while (j > 0) {
|
while (j > 0) {
|
||||||
|
|
@ -437,44 +391,26 @@ pub fn main() !void {
|
||||||
_ = soundnode.activities.swapRemove(activity_ind);
|
_ = soundnode.activities.swapRemove(activity_ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Calculating and writing output amps
|
//Calculating and writing output amps
|
||||||
|
|
||||||
left = soundnodes.items[0];
|
left = soundnodes.items[0];
|
||||||
right = soundnodes.items[1];
|
right = soundnodes.items[1];
|
||||||
|
|
||||||
var left_r_amp = left.pins[0];
|
sample = @intFromFloat(left.r_amp * settings.max_amp_multiplier);
|
||||||
|
|
||||||
if (left_r_amp > 1) {
|
|
||||||
left_r_amp = 1;
|
|
||||||
} else if (left_r_amp < -1) {
|
|
||||||
left_r_amp = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sample = @intFromFloat(left_r_amp * settings.max_amp_multiplier);
|
|
||||||
try stdout.writeInt(i24, sample, Endian.little);
|
try stdout.writeInt(i24, sample, Endian.little);
|
||||||
|
|
||||||
var right_r_amp = right.pins[0];
|
sample = @intFromFloat(right.r_amp * settings.max_amp_multiplier);
|
||||||
|
|
||||||
if (right_r_amp > 1) {
|
|
||||||
right_r_amp = 1;
|
|
||||||
} else if (right_r_amp < -1) {
|
|
||||||
right_r_amp = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sample = @intFromFloat(right_r_amp * settings.max_amp_multiplier);
|
|
||||||
try stdout.writeInt(i24, sample, Endian.little);
|
try stdout.writeInt(i24, sample, Endian.little);
|
||||||
|
|
||||||
left.fab.current_tick += 1;
|
left.fab.current_tick += 1;
|
||||||
right.fab.current_tick += 1;
|
right.fab.current_tick += 1;
|
||||||
|
|
||||||
|
|
||||||
tick += 1;
|
tick += 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try bw.flush();
|
try bw.flush();
|
||||||
print("\n", .{});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ const StringHashMap = std.StringHashMap;
|
||||||
|
|
||||||
const pnt = @import("point.zig");
|
const pnt = @import("point.zig");
|
||||||
const Pnt = pnt.Pnt;
|
const Pnt = pnt.Pnt;
|
||||||
const Link = @import("link.zig").Link;
|
const Pin = @import("pin.zig").Pin;
|
||||||
const Activity = @import("activity.zig").Activity;
|
const Activity = @import("activity.zig").Activity;
|
||||||
const SoundSettings = @import("settings.zig").SoundSettings;
|
const SoundSettings = @import("settings.zig").SoundSettings;
|
||||||
const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer;
|
const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer;
|
||||||
|
|
@ -24,73 +24,127 @@ pub const SoundNode = struct {
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
|
|
||||||
uid: usize = 0,
|
uid: usize = 0,
|
||||||
freq_q: u8,
|
|
||||||
|
|
||||||
pins: [256]f64,
|
// 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),
|
activities: ArrayList(*Activity),
|
||||||
links: ArrayList(*Link),
|
pins: ArrayList(*Pin),
|
||||||
|
|
||||||
props: StringHashMap(f64),
|
props: StringHashMap(f64),
|
||||||
|
|
||||||
wantprint: bool = false,
|
x: f32 = 0,
|
||||||
|
y: f32 = 0,
|
||||||
|
z: f32 = 0,
|
||||||
|
|
||||||
fab: FreqAmpBuffer,
|
fab: FreqAmpBuffer,
|
||||||
active: u8 = 0,
|
active: u8 = 1,
|
||||||
|
|
||||||
|
pub fn nullizeStartTick(self: *SoundNode) void {
|
||||||
pub fn create(allocator: Allocator, uid: usize, freq_q: u8) !*SoundNode {
|
|
||||||
|
|
||||||
const activities = ArrayList(*Activity).init(allocator);
|
|
||||||
const links = ArrayList(*Link).init(allocator);
|
|
||||||
const fab = FreqAmpBuffer{};
|
|
||||||
const props = StringHashMap(f64).init(allocator);
|
|
||||||
|
|
||||||
const sn = try allocator.create(SoundNode);
|
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;
|
||||||
sn.* = .{
|
|
||||||
.uid = uid,
|
|
||||||
.freq_q = freq_q,
|
|
||||||
|
|
||||||
.pins = std.mem.zeroes([256]f64),
|
|
||||||
|
|
||||||
.allocator = allocator,
|
|
||||||
|
|
||||||
.activities = activities,
|
|
||||||
.links = links,
|
|
||||||
.fab = fab,
|
|
||||||
.props = props,
|
|
||||||
|
|
||||||
.wantprint = false,
|
|
||||||
.active = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
//Gain and per-freq gains must be initialized as 1
|
|
||||||
sn.pins[32] = 1;
|
|
||||||
@memset(sn.pins[112..160], 1);
|
|
||||||
|
|
||||||
return sn;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn printState(self: *SoundNode) void {
|
|
||||||
const fcurrent_tick: f64 = @floatFromInt(self.current_tick());
|
|
||||||
|
|
||||||
print("\n===SOUNDNODE {d} TICK {d} SECOND {d}===\n", .{self.uid, fcurrent_tick, fcurrent_tick/44100});
|
|
||||||
|
|
||||||
print("======================\n", .{});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn corrGain(self: *SoundNode, gainmult: f64) f64 {
|
pub fn corrGain(self: *SoundNode, gainmult: f64) f64 {
|
||||||
|
|
||||||
if (gainmult > 0) {
|
if (gainmult > 0) {
|
||||||
return self.pins[32] * gainmult;
|
return self.gain * gainmult;
|
||||||
} else {
|
} else {
|
||||||
return self.pins[32];
|
return self.gain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = 1,
|
||||||
|
.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 {
|
pub fn deinit(self: *SoundNode) void {
|
||||||
|
|
||||||
|
|
@ -109,7 +163,7 @@ pub const SoundNode = struct {
|
||||||
pub fn add_r_amp(self: *SoundNode, r_amp: f64) void {
|
pub fn add_r_amp(self: *SoundNode, r_amp: f64) void {
|
||||||
|
|
||||||
self.fab.add_r_amp(r_amp);
|
self.fab.add_r_amp(r_amp);
|
||||||
self.pins[0] += r_amp;
|
self.r_amp += r_amp;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,13 +186,143 @@ pub const SoundNode = struct {
|
||||||
|
|
||||||
pub fn distance(self: *SoundNode, other: *SoundNode) f64 {
|
pub fn distance(self: *SoundNode, other: *SoundNode) f64 {
|
||||||
|
|
||||||
if ((self.pins[61] == other.pins[61]) and (self.pins[62] == other.pins[62]) and (self.pins[63] == other.pins[63])) {
|
if ((self.x == other.x) and (self.y == other.y) and (self.z == other.z)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dx = self.pins[61] - other.pins[61];
|
const dx: f32 = self.x - other.x;
|
||||||
const dy = self.pins[62] - other.pins[62];
|
const dy: f32 = self.y - other.y;
|
||||||
const dz = self.pins[63] - other.pins[63];
|
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,
|
||||||
|
|
||||||
|
air_in: ArrayList(*SoundNode),
|
||||||
|
wire_in: ArrayList(*SoundNode),
|
||||||
|
|
||||||
|
air_targets: ArrayList(*SoundNode),
|
||||||
|
wire_targets: ArrayList(*SoundNode),
|
||||||
|
|
||||||
|
activities: ArrayList(*Activity),
|
||||||
|
props: StringHashMap(f64),
|
||||||
|
|
||||||
|
x: f32 = 0,
|
||||||
|
y: f32 = 0,
|
||||||
|
z: f32 = 0,
|
||||||
|
|
||||||
|
fab: FreqAmpBuffer,
|
||||||
|
active: u8 = 1,
|
||||||
|
|
||||||
|
pub fn create(allocator: Allocator, name: []const u8, uid: usize) !*SoundNode {
|
||||||
|
|
||||||
|
const air_in = ArrayList(*SoundNode).init(allocator);
|
||||||
|
const wire_in = ArrayList(*SoundNode).init(allocator);
|
||||||
|
const air_targets = ArrayList(*SoundNode).init(allocator);
|
||||||
|
const wire_targets = ArrayList(*SoundNode).init(allocator);
|
||||||
|
const activities = ArrayList(*Activity).init(allocator);
|
||||||
|
const fab = FreqAmpBuffer{};
|
||||||
|
const props = StringHashMap(f64).init(allocator);
|
||||||
|
|
||||||
|
const sn = try allocator.create(SoundNode);
|
||||||
|
|
||||||
|
sn.* = .{
|
||||||
|
.uid = uid,
|
||||||
|
.allocator = allocator,
|
||||||
|
.name = name,
|
||||||
|
.air_in = air_in,
|
||||||
|
.wire_in = wire_in,
|
||||||
|
.air_targets = air_targets,
|
||||||
|
.wire_targets = wire_targets,
|
||||||
|
.activities = activities,
|
||||||
|
.fab = fab,
|
||||||
|
.props = props,
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.z = 0,
|
||||||
|
.active = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
return sn;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(allocator: Allocator, name: []const u8) !SoundNode {
|
||||||
|
|
||||||
|
const air_in = ArrayList(*SoundNode).init(allocator);
|
||||||
|
const wire_in = ArrayList(*SoundNode).init(allocator);
|
||||||
|
const activities = ArrayList(*Activity).init(allocator);
|
||||||
|
const fab = try FreqAmpBuffer.init(allocator);
|
||||||
|
const props = StringHashMap(f64).init(allocator);
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.name = name,
|
||||||
|
.air_in = air_in,
|
||||||
|
.wire_in = wire_in,
|
||||||
|
.activities = activities,
|
||||||
|
.fab = fab,
|
||||||
|
.props = props,
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.z = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *SoundNode) void {
|
||||||
|
|
||||||
|
self.air_in.deinit();
|
||||||
|
self.wire_in.deinit();
|
||||||
|
self.activities.deinit();
|
||||||
|
self.fab.deinit();
|
||||||
|
self.props.deinit();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current_tick(self: *SoundNode) u32 {
|
||||||
|
|
||||||
|
return self.fab.current_tick;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
return math.sqrt(dx*dx + dy*dy + dz*dz);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue