From bf01f2efce3313c541c80f51fa8d91f9b68a41c2 Mon Sep 17 00:00:00 2001 From: aprilnightk Date: Thu, 11 Sep 2025 11:20:28 +0300 Subject: [PATCH] actually working version, but too slow to be good --- .gitignore | 1 + disttest.py | 40 ---- pysonnum/activity.py | 20 +- pysonnum/compiler.py | 60 +++--- pysonnum/instruction.py | 46 ++++- sintest.py | 43 ----- snm.py | 49 +++++ test.py | 41 ----- zigsonnum/activity.zig | 91 +++++++-- zigsonnum/freqamp.zig | 18 +- zigsonnum/point.zig | 2 +- zigsonnum/sonnum.zig | 397 +++++++++++++--------------------------- zigsonnum/soundnode.zig | 2 +- zigsonnum/testtest.zig | 58 ------ 14 files changed, 351 insertions(+), 517 deletions(-) delete mode 100644 disttest.py delete mode 100644 sintest.py create mode 100644 snm.py delete mode 100644 test.py delete mode 100644 zigsonnum/testtest.zig diff --git a/.gitignore b/.gitignore index 9896dfb..fd6700b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ err.txt log.txt t*.html *.kdev4 +*.o .kdev4/ HTML/ PDF/ diff --git a/disttest.py b/disttest.py deleted file mode 100644 index 2b858fb..0000000 --- a/disttest.py +++ /dev/null @@ -1,40 +0,0 @@ -from random import randint -import numpy as np - -def dist1(loc, other_loc): - return (loc[0]-other_loc[0])**2 + (loc[1]-other_loc[1])**2 + (loc[2]-other_loc[2])**2 - -def yield_pts(n): - - for i in range(0,n): - p1 = (10000-randint(0,20000), 10000-randint(0,20000), 10000-randint(0,20000)) - p2 = (10000-randint(0,20000), 10000-randint(0,20000), 10000-randint(0,20000)) - - yield p1, p2 - - -def native(ptlst): - return [dist1(p[0], p[1]) for p in ptlst] - -def fast(x1s, y1s, z1s, x2s, y2s, z2s): - - p1 = np.array([x1s, y1s, z1s]) - p2 = np.array([x2s, y2s, z2s]) - - squared_dist = np.sum((p1-p2)**2, axis=0) - return np.sqrt(squared_dist) - -import cProfile - -ptlst = [(p1, p2) for (p1, p2) in yield_pts(41000*5*10)] -cProfile.runctx("native(ptlst)", globals(), locals()) - - -n=41000*5*10 -x1s = [10000-randint(0,20000) for i in range(0, n)] -y1s = [10000-randint(0,20000) for i in range(0, n)] -z1s = [10000-randint(0,20000) for i in range(0, n)] -x2s = [10000-randint(0,20000) for i in range(0, n)] -y2s = [10000-randint(0,20000) for i in range(0, n)] -z2s = [10000-randint(0,20000) for i in range(0, n)] -cProfile.runctx("fast(x1s, y1s, z1s, x2s, y2s, z2s)", globals(), locals()) \ No newline at end of file diff --git a/pysonnum/activity.py b/pysonnum/activity.py index f6c50d0..4fedebd 100644 --- a/pysonnum/activity.py +++ b/pysonnum/activity.py @@ -1,23 +1,11 @@ import struct +from .instruction import OPCODES class Activity: - OPCODES = { - - 'create': 0, - 'wire': 1, - 'air': 2, - 'endtick': 3, - 'relay': 4, - 'reset': 5, - 'setfreq': 6, - 'setpos': 7, - - } - def __repr__(self): - return f'{self.name.rjust(20)} | {self.OPCODES[self.name]} {self.tick_start} {self.tick_end} {self.src_node.order if self.src_node else 0} {self.trg_node.order if self.trg_node else 0} '+' '.join(str(op) for op in self.operands) + return f'{self.name.rjust(20)} | {OPCODES[self.name]} {self.tick_start} {self.tick_end} {self.src_node.order if self.src_node else 0} {self.trg_node.order if self.trg_node else 0} '+' '.join(str(op) for op in self.operands) def __init__(self, sonnum, name, tick_start, tick_end, src_node, trg_node, operands): @@ -32,9 +20,9 @@ class Activity: def to_bytes(self): - if self.name in self.OPCODES: + if self.name in OPCODES: - b_opcode = self.OPCODES[self.name].to_bytes(2, byteorder="big") + b_opcode = OPCODES[self.name].to_bytes(2, byteorder="big") b_tick_start = int(self.tick_start).to_bytes(4, byteorder="big") b_tick_end = int(self.tick_end).to_bytes(4, byteorder="big") diff --git a/pysonnum/compiler.py b/pysonnum/compiler.py index ea10824..804faa9 100644 --- a/pysonnum/compiler.py +++ b/pysonnum/compiler.py @@ -1,6 +1,6 @@ -from sonnum import Sonnum -from activity import Activity -from instruction import * +from .sonnum import Sonnum +from .activity import Activity +from .instruction import * class SonnumCompiler: @@ -28,7 +28,11 @@ class SonnumCompiler: self.activities.append(a) def sanitize_operand(self, operand): - + + if operand.endswith('~sec'): + sec = operand[:-4] + return f'{sec}*44100' + try: return str(float(operand)) except: @@ -56,9 +60,14 @@ class SonnumCompiler: elif ln.endswith('!'): - ticklen = int(ln[1:-1]) + ticklen = self.sanitize_operand(ln[1:-1]) ln = f"i_end_tick(self, self.sonnum, {ticklen})" + elif ln.endswith('@@'): + + name = ln[1:-2] + ln = f"i_create_accumulate(self, self.sonnum, '{name}')" + elif ln.endswith('@'): name = ln[1:-1] @@ -73,13 +82,28 @@ class SonnumCompiler: ln = f"i_air(self, self.sonnum, '{name_src}', '{name_trg}')" else: - print(ln) - lst = ln[1:].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, '{src_node_name}', "+', '.join(operands)+")" + if '; ' in ln: + + tickdata, ln = ln[1:].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: + pass + ln = tablevel*'\t' + ln py_src.append(ln) @@ -146,16 +170,6 @@ class SonnumCompiler: with open(fn, 'wb') as fl: fl.write(b''.join(bytecode)) - -TEST = """;44100! -;left_mic@ -;right_mic@ -;synth* -;synth setfreq 0 440 0.9 - -;synth=>left_mic -;synth=>right_mic""" - -C = SonnumCompiler() -snm = C.compile_to_smnb(TEST, '../zigsonnum/test.snmb') \ No newline at end of file +#C = SonnumCompiler() +#snm = C.compile_to_smnb(TEST, '../zigsonnum/test.snmb') \ No newline at end of file diff --git a/pysonnum/instruction.py b/pysonnum/instruction.py index 04d5bdd..55f1279 100644 --- a/pysonnum/instruction.py +++ b/pysonnum/instruction.py @@ -1,6 +1,20 @@ # Here, s stands for the sonnum object, # c stands for compiler object +OPCODES = { + + 'create': 0, + 'wire': 1, + 'air': 2, + 'endtick': 3, + 'relay': 4, + 'accumulate': 5, + 'reset': 6, + 'setfreq': 7, + 'setpos': 8, + + } + def i_create_simple(c, s, name): # ;name* @@ -14,6 +28,13 @@ def i_create_relay(c, s, name): c.add_activity('create', 0, 0, node, None, []) c.add_activity('relay', 0, s.g('endtick'), node, None, []) +def i_create_accumulate(c, s, name): + # ;name@ + + node = s.add_node(name) + c.add_activity('create', 0, 0, node, None, []) + c.add_activity('accumulate', 0, s.g('endtick'), node, None, []) + def i_end_tick(c, s, endtick): # ;endtick! c.add_activity('endtick', 0, endtick, None, None, []) @@ -37,12 +58,29 @@ def i_air(c, s, src_name, trg_name): if src_node and trg_node: c.add_activity('air', 0, 0, src_node, trg_node, []) -def i_pos(c, s, node_name, tick, x, y, z): +def i_setpos(c, s, start_tick, end_tick, node_name, x, y, z): node = s.node_by_name(node_name) - c.add_activity('setpos', tick, tick, node, None, [x, y, z]) + c.add_activity('setpos', start_tick, end_tick, node, None, [x, y, z]) -def i_setfreq(c, s, node_name, tick, freq, r_amp): +def i_setfreq(c, s, start_tick, end_tick, node_name, freq, r_amp): node = s.node_by_name(node_name) - c.add_activity('setfreq', tick, tick, node, None, [freq, r_amp]) \ No newline at end of file + c.add_activity('setfreq', start_tick, end_tick, node, None, [freq, r_amp]) + +def i_triangle(c, s, start_tick, end_tick, node_name, harmonics_q, freq, r_amp): + + node = s.node_by_name(node_name) + c.add_activity('reset', 0, 0, node, None, []) + + for i in range(0, int(harmonics_q)): + + har_freq = freq*(i*2 + 1) + + if i%2 == 0: + m = 1 + else: + m = -1 + + c.add_activity('setfreq', start_tick, end_tick, node, None, [har_freq, m * r_amp / float((i*2 + 1)**2)]) + \ No newline at end of file diff --git a/sintest.py b/sintest.py deleted file mode 100644 index ac5d14b..0000000 --- a/sintest.py +++ /dev/null @@ -1,43 +0,0 @@ -import math - -def cutsin(t, freq): - - tF = t * (freq - int(freq)) - ftF = int(tF) - - return 2*math.pi*(tF - ftF) - -def normsin(t, freq): - - return math.sin(2*math.pi*freq*t) - - -freq = 9110.7204 -t = 5*60*44100 - -print(normsin(t, freq)) -print(cutsin(t, freq)) - - -print(t - int(t*freq)/float(freq)) -print(f'F = {freq}') -print(f'TF = {t*freq}') -print(f'fTF = {int(t*freq)}') -print(f'fTF/F = {int(t*freq)/float(freq)}') - - -import cProfile - -def dvd(): - for i in range(0,1000000): - normsin(t, freq) - -def snn(): - for i in range(0,1000000): - cutsin(t, freq) - - -cProfile.runctx("dvd()", globals(), locals()) -cProfile.runctx("snn()", globals(), locals()) - - diff --git a/snm.py b/snm.py new file mode 100644 index 0000000..3d9b72f --- /dev/null +++ b/snm.py @@ -0,0 +1,49 @@ +import argparse +import os + +from pysonnum.compiler import * + +# USAGE +# python snm.py path_to.snm output.wav + +parser = argparse.ArgumentParser(description="Sonnum - the additive synthesizer.") + +parser.add_argument('input_snm_fn', metavar="INPUT", nargs='?', type=str, help="Input *.snm source file", default='') + +parser.add_argument('-t', '--transpile', help="View the transpiled python code", action='store_true') +parser.add_argument('-b', '--bytecode', help="View the resulting bytecode", action='store_true') + +parser.add_argument('-o', '--output', metavar='FN', help="Synthesize to given wav filenames", type=str) + + +def run(): + + args = parser.parse_args() + + C = SonnumCompiler() + fn = args.input_snm_fn + + with open(fn, 'r', encoding = 'utf-8') as fl: + snm = fl.read() + + if args.transpile: + py_snm = C.transpile_snm_to_py(snm) + print('TRANSPILED CODE') + print(py_snm) + + elif args.bytecode: + py_snm = C.transpile_snm_to_py(snm) + C.run_transpiled_code(py_snm) + C.sort_activities() + C.list_activities() + + elif args.output: + C.compile_to_smnb(snm, 'source.snmb') + os.system(f'./zigsonnum/sonnum > {args.output}') + + else: + C.compile_to_smnb(snm, 'source.snmb') + os.system(f'zig run zigsonnum/sonnum.zig -lc -OReleaseFast > {fn}.wav') + +if __name__ == '__main__': + run() \ No newline at end of file diff --git a/test.py b/test.py deleted file mode 100644 index 13c5e71..0000000 --- a/test.py +++ /dev/null @@ -1,41 +0,0 @@ -import math - -from core.room import Room -from core.program import Program -from core.soundnode import SoundNode -from core.nodes.sinenode import * -from core.nodes.triangle import * -from core.nodes.sawtooth import * -from core.actions.basics import * - -class TestProgram(Program): - - def __init__(self): - - super().__init__("testprogram") - - def setup(self): - self.reset() - - sn = SineNode(440, self.room) - - sn.wire_to(self.room.left_sink) - sn.wire_to(self.room.right_sink) - - #sn.start_location = (49,0,0) - #sn2.start_location = (-4,0,0) - - """ - NoteAction('A4', self.st(0), self.st(0.5), [sn, tn], self) - NoteAction('G4', self.st(1), self.st(0.5), [sn, tn], self) - NoteAction('F4', self.st(2), self.st(0.5), [sn, tn], self) - NoteAction('E4', self.st(3), self.st(0.5), [sn, tn], self) - """ - #LinearPitchTransition('A4', 'E4', self.st(0), self.st(5), [sn], self) - #LinearPitchTransition('E4', 'A4', self.st(0), self.st(5), [sn2], self) - - #LinearSpatialTransition((-8,0,0),(8,0,0), self.st(0), self.st(5), [sn], self) - -TP = TestProgram() -TP.setup() -TP.interface() \ No newline at end of file diff --git a/zigsonnum/activity.zig b/zigsonnum/activity.zig index d9a00db..6c60fd8 100644 --- a/zigsonnum/activity.zig +++ b/zigsonnum/activity.zig @@ -30,9 +30,10 @@ pub const Activity = struct { pub fn do(self: *Activity) !void { switch (self.opcode) { 4 => { try self.relay(); }, - 5 => { try self.reset(); }, - 6 => { try self.setfreq(); }, - 7 => { try self.slide_freq(); }, + 5 => { try self.accumulate(); }, + 6 => { try self.reset(); }, + 7 => { try self.setfreq(); }, + 8 => { self.setpos(); }, else => {}, } } @@ -73,15 +74,13 @@ pub const Activity = struct { try self.soundnode.fab.reset(); const current_tick: u32 = self.soundnode.fab.current_tick; const current_index: u32 = self.soundnode.fab.current_index; - - var current_fal: *FreqAmpList = undefined; - + for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { - current_fal = wired_sn.fab.fal_array[current_index]; + const current_fal = wired_sn.fab.fal_array[current_index]; for (current_fal.arraylist.items) |fa| { - try self.soundnode.fab.addfreq(fa.freq, fa.r_amp, fa.phase); + try self.soundnode.fab.add_fa(fa); } _ = i; @@ -90,22 +89,82 @@ pub const Activity = struct { for (self.soundnode.air_in.items, 0..) |aired_sn, i| { - const dist: f32 = self.soundnode.distance(aired_sn); - const sample_tick: u32 = @intFromFloat(@floor(@as(f32, @floatFromInt(current_tick)) - @floor(128.571428 * dist))); + const dist: f64 = self.soundnode.distance(aired_sn); - const sample_index = aired_sn.fab.index_by_tick(sample_tick); - const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); - current_fal = aired_sn.fab.fal_array[sample_index]; + var sample_tick: u32 = 0; + const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); + + if (tck > 0) { + sample_tick = @intFromFloat( @floor(tck) ); + + const sample_index = aired_sn.fab.index_by_tick(sample_tick); + const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const sample_fal = aired_sn.fab.fal_array[sample_index]; + + for (sample_fal.arraylist.items) |fa| { + try self.soundnode.fab.addfreq(fa.freq, fa.r_amp * attenuation, fa.phase); + } - for (current_fal.arraylist.items) |fa| { - try self.soundnode.fab.addfreq(fa.freq, fa.r_amp * attenuation, fa.phase); } _ = i; } - } + pub fn accumulate(self: *Activity) !void { + + try self.soundnode.fab.reset(); + const current_tick: u32 = self.soundnode.fab.current_tick; + const current_index: u32 = self.soundnode.fab.current_index; + + for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { + + const current_fal = wired_sn.fab.fal_array[current_index]; + + for (current_fal.arraylist.items) |fa| { + try self.soundnode.fab.addfreq(fa.freq, fa.r_amp, fa.phase); + } + + _ = i; + + } + + for (self.soundnode.air_in.items, 0..) |aired_sn, i| { + + const dist: f64 = self.soundnode.distance(aired_sn); + + var sample_tick: u32 = 0; + const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist); + + if (tck > 0) { + sample_tick = @intFromFloat( @floor(tck) ); + + const sample_index = aired_sn.fab.index_by_tick(sample_tick); + const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); + + const sample_fal = aired_sn.fab.fal_array[sample_index]; + + for (sample_fal.arraylist.items) |fa| { + try self.soundnode.fab.addfreq(fa.freq, fa.r_amp * attenuation, fa.phase); + } + + } + + _ = i; + + } + + } + + pub fn setpos(self: *Activity) void { + self.soundnode.location.x = @as(f32, @floatCast(self.operands[0])); + self.soundnode.location.y = @as(f32, @floatCast(self.operands[1])); + self.soundnode.location.z = @as(f32, @floatCast(self.operands[2])); + + } + + }; \ No newline at end of file diff --git a/zigsonnum/freqamp.zig b/zigsonnum/freqamp.zig index 56bd837..ee6a5f7 100644 --- a/zigsonnum/freqamp.zig +++ b/zigsonnum/freqamp.zig @@ -46,6 +46,12 @@ pub const FreqAmpList = struct { } + pub fn add_fa(self: *FreqAmpList, fa: *FreqAmp) !void { + + try self.arraylist.append(fa); + + } + pub fn setfreq(self: *FreqAmpList, freq: f64, r_amp: f64, phase: f64) !void { for (self.arraylist.items) |fa| { @@ -89,8 +95,10 @@ pub const FreqAmpList = struct { pub fn deinit(self: *FreqAmpList) void { - for (self.arraylist.items) |freqamp| { - self.allocator.destroy(freqamp); + if (0>0) { + for (self.arraylist.items) |freqamp| { + self.allocator.destroy(freqamp); + } } self.arraylist.deinit(); @@ -221,6 +229,12 @@ pub const FreqAmpBuffer = struct { } + pub fn add_fa(self: *FreqAmpBuffer, fa: *FreqAmp) !void { + var current_fal = self.fal_array[self.current_index]; + try current_fal.add_fa(fa); + + } + pub fn addfreq(self: *FreqAmpBuffer, freq: f64, r_amp: f64, phase: f64) !void { var current_fal = self.fal_array[self.current_index]; diff --git a/zigsonnum/point.zig b/zigsonnum/point.zig index f57d96a..077a3d9 100644 --- a/zigsonnum/point.zig +++ b/zigsonnum/point.zig @@ -15,7 +15,7 @@ pub const Pnt = struct { }; -pub fn distanceBetweenPoints(pt1: Pnt, pt2: Pnt) f32 { +pub fn distanceBetweenPoints(pt1: Pnt, pt2: Pnt) f64 { if ((pt1.x == pt2.x) and (pt1.y == pt2.y) and (pt1.z == pt2.z)) { return 0; diff --git a/zigsonnum/sonnum.zig b/zigsonnum/sonnum.zig index b359970..3354758 100644 --- a/zigsonnum/sonnum.zig +++ b/zigsonnum/sonnum.zig @@ -32,7 +32,7 @@ pub fn main() !void { var end_tick: u32 = 44100 * 10; // Loading the input binary code, preparing registers - const file = try std.fs.cwd().openFile("test.snmb", .{}); + const file = try std.fs.cwd().openFile("source.snmb", .{}); defer file.close(); const stat = try file.stat(); @@ -82,11 +82,6 @@ pub fn main() !void { try stdout.writeInt(u16, settings.bit_depth, Endian.little); try stdout.writeAll("data"); - try stdout.writeInt( - u32, - end_tick * 2 * settings.sample_width, - Endian.little, - ); // Setting up tick iteration var tick: u32 = start_tick; @@ -95,142 +90,172 @@ pub fn main() !void { var left: *SoundNode = undefined; var right: *SoundNode = undefined; + var nextopcodetick: u32 = 0; + while (tick < end_tick) { - while (cursor < buf.len) { + if (tick == nextopcodetick) { - opcode = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big); - //print("----\nOPCODE {d} :: {any}\n", .{opcode, buf[cursor..cursor+2]}); - cursor += 2; - - tick_start = std.mem.readVarInt(u32, buf[cursor..cursor+4], .big); - //print("TICKSTART {d} :: {any}\n", .{tick_start, buf[cursor..cursor+4]}); - cursor += 4; - - if (tick_start > tick) { - cursor -= 6; - break; + while (cursor < buf.len) { - } else { - - tick_end = std.mem.readVarInt(u32, buf[cursor..cursor+4], .big); - //print("TICKEND {d} :: {any}\n", .{tick_end, buf[cursor..cursor+4]}); + opcode = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big); + print("----\nCURRENT TICK {d}\nOPCODE {d} :: {any}\n", .{tick, opcode, buf[cursor..cursor+2]}); + cursor += 2; + + tick_start = std.mem.readVarInt(u32, buf[cursor..cursor+4], .big); + print("TICKSTART {d} :: {any}\n", .{tick_start, buf[cursor..cursor+4]}); cursor += 4; - src_node = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big); - //print("SRCNODE {d} :: {any}\n", .{src_node, buf[cursor..cursor+2]}); - cursor += 2; - - trg_node = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big); - //print("TRGNODE {d} :: {any}\n", .{trg_node, buf[cursor..cursor+2]}); - cursor += 2; - - op1 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); - //print("OP1 {d} :: {any}\n", .{op1, buf[cursor..cursor+8]}); - cursor += 8; - - op2 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); - //print("OP2 {d} :: {any}\n", .{op2, buf[cursor..cursor+8]}); - cursor += 8; - - op3 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); - //print("OP3 {d} :: {any}\n", .{op3, buf[cursor..cursor+8]}); - cursor += 8; - - op4 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); - //print("OP4 {d} :: {any}\n", .{op4, buf[cursor..cursor+8]}); - cursor += 8; - - op5 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); - //print("OP5 {d} :: {any}\n", .{op5, buf[cursor..cursor+8]}); - cursor += 8; - - op6 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); - //print("OP6 {d} :: {any}\n", .{op6, buf[cursor..cursor+8]}); - cursor += 8; - - // Executing opcodes - - switch (opcode) { + if (tick_start > tick) { + cursor -= 6; + nextopcodetick = tick_start; + break; - 0 => { - const nodename = try std.fmt.allocPrint(allocator, "{d}", .{src_node}); - - const sn = try SoundNode.create(allocator, nodename); - //print("Added node {s} at tick {d}\n", .{nodename, tick}); - try soundnodes.append(sn); - }, + } else { + + tick_end = std.mem.readVarInt(u32, buf[cursor..cursor+4], .big); + print("TICKEND {d} :: {any}\n", .{tick_end, buf[cursor..cursor+4]}); + cursor += 4; - 1 => { - const src = soundnodes.items[src_node]; - const trg = soundnodes.items[trg_node]; - //print("Wired nodes at tick {d}\n", .{tick}); - - try trg.wire_in.append(src); - }, + src_node = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big); + print("SRCNODE {d} :: {any}\n", .{src_node, buf[cursor..cursor+2]}); + cursor += 2; - 2 => { - const src = soundnodes.items[src_node]; - const trg = soundnodes.items[trg_node]; - - //print("Aired nodes at tick {d}\n", .{tick}); - try trg.air_in.append(src); - }, + trg_node = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big); + //print("TRGNODE {d} :: {any}\n", .{trg_node, buf[cursor..cursor+2]}); + cursor += 2; - 3 => { - end_tick = tick_end; - //print("End tick set to {d}\n", .{end_tick}); - }, + op1 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); + //print("OP1 {d} :: {any}\n", .{op1, buf[cursor..cursor+8]}); + cursor += 8; - else => { + op2 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); + //print("OP2 {d} :: {any}\n", .{op2, buf[cursor..cursor+8]}); + cursor += 8; + + op3 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); + //print("OP3 {d} :: {any}\n", .{op3, buf[cursor..cursor+8]}); + cursor += 8; + + op4 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); + //print("OP4 {d} :: {any}\n", .{op4, buf[cursor..cursor+8]}); + cursor += 8; + + op5 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); + //print("OP5 {d} :: {any}\n", .{op5, buf[cursor..cursor+8]}); + cursor += 8; + + op6 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big)); + //print("OP6 {d} :: {any}\n", .{op6, buf[cursor..cursor+8]}); + cursor += 8; + + // Executing opcodes + + switch (opcode) { - const src = soundnodes.items[src_node]; - const a = try Activity.create(allocator, tick_start, tick_end, opcode, src, [6]f64{op1, op2, op3, op4, op5, op6}); + 0 => { + const nodename = try std.fmt.allocPrint(allocator, "{d}", .{src_node}); + + const sn = try SoundNode.create(allocator, nodename); + //print("Added node {s} at tick {d}\n", .{nodename, tick}); + try soundnodes.append(sn); + }, - //print("Set activity {d} for node {d} s at tick {d}\n", .{opcode, src_node, tick}); - try src.activities.append(a); + 1 => { + const src = soundnodes.items[src_node]; + const trg = soundnodes.items[trg_node]; + //print("Wired nodes at tick {d}\n", .{tick}); + + try trg.wire_in.append(src); + }, - }, + 2 => { + const src = soundnodes.items[src_node]; + const trg = soundnodes.items[trg_node]; + + //print("Aired nodes at tick {d}\n", .{tick}); + try trg.air_in.append(src); + }, + + 3 => { + end_tick = tick_end; + + try stdout.writeInt( + u32, + end_tick * 2 * settings.sample_width, + Endian.little, + ); + //print("End tick set to {d}\n", .{end_tick}); + }, + + else => { + + const src = soundnodes.items[src_node]; + const a = try Activity.create(allocator, tick_start, tick_end, opcode, src, [6]f64{op1, op2, op3, op4, op5, op6}); + + print("Set activity {d} for node {d} s at tick {d}\n", .{opcode, src_node, tick}); + try src.activities.append(a); + + }, + + } } - + } } - + //All but left and right - for (soundnodes.items, 2..) |soundnode, i| { + for (soundnodes.items[2..], 0..) |soundnode, i| { - for (soundnode.activities.items, 0..) |activity, j| { + var toremove = ArrayList(usize).init(allocator); + 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); } - - _ = j; - } + + var j: usize = toremove.items.len; - + while (j > 0) { + j -= 1; + const activity_ind = toremove.items[j]; + _ = soundnode.activities.swapRemove(activity_ind); + } + soundnode.fab.increment_tick(); _ = i; } //Left and right - for (soundnodes.items, 0..2) |soundnode, i| { + for (soundnodes.items[0..2], 0..) |soundnode, i| { + + var toremove = ArrayList(usize).init(allocator); 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); } - - _ = j; - + } + + var j: usize = toremove.items.len; + while (j > 0) { + j -= 1; + const activity_ind = toremove.items[j]; + _ = soundnode.activities.swapRemove(activity_ind); + } soundnode.fab.increment_tick(); _ = i; @@ -271,176 +296,4 @@ pub fn main() !void { try bw.flush(); -} - -pub fn nnnmain() !void { - - //var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - //const allocator = gpa.allocator(); - - const allocator = std.heap.c_allocator; - - var settings: SoundSettings = SoundSettings{}; - - const start_tick: u32 = 0; - const end_tick: u32 = 44100 * 10; - - var left: SoundNode = try SoundNode.init(allocator, "left_sink"); - defer left.deinit(); - left.location.x = -0.15; - - var right: SoundNode = try SoundNode.init(allocator, "right_sink"); - defer right.deinit(); - right.location.x = 0.15; - - var sine: SoundNode = try SoundNode.init(allocator, "sine"); - defer sine.deinit(); - - var a = Activity{ - .start_tick = 0, - .end_tick = 0, - .opcode = 1, - .soundnode = &sine, - }; - - a.operands[0] = 440.0; - a.operands[1] = 0.5; - - var sine2: SoundNode = try SoundNode.init(allocator, "sine2"); - defer sine2.deinit(); - - var a4 = Activity{ - .start_tick = 0, - .end_tick = 0, - .opcode = 1, - .soundnode = &sine, - }; - - a4.operands[0] = 449.0; - a4.operands[1] = 0.5; - a4.operands[2] = 0.55; - - try sine.activities.append(&a); - try sine.activities.append(&a4); - - var a2 = Activity{ - .start_tick = 0, - .end_tick = end_tick, - .opcode = 2, - .soundnode = &left, - }; - try left.activities.append(&a2); - - var a3 = Activity{ - .start_tick = 0, - .end_tick = end_tick, - .opcode = 2, - .soundnode = &right, - }; - try right.activities.append(&a3); - - var soundnodes = ArrayList(*SoundNode).init(allocator); - defer soundnodes.deinit(); - - //Preset sink nodes - try soundnodes.append(&sine); - try soundnodes.append(&sine2); - try soundnodes.append(&left); - try soundnodes.append(&right); - - try left.wire_in.append(&sine); - try right.wire_in.append(&sine); - - var tick: u32 = start_tick; - - //STARTING WAV - const stdout_file = std.io.getStdOut().writer(); - var bw = std.io.bufferedWriter(stdout_file); - const stdout = bw.writer(); - - //WRITING WAV HEADER - try stdout.writeAll("RIFF"); - - try stdout.writeInt( - u32, - 36 + (end_tick * 2 * settings.sample_width), - Endian.little, - ); - - try stdout.writeAll("WAVE"); - try stdout.writeAll("fmt "); - - try stdout.writeInt(u32, 16, Endian.little); - try stdout.writeInt(u16, 1, Endian.little); - try stdout.writeInt(u16, 2, Endian.little); - try stdout.writeInt(u32, settings.sample_rate, Endian.little); - - const block_align: u16 = @intCast(2 * settings.sample_width); - - try stdout.writeInt(u32, @as(u32, block_align) * settings.sample_rate, Endian.little); - try stdout.writeInt(u16, block_align, Endian.little); - try stdout.writeInt(u16, settings.bit_depth, Endian.little); - - try stdout.writeAll("data"); - try stdout.writeInt( - u32, - end_tick * 2 * settings.sample_width, - Endian.little, - ); - - var sample: i24 = 0.0; - - while (tick < end_tick) { - - if (tick%44100 == 0) { - print("TICK {d}\n", .{tick}); - } - - for (soundnodes.items, 0..) |soundnode, i| { - - for (soundnode.activities.items, 0..) |activity, j| { - - if (tick <= activity.end_tick and tick >= activity.start_tick) { - try activity.do(); - } - - _ = j; - - } - - - soundnode.fab.increment_tick(); - _ = i; - } - - var amp: f64 = 0; - - const current_index = left.fab.current_index; - - const current_fal_left = left.fab.fal_array[current_index]; - - for (current_fal_left.arraylist.items) |fa| { - amp += fa.r_amp * singleSineTick(&settings, fa.freq, tick, fa.phase); - } - - sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp))); - try stdout.writeInt(i24, sample, Endian.little); - - amp = 0; - - const current_fal_right = right.fab.fal_array[current_index]; - - for (current_fal_right.arraylist.items) |fa| { - amp += fa.r_amp * singleSineTick(&settings, fa.freq, tick, fa.phase); - } - - sample = @intFromFloat(amp * @as(f64, @floatFromInt(settings.max_amp))); - try stdout.writeInt(i24, sample, Endian.little); - - tick += 1; - - } - - try bw.flush(); - } \ No newline at end of file diff --git a/zigsonnum/soundnode.zig b/zigsonnum/soundnode.zig index a8ffb21..3a45d6f 100644 --- a/zigsonnum/soundnode.zig +++ b/zigsonnum/soundnode.zig @@ -85,7 +85,7 @@ pub const SoundNode = struct { } - pub fn distance(self: *SoundNode, other: *SoundNode) f32 { + pub fn distance(self: *SoundNode, other: *SoundNode) f64 { return pnt.distanceBetweenPoints(self.location, other.location); diff --git a/zigsonnum/testtest.zig b/zigsonnum/testtest.zig deleted file mode 100644 index a913e0d..0000000 --- a/zigsonnum/testtest.zig +++ /dev/null @@ -1,58 +0,0 @@ -const std = @import("std"); -const print = std.debug.print; -const ArrayList = std.ArrayList; -const AutoHashMap = std.AutoHashMap; - -pub fn prnt(s: []const u8) void { - print("{s}\n", .{s}); -} - -const Pnt = struct { - - x: f32 = 0, - y: f32 = 0, - z: f32 = 0, - - fn printPnt(self: *const Pnt) void { - print("{d} {d} {d}\n", .{self.x, self.y, self.z}); - } - -}; - -pub fn main() !void { - - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - const allocator = gpa.allocator(); - - defer { - const deinit_status = gpa.deinit(); - _ = deinit_status; - } - - var pntlist = ArrayList(Pnt).init(allocator); - - var p1 = Pnt{.x = 0, .y= 1, .z = 3}; - p1.printPnt(); - - try pntlist.append(p1); - pntlist.items[0].printPnt(); - print("{d}\n", .{pntlist.items.len}); - try pntlist.append(p1); - print("{d}\n", .{pntlist.items.len}); - try pntlist.append(p1); - print("{d}\n", .{pntlist.items.len}); - - p1.x = 4; - p1.printPnt(); - pntlist.items[0].printPnt(); - print("{any}", .{@TypeOf(pntlist)}); - defer pntlist.deinit(); - - var map = AutoHashMap(u32, Pnt).init(allocator); - defer map.deinit(); - - try map.put(1, p1); - try map.put(22, pntlist.items[0]); - //map.get(22).printPnt(); - -} \ No newline at end of file