workable smnb compilation
This commit is contained in:
parent
04690d9df8
commit
0d33e1e022
8 changed files with 618 additions and 7 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -9,6 +9,8 @@ sonnum.prj
|
|||
node_modules/
|
||||
dist/
|
||||
*.pyc
|
||||
*.snm
|
||||
*.snmb
|
||||
err*.txt
|
||||
log*.txt
|
||||
err.txt
|
||||
|
|
|
|||
59
pysonnum/activity.py
Normal file
59
pysonnum/activity.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import struct
|
||||
|
||||
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)
|
||||
|
||||
def __init__(self, sonnum, name, tick_start, tick_end, src_node, trg_node, operands):
|
||||
|
||||
self.sonnum = sonnum
|
||||
|
||||
self.name = name
|
||||
self.tick_start = tick_start
|
||||
self.tick_end = tick_end
|
||||
self.src_node = src_node
|
||||
self.trg_node = trg_node
|
||||
self.operands = operands
|
||||
|
||||
def to_bytes(self):
|
||||
|
||||
if self.name in self.OPCODES:
|
||||
|
||||
b_opcode = self.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")
|
||||
|
||||
if not self.src_node:
|
||||
b_src_node = b'\x00' * 2
|
||||
else:
|
||||
b_src_node = self.src_node.order.to_bytes(2, byteorder="big")
|
||||
|
||||
if not self.trg_node:
|
||||
b_trg_node = b'\x00' * 2
|
||||
else:
|
||||
b_trg_node = self.trg_node.order.to_bytes(2, byteorder="big")
|
||||
|
||||
b_operands = [struct.pack('>d', 0.0)] * 6
|
||||
|
||||
for i in range(0, 6):
|
||||
if len(self.operands) > i: b_operands[i] = struct.pack('>d', self.operands[i])
|
||||
|
||||
return b_opcode + b_tick_start + b_tick_end + b_src_node + b_trg_node + b''.join(b_operands)
|
||||
|
||||
else:
|
||||
return b''
|
||||
161
pysonnum/compiler.py
Normal file
161
pysonnum/compiler.py
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
from sonnum import Sonnum
|
||||
from activity import Activity
|
||||
from instruction import *
|
||||
|
||||
|
||||
class SonnumCompiler:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.sonnum = Sonnum() # {order: name}
|
||||
self.activities = []
|
||||
|
||||
def list_activities(self):
|
||||
|
||||
print('ACTIVITY LISTING')
|
||||
for activity in self.activities:
|
||||
print(activity)
|
||||
|
||||
def list_bytecode(self):
|
||||
|
||||
print('BYTECODE LISTING')
|
||||
for activity in self.activities:
|
||||
print(list(activity.to_bytes()))
|
||||
|
||||
def add_activity(self, name, tick_start, tick_end, src_node, trg_node, operands):
|
||||
|
||||
a = Activity(self.sonnum, name, tick_start, tick_end, src_node, trg_node, operands)
|
||||
self.activities.append(a)
|
||||
|
||||
def sanitize_operand(self, operand):
|
||||
|
||||
try:
|
||||
return str(float(operand))
|
||||
except:
|
||||
return str(operand)
|
||||
|
||||
def transpile_snm_to_py(self, snm_src):
|
||||
|
||||
py_src = []
|
||||
|
||||
for ln in snm_src.split('\n'):
|
||||
|
||||
tablevel = 0
|
||||
|
||||
while ln.startswith('\t'):
|
||||
|
||||
tablevel += 1
|
||||
ln = ln[1:]
|
||||
|
||||
if ln.startswith(';'):
|
||||
|
||||
if ln.endswith('*'):
|
||||
|
||||
name = ln[1:-1]
|
||||
ln = f"i_create_simple(self, self.sonnum, '{name}')"
|
||||
|
||||
elif ln.endswith('!'):
|
||||
|
||||
ticklen = int(ln[1:-1])
|
||||
ln = f"i_end_tick(self, self.sonnum, {ticklen})"
|
||||
|
||||
elif ln.endswith('@'):
|
||||
|
||||
name = ln[1:-1]
|
||||
ln = f"i_create_relay(self, self.sonnum, '{name}')"
|
||||
|
||||
elif '=>' in ln:
|
||||
name_src, name_trg = ln[1:].split('=>')
|
||||
ln = f"i_wire(self, self.sonnum, '{name_src}', '{name_trg}')"
|
||||
|
||||
elif '->' in ln:
|
||||
name_src, name_trg = ln[1:].split('->')
|
||||
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)+")"
|
||||
|
||||
ln = tablevel*'\t' + ln
|
||||
py_src.append(ln)
|
||||
|
||||
else:
|
||||
ln = tablevel*'\t' + ln
|
||||
py_src.append(ln)
|
||||
|
||||
return '\n'.join(py_src)
|
||||
|
||||
def run_transpiled_code(self, py_src):
|
||||
|
||||
exec(py_src)
|
||||
|
||||
def sort_activities(self):
|
||||
|
||||
new = []
|
||||
|
||||
to_delete = []
|
||||
for activity in self.activities:
|
||||
|
||||
if activity.name == 'endtick':
|
||||
new.append(activity)
|
||||
to_delete.append(activity)
|
||||
|
||||
for activity in to_delete:
|
||||
self.activities.remove(activity)
|
||||
|
||||
to_delete = []
|
||||
for activity in self.activities:
|
||||
|
||||
if activity.name == 'create':
|
||||
new.append(activity)
|
||||
to_delete.append(activity)
|
||||
|
||||
for activity in to_delete:
|
||||
self.activities.remove(activity)
|
||||
|
||||
to_delete = []
|
||||
for activity in self.activities:
|
||||
|
||||
if activity.name in ('wire','air'):
|
||||
new.append(activity)
|
||||
to_delete.append(activity)
|
||||
|
||||
for activity in to_delete:
|
||||
self.activities.remove(activity)
|
||||
|
||||
self.activities.sort(key=lambda x: x.tick_start, reverse = False)
|
||||
new.extend(self.activities)
|
||||
self.activities = new
|
||||
|
||||
def compile_to_smnb(self, snm_src, fn):
|
||||
|
||||
py_src = self.transpile_snm_to_py(snm_src)
|
||||
self.run_transpiled_code(py_src)
|
||||
self.sort_activities()
|
||||
self.list_activities()
|
||||
|
||||
bytecode = []
|
||||
|
||||
for activity in self.activities:
|
||||
bytecode.append(activity.to_bytes())
|
||||
|
||||
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')
|
||||
48
pysonnum/instruction.py
Normal file
48
pysonnum/instruction.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Here, s stands for the sonnum object,
|
||||
# c stands for compiler object
|
||||
|
||||
def i_create_simple(c, s, name):
|
||||
# ;name*
|
||||
|
||||
node = s.add_node(name)
|
||||
c.add_activity('create', 0, 0, node, None, [])
|
||||
|
||||
def i_create_relay(c, s, name):
|
||||
# ;name@
|
||||
|
||||
node = s.add_node(name)
|
||||
c.add_activity('create', 0, 0, node, None, [])
|
||||
c.add_activity('relay', 0, s.g('endtick'), node, None, [])
|
||||
|
||||
def i_end_tick(c, s, endtick):
|
||||
# ;endtick!
|
||||
c.add_activity('endtick', 0, endtick, None, None, [])
|
||||
s.s('endtick', endtick)
|
||||
|
||||
def i_wire(c, s, src_name, trg_name):
|
||||
# ;name=>name
|
||||
|
||||
src_node = s.node_by_name(src_name)
|
||||
trg_node = s.node_by_name(trg_name)
|
||||
|
||||
if src_node and trg_node:
|
||||
c.add_activity('wire', 0, 0, src_node, trg_node, [])
|
||||
|
||||
def i_air(c, s, src_name, trg_name):
|
||||
# ;name->name
|
||||
|
||||
src_node = s.node_by_name(src_name)
|
||||
trg_node = s.node_by_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):
|
||||
|
||||
node = s.node_by_name(node_name)
|
||||
c.add_activity('setpos', tick, tick, node, None, [x, y, z])
|
||||
|
||||
def i_setfreq(c, s, node_name, tick, freq, r_amp):
|
||||
|
||||
node = s.node_by_name(node_name)
|
||||
c.add_activity('setfreq', tick, tick, node, None, [freq, r_amp])
|
||||
47
pysonnum/sonnum.py
Normal file
47
pysonnum/sonnum.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
class SoundNode:
|
||||
|
||||
def __init__(self, order, name):
|
||||
|
||||
self.order = order
|
||||
self.name = name
|
||||
self.properties = dict() # {k: v}
|
||||
|
||||
def __repr__(self):
|
||||
return f'{self.order}:{self.name}'
|
||||
|
||||
def g(self, k):
|
||||
return self.properties.get(k)
|
||||
|
||||
def s(self, k, v):
|
||||
self.properties[k] = v
|
||||
|
||||
class Sonnum:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.nodes = dict() # {order: name}
|
||||
self.properties = dict() # {k: v}
|
||||
|
||||
def add_node(self, name):
|
||||
|
||||
order = len(self.nodes)
|
||||
self.nodes[name] = SoundNode(order, name)
|
||||
|
||||
return self.nodes[name]
|
||||
|
||||
def node_by_name(self, name):
|
||||
|
||||
for order, node in self.nodes.items():
|
||||
|
||||
if node.name == name:
|
||||
return node
|
||||
|
||||
def node_by_order(self, order):
|
||||
|
||||
return self.nodes.get(order)
|
||||
|
||||
def g(self, k):
|
||||
return self.properties.get(k)
|
||||
|
||||
def s(self, k, v):
|
||||
self.properties[k] = v
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
const std = @import("std");
|
||||
const print = std.debug.print;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const SoundNode = @import("soundnode.zig").SoundNode;
|
||||
const FreqAmpList = @import("freqamp.zig").FreqAmpList;
|
||||
|
||||
|
|
@ -11,12 +12,27 @@ pub const Activity = struct {
|
|||
soundnode: *SoundNode,
|
||||
operands: [6]f64 = std.mem.zeroes([6]f64),
|
||||
|
||||
pub fn create(allocator: Allocator, start_tick: u32, end_tick: u32, opcode: u16, soundnode: *SoundNode, operands: [6]f64) !*Activity {
|
||||
|
||||
const a = try allocator.create(Activity);
|
||||
a.* = .{
|
||||
.start_tick = start_tick,
|
||||
.end_tick = end_tick,
|
||||
.opcode = opcode,
|
||||
.soundnode = soundnode,
|
||||
.operands = operands,
|
||||
};
|
||||
|
||||
return a;
|
||||
|
||||
}
|
||||
|
||||
pub fn do(self: *Activity) !void {
|
||||
switch (self.opcode) {
|
||||
0 => { try self.reset(); },
|
||||
1 => { try self.setfreq(); },
|
||||
2 => { try self.relay(); },
|
||||
3 => { try self.slide_freq(); },
|
||||
4 => { try self.relay(); },
|
||||
5 => { try self.reset(); },
|
||||
6 => { try self.setfreq(); },
|
||||
7 => { try self.slide_freq(); },
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,265 @@ pub fn singleSineTick(st: *SoundSettings, freq: f64, t: u32, phase: f64) f64 {
|
|||
return math.sin(st.sine_multiplier * freq * ft - phase * utility.tau);
|
||||
}
|
||||
|
||||
|
||||
pub fn main() !void {
|
||||
|
||||
const allocator = std.heap.c_allocator;
|
||||
|
||||
// Initializing sound settings
|
||||
var settings: SoundSettings = SoundSettings{};
|
||||
|
||||
// Creating a list of soundnodes
|
||||
var soundnodes = ArrayList(*SoundNode).init(allocator);
|
||||
defer soundnodes.deinit();
|
||||
|
||||
// Determining length of resulting audio in ticks
|
||||
const start_tick: u32 = 0;
|
||||
var end_tick: u32 = 44100 * 10;
|
||||
|
||||
// Loading the input binary code, preparing registers
|
||||
const file = try std.fs.cwd().openFile("test.snmb", .{});
|
||||
defer file.close();
|
||||
|
||||
const stat = try file.stat();
|
||||
const buf: []u8 = try file.readToEndAlloc(allocator, stat.size);
|
||||
|
||||
var cursor: u32 = 0;
|
||||
|
||||
var opcode: u16 = 0;
|
||||
var tick_start: u32 = 0;
|
||||
var tick_end: u32 = 0;
|
||||
var src_node: u16 = 0;
|
||||
var trg_node: u16 = 0;
|
||||
var op1: f64 = 0;
|
||||
var op2: f64 = 0;
|
||||
var op3: f64 = 0;
|
||||
var op4: f64 = 0;
|
||||
var op5: f64 = 0;
|
||||
var op6: f64 = 0;
|
||||
|
||||
// Preparing to write wav data to stdout
|
||||
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,
|
||||
);
|
||||
|
||||
// Setting up tick iteration
|
||||
var tick: u32 = start_tick;
|
||||
var amp: f64 = 0;
|
||||
var sample: i24 = 0.0;
|
||||
var left: *SoundNode = undefined;
|
||||
var right: *SoundNode = undefined;
|
||||
|
||||
while (tick < end_tick) {
|
||||
|
||||
while (cursor < buf.len) {
|
||||
|
||||
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;
|
||||
|
||||
} 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;
|
||||
|
||||
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) {
|
||||
|
||||
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);
|
||||
},
|
||||
|
||||
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;
|
||||
//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 (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;
|
||||
}
|
||||
|
||||
//Left and right
|
||||
|
||||
for (soundnodes.items, 0..2) |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;
|
||||
}
|
||||
|
||||
//Calculating and writing output amps
|
||||
|
||||
amp = 0;
|
||||
|
||||
left = soundnodes.items[0];
|
||||
right = soundnodes.items[1];
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
pub fn nnnmain() !void {
|
||||
|
||||
//var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
//const allocator = gpa.allocator();
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,28 @@ pub const SoundNode = struct {
|
|||
|
||||
fab: FreqAmpBuffer,
|
||||
|
||||
pub fn create(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 sn = try allocator.create(SoundNode);
|
||||
|
||||
sn.* = .{
|
||||
.allocator = allocator,
|
||||
.name = name,
|
||||
.air_in = air_in,
|
||||
.wire_in = wire_in,
|
||||
.activities = activities,
|
||||
.fab = fab,
|
||||
};
|
||||
|
||||
return sn;
|
||||
|
||||
}
|
||||
|
||||
pub fn init(allocator: Allocator, name: []const u8) !SoundNode {
|
||||
|
||||
const air_in = ArrayList(*SoundNode).init(allocator);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue