actually working version, but too slow to be good

This commit is contained in:
aprilnightk 2025-09-11 11:20:28 +03:00
parent 0d33e1e022
commit bf01f2efce
14 changed files with 351 additions and 517 deletions

1
.gitignore vendored
View file

@ -17,6 +17,7 @@ err.txt
log.txt log.txt
t*.html t*.html
*.kdev4 *.kdev4
*.o
.kdev4/ .kdev4/
HTML/ HTML/
PDF/ PDF/

View file

@ -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())

View file

@ -1,23 +1,11 @@
import struct import struct
from .instruction import OPCODES
class Activity: class Activity:
OPCODES = {
'create': 0,
'wire': 1,
'air': 2,
'endtick': 3,
'relay': 4,
'reset': 5,
'setfreq': 6,
'setpos': 7,
}
def __repr__(self): 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): def __init__(self, sonnum, name, tick_start, tick_end, src_node, trg_node, operands):
@ -32,9 +20,9 @@ class Activity:
def to_bytes(self): 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_start = int(self.tick_start).to_bytes(4, byteorder="big")
b_tick_end = int(self.tick_end).to_bytes(4, byteorder="big") b_tick_end = int(self.tick_end).to_bytes(4, byteorder="big")

View file

@ -1,6 +1,6 @@
from sonnum import Sonnum from .sonnum import Sonnum
from activity import Activity from .activity import Activity
from instruction import * from .instruction import *
class SonnumCompiler: class SonnumCompiler:
@ -28,7 +28,11 @@ class SonnumCompiler:
self.activities.append(a) self.activities.append(a)
def sanitize_operand(self, operand): def sanitize_operand(self, operand):
if operand.endswith('~sec'):
sec = operand[:-4]
return f'{sec}*44100'
try: try:
return str(float(operand)) return str(float(operand))
except: except:
@ -56,9 +60,14 @@ class SonnumCompiler:
elif ln.endswith('!'): elif ln.endswith('!'):
ticklen = int(ln[1:-1]) ticklen = self.sanitize_operand(ln[1:-1])
ln = f"i_end_tick(self, self.sonnum, {ticklen})" 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('@'): elif ln.endswith('@'):
name = ln[1:-1] name = ln[1:-1]
@ -73,13 +82,28 @@ class SonnumCompiler:
ln = f"i_air(self, self.sonnum, '{name_src}', '{name_trg}')" ln = f"i_air(self, self.sonnum, '{name_src}', '{name_trg}')"
else: 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 ln = tablevel*'\t' + ln
py_src.append(ln) py_src.append(ln)
@ -146,16 +170,6 @@ class SonnumCompiler:
with open(fn, 'wb') as fl: with open(fn, 'wb') as fl:
fl.write(b''.join(bytecode)) fl.write(b''.join(bytecode))
TEST = """;44100!
;left_mic@
;right_mic@
;synth*
;synth setfreq 0 440 0.9 #C = SonnumCompiler()
#snm = C.compile_to_smnb(TEST, '../zigsonnum/test.snmb')
;synth=>left_mic
;synth=>right_mic"""
C = SonnumCompiler()
snm = C.compile_to_smnb(TEST, '../zigsonnum/test.snmb')

View file

@ -1,6 +1,20 @@
# Here, s stands for the sonnum object, # Here, s stands for the sonnum object,
# c stands for compiler 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): def i_create_simple(c, s, name):
# ;name* # ;name*
@ -14,6 +28,13 @@ def i_create_relay(c, s, name):
c.add_activity('create', 0, 0, node, None, []) c.add_activity('create', 0, 0, node, None, [])
c.add_activity('relay', 0, s.g('endtick'), 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): def i_end_tick(c, s, endtick):
# ;endtick! # ;endtick!
c.add_activity('endtick', 0, endtick, None, None, []) 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: if src_node and trg_node:
c.add_activity('air', 0, 0, src_node, 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) 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) node = s.node_by_name(node_name)
c.add_activity('setfreq', tick, tick, node, None, [freq, r_amp]) 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)])

View file

@ -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())

49
snm.py Normal file
View file

@ -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()

41
test.py
View file

@ -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()

View file

@ -30,9 +30,10 @@ pub const Activity = struct {
pub fn do(self: *Activity) !void { pub fn do(self: *Activity) !void {
switch (self.opcode) { switch (self.opcode) {
4 => { try self.relay(); }, 4 => { try self.relay(); },
5 => { try self.reset(); }, 5 => { try self.accumulate(); },
6 => { try self.setfreq(); }, 6 => { try self.reset(); },
7 => { try self.slide_freq(); }, 7 => { try self.setfreq(); },
8 => { self.setpos(); },
else => {}, else => {},
} }
} }
@ -73,15 +74,13 @@ pub const Activity = struct {
try self.soundnode.fab.reset(); try self.soundnode.fab.reset();
const current_tick: u32 = self.soundnode.fab.current_tick; const current_tick: u32 = self.soundnode.fab.current_tick;
const current_index: u32 = self.soundnode.fab.current_index; const current_index: u32 = self.soundnode.fab.current_index;
var current_fal: *FreqAmpList = undefined;
for (self.soundnode.wire_in.items, 0..) |wired_sn, i| { 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| { 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; _ = i;
@ -90,22 +89,82 @@ pub const Activity = struct {
for (self.soundnode.air_in.items, 0..) |aired_sn, i| { for (self.soundnode.air_in.items, 0..) |aired_sn, i| {
const dist: f32 = self.soundnode.distance(aired_sn); const dist: f64 = self.soundnode.distance(aired_sn);
const sample_tick: u32 = @intFromFloat(@floor(@as(f32, @floatFromInt(current_tick)) - @floor(128.571428 * dist)));
const sample_index = aired_sn.fab.index_by_tick(sample_tick); var sample_tick: u32 = 0;
const attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0))); const tck = @as(f64, @floatFromInt(current_tick)) - (128.571428 * dist);
current_fal = aired_sn.fab.fal_array[sample_index];
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; _ = 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]));
}
}; };

View file

@ -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 { pub fn setfreq(self: *FreqAmpList, freq: f64, r_amp: f64, phase: f64) !void {
for (self.arraylist.items) |fa| { for (self.arraylist.items) |fa| {
@ -89,8 +95,10 @@ pub const FreqAmpList = struct {
pub fn deinit(self: *FreqAmpList) void { pub fn deinit(self: *FreqAmpList) void {
for (self.arraylist.items) |freqamp| { if (0>0) {
self.allocator.destroy(freqamp); for (self.arraylist.items) |freqamp| {
self.allocator.destroy(freqamp);
}
} }
self.arraylist.deinit(); 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 { pub fn addfreq(self: *FreqAmpBuffer, freq: f64, r_amp: f64, phase: f64) !void {
var current_fal = self.fal_array[self.current_index]; var current_fal = self.fal_array[self.current_index];

View file

@ -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)) { if ((pt1.x == pt2.x) and (pt1.y == pt2.y) and (pt1.z == pt2.z)) {
return 0; return 0;

View file

@ -32,7 +32,7 @@ pub fn main() !void {
var end_tick: u32 = 44100 * 10; var end_tick: u32 = 44100 * 10;
// Loading the input binary code, preparing registers // 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(); defer file.close();
const stat = try file.stat(); const stat = try file.stat();
@ -82,11 +82,6 @@ pub fn main() !void {
try stdout.writeInt(u16, settings.bit_depth, Endian.little); try stdout.writeInt(u16, settings.bit_depth, Endian.little);
try stdout.writeAll("data"); try stdout.writeAll("data");
try stdout.writeInt(
u32,
end_tick * 2 * settings.sample_width,
Endian.little,
);
// Setting up tick iteration // Setting up tick iteration
var tick: u32 = start_tick; var tick: u32 = start_tick;
@ -95,142 +90,172 @@ pub fn main() !void {
var left: *SoundNode = undefined; var left: *SoundNode = undefined;
var right: *SoundNode = undefined; var right: *SoundNode = undefined;
var nextopcodetick: u32 = 0;
while (tick < end_tick) { while (tick < end_tick) {
while (cursor < buf.len) { if (tick == nextopcodetick) {
opcode = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big); while (cursor < buf.len) {
//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;
} else { opcode = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big);
print("----\nCURRENT TICK {d}\nOPCODE {d} :: {any}\n", .{tick, opcode, buf[cursor..cursor+2]});
tick_end = std.mem.readVarInt(u32, buf[cursor..cursor+4], .big); cursor += 2;
//print("TICKEND {d} :: {any}\n", .{tick_end, buf[cursor..cursor+4]});
tick_start = std.mem.readVarInt(u32, buf[cursor..cursor+4], .big);
print("TICKSTART {d} :: {any}\n", .{tick_start, buf[cursor..cursor+4]});
cursor += 4; cursor += 4;
src_node = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big); if (tick_start > tick) {
//print("SRCNODE {d} :: {any}\n", .{src_node, buf[cursor..cursor+2]}); cursor -= 6;
cursor += 2; nextopcodetick = tick_start;
break;
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) {
0 => { } else {
const nodename = try std.fmt.allocPrint(allocator, "{d}", .{src_node});
tick_end = std.mem.readVarInt(u32, buf[cursor..cursor+4], .big);
const sn = try SoundNode.create(allocator, nodename); print("TICKEND {d} :: {any}\n", .{tick_end, buf[cursor..cursor+4]});
//print("Added node {s} at tick {d}\n", .{nodename, tick}); cursor += 4;
try soundnodes.append(sn);
},
1 => { src_node = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big);
const src = soundnodes.items[src_node]; print("SRCNODE {d} :: {any}\n", .{src_node, buf[cursor..cursor+2]});
const trg = soundnodes.items[trg_node]; cursor += 2;
//print("Wired nodes at tick {d}\n", .{tick});
try trg.wire_in.append(src);
},
2 => { trg_node = std.mem.readVarInt(u16, buf[cursor..cursor+2], .big);
const src = soundnodes.items[src_node]; //print("TRGNODE {d} :: {any}\n", .{trg_node, buf[cursor..cursor+2]});
const trg = soundnodes.items[trg_node]; cursor += 2;
//print("Aired nodes at tick {d}\n", .{tick});
try trg.air_in.append(src);
},
3 => { op1 = @bitCast(std.mem.readVarInt(u64, buf[cursor..cursor+8], .big));
end_tick = tick_end; //print("OP1 {d} :: {any}\n", .{op1, buf[cursor..cursor+8]});
//print("End tick set to {d}\n", .{end_tick}); 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]; 0 => {
const a = try Activity.create(allocator, tick_start, tick_end, opcode, src, [6]f64{op1, op2, op3, op4, op5, op6}); 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}); 1 => {
try src.activities.append(a); 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 //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) { if (tick <= activity.end_tick and tick >= activity.start_tick) {
try activity.do(); 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(); soundnode.fab.increment_tick();
_ = i; _ = i;
} }
//Left and right //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| { for (soundnode.activities.items, 0..) |activity, j| {
if (tick <= activity.end_tick and tick >= activity.start_tick) { if (tick <= activity.end_tick and tick >= activity.start_tick) {
try activity.do(); 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(); soundnode.fab.increment_tick();
_ = i; _ = i;
@ -271,176 +296,4 @@ pub fn main() !void {
try bw.flush(); 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();
} }

View file

@ -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); return pnt.distanceBetweenPoints(self.location, other.location);

View file

@ -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();
}