major overhaul

This commit is contained in:
aprilnightk 2025-09-16 23:16:48 +03:00
parent 8362e1643c
commit 3f30771451
9 changed files with 1213 additions and 581 deletions

9
mysynths/sintest.py Normal file
View file

@ -0,0 +1,9 @@
s.setup(s.sec(60))
n = s.node()
n.setbasefreq(0, s.note("D4"))
n.setgain(0, 0.09)
n.sine(0, s.sec(10))
s.wire(n, s.left)

View file

@ -3,14 +3,13 @@ import struct
OPCODES = {
'create': 0,
'wire': 1,
'air': 2,
'pin': 1,
'endtick': 3,
'relay': 4,
'setpos': 5,
'setbasefreq': 6,
'setgain': 7,
'setphase': 8,
'setbasephase': 8,
'sine': 9,
'triangle': 10,
'square': 11,

View file

@ -131,7 +131,7 @@ class SonnumCompiler:
to_delete = []
for activity in self.activities:
if activity.name in ('wire','air'):
if activity.name in ('wire','air','pin'):
new.append(activity)
to_delete.append(activity)

View file

@ -79,7 +79,7 @@ class Sonnum:
for src_node in src_nodes:
for trg_node in trg_nodes:
self.act('wire', 0, 0, src_node, trg_node, [])
self.act('pin', 0, 0, src_node, trg_node, [0, 0])
def air(self, src_nodes, trg_nodes):
@ -91,4 +91,16 @@ class Sonnum:
for src_node in src_nodes:
for trg_node in trg_nodes:
self.act('air', 0, 0, src_node, trg_node, [])
self.act('pin', 0, 0, src_node, trg_node, [0, 1])
def pin(self, src_nodes, trg_nodes, src_pin, trg_pin):
if not isinstance(src_nodes, list):
src_nodes = [src_nodes]
if not isinstance(trg_nodes, list):
trg_nodes = [trg_nodes]
for src_node in src_nodes:
for trg_node in trg_nodes:
self.act('pin', 0, 0, src_node, trg_node, [src_pin, trg_pin])

593
zigsonnum/activity.bak.zig Normal file
View file

@ -0,0 +1,593 @@
const std = @import("std");
const math = std.math;
const print = std.debug.print;
const Allocator = std.mem.Allocator;
const SoundNode = @import("soundnode.zig").SoundNode;
const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer;
const FreqAmpList = @import("freqamp.zig").FreqAmpList;
const utility = @import("utility.zig");
pub const Activity = struct {
start_tick: u32,
end_tick: u32,
opcode: u16,
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) {
4 => { self.relay(); },
5 => { self.setpos(); },
6 => { self.setbasefreq(); },
7 => { self.setgain(); },
8 => { self.setphase(); },
9 => { self.sine(); },
10 => { self.triangle(); },
11 => { self.square(); },
12 => { self.sawtooth(); },
13 => { self.setskew(); },
14 => { self.skewsine(); },
15 => { try self.slidebasefreq(); },
16 => { try self.slidegain(); },
17 => { try self.slidephase(); },
18 => { try self.slideskew(); },
19 => { self.slidepos(); },
20 => { self.pulse(); },
21 => { try self.fmsetup(); },
22 => { try self.fm(); },
23 => { try self.am(); },
24 => { try self.mute(); },
25 => { self.whitenoise(); },
26 => { try self.setadsrgain(); },
27 => { try self.setadsrsustain(); },
28 => { try self.adsr(); },
else => {},
}
}
pub fn relay_imprecise(self: *Activity) void {
const current_tick: u32 = self.soundnode.fab.current_tick;
for (self.soundnode.wire_in.items, 0..) |wired_sn, i| {
const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick);
self.soundnode.fab.add_r_amp(relayed_r_amp);
_ = 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 attenuation: f64 = @as(f64, std.math.exp(-(dist / 100.0)));
const relayed_r_amp = aired_sn.fab.get_r_amp(sample_tick) * attenuation;
self.soundnode.fab.add_r_amp(relayed_r_amp);
}
_ = i;
}
}
pub fn relay(self: *Activity) void {
self.soundnode.fab.add_r_amp(self.soundnode.in_wire);
self.soundnode.fab.add_r_amp(self.soundnode.in_air);
self.soundnode.r_amp += self.soundnode.in_wire;
self.soundnode.r_amp += self.soundnode.in_air;
}
pub fn setbasefreq(self: *Activity) void {
self.soundnode.basefreq = self.operands[0];
}
pub fn setgain(self: *Activity) !void {
self.soundnode.gain = self.operands[0];
}
pub fn setbasephase(self: *Activity) !void {
self.soundnode.basephase = self.operands[0];
}
pub fn setpos(self: *Activity) void {
self.soundnode.x = @as(f32, @floatCast(self.operands[0]));
self.soundnode.y = @as(f32, @floatCast(self.operands[1]));
self.soundnode.z = @as(f32, @floatCast(self.operands[2]));
}
pub fn sine(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau);
self.soundnode.fab.add_r_amp(amp);
}
pub fn triangle(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const period = 44100 / freq;
const tp = (current_tick - (period * phase)) / period;
const amp = r_amp * (@abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1);
self.soundnode.fab.add_r_amp(amp);
}
pub fn square(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const sin = math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau);
if (sin > 0) {
self.soundnode.fab.add_r_amp(r_amp);
} else {
self.soundnode.fab.add_r_amp(-r_amp);
}
}
pub fn sawtooth(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const period = 44100 / freq;
const tp = (current_tick - (period * phase)) / period;
const amp = r_amp * (2 * (tp - @floor(0.5+tp)));
self.soundnode.fab.add_r_amp(amp);
}
pub fn setskew(self: *Activity) !void {
try self.soundnode.s("skew", self.operands[0]);
}
pub fn skewsine(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const skew = self.soundnode.g("skew");
if (skew == 0) {
const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau);
self.soundnode.fab.add_r_amp(amp);
} else if (skew > 0) {
const m = (utility.corrected_tau * freq * current_tick) - (phase * utility.tau);
const sincos = skew * math.sin(m) / (1 - skew*math.cos(m));
const amp = r_amp * ((1/skew) * math.atan(sincos));
self.soundnode.fab.add_r_amp(amp);
} else if (skew < 0) {
const m = (utility.corrected_tau * freq * current_tick);
const sincos = skew * math.cos(m) / (1 + skew*math.sin(m));
const amp = r_amp * ((1/skew) * math.atan(sincos));
self.soundnode.fab.add_r_amp(amp);
}
}
pub fn slidebasefreq(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startfreq = self.operands[0];
const endfreq = self.operands[1];
const x = (current_tick * (current_tick / 2)) - (start_tick*current_tick);
const xx = ((endfreq - startfreq) / (end_tick - start_tick)) * x;
const freq = ((startfreq * current_tick) + xx) / current_tick;
try self.soundnode.s("basefreq", freq);
}
pub fn slidebasefreq_iterative(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startfreq = self.operands[0];
const endfreq = self.operands[1];
const instfreq = utility.interpolate(current_tick, start_tick, end_tick, startfreq, endfreq);
const c = current_tick / 44100;
const prevphase = self.soundnode.g("phase");
const prevfreq = self.soundnode.g("basefreq");
const pp = prevphase + c*(instfreq - prevfreq) + @floor(c * prevfreq - prevphase);
const newphase = pp - @floor(pp);
try self.soundnode.s("phase", newphase);
try self.soundnode.s("basefreq", instfreq);
}
pub fn slidegain(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startgain = self.operands[0];
const endgain = self.operands[1];
const gain = utility.interpolate(current_tick, start_tick, end_tick, startgain, endgain);
try self.soundnode.s("gain", gain);
}
pub fn slidephase(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startphase = self.operands[0];
const endphase = self.operands[1];
const phase = utility.interpolate(current_tick, start_tick, end_tick, startphase, endphase);
try self.soundnode.s("phase", phase);
}
pub fn slideskew(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startskew = self.operands[0];
const endskew = self.operands[1];
const skew = utility.interpolate(current_tick, start_tick, end_tick, startskew, endskew);
try self.soundnode.s("skew", skew);
}
pub fn slidepos(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const start_x = self.operands[0];
const start_y = self.operands[1];
const start_z = self.operands[2];
const end_x = self.operands[3];
const end_y = self.operands[4];
const end_z = self.operands[5];
const x = utility.interpolate(current_tick, start_tick, end_tick, start_x, end_x);
const y = utility.interpolate(current_tick, start_tick, end_tick, start_y, end_y);
const z = utility.interpolate(current_tick, start_tick, end_tick, start_z, end_z);
self.soundnode.x = @as(f32, @floatCast(x));
self.soundnode.y = @as(f32, @floatCast(y));
self.soundnode.z = @as(f32, @floatCast(z));
}
pub fn pulse(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const period = 44100 / freq;
const tp = current_tick / period;
const tp_detract = (current_tick - (period * phase)) / period;
const amp =2 * (tp - @floor(0.5+tp));
const amp_detract = 2 * (tp_detract - @floor(0.5+tp_detract));
const final_amp = r_amp * (amp - amp_detract);
self.soundnode.fab.add_r_amp(final_amp);
}
pub fn fmsetup(self: *Activity) !void {
try self.soundnode.s("fmbasefreq", self.operands[0]);
try self.soundnode.s("instfreq", self.operands[0]);
try self.soundnode.s("fmq", self.operands[1]);
}
pub fn fm(self: *Activity) !void {
const current_tick: u32 = self.soundnode.fab.current_tick;
const fcurrent_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
var fprev_tick: f64 = 0;
if (fcurrent_tick > 0) {
fprev_tick = @floatFromInt(current_tick - 1);
}
const fmq = self.soundnode.g("fmq");
const fmbasefreq = self.soundnode.g("fmbasefreq");
const prevphase = self.soundnode.g("phase");
const prevfreq = self.soundnode.g("basefreq");
var srcamp: f64 = 0;
for (self.soundnode.wire_in.items, 0..) |wired_sn, i| {
if (wired_sn.active == 1) {
const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick);
srcamp += relayed_r_amp;
}
_ = i;
}
for (self.soundnode.air_in.items, 0..) |aired_sn, i| {
if (aired_sn.active == 1) {
const dist: f64 = self.soundnode.distance(aired_sn);
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 = aired_sn.fab.get_r_amp(b_sample_tick);
const n_r_amp = aired_sn.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;
srcamp += relayed_r_amp;
}
}
_ = i;
}
if (srcamp > 1) {
srcamp = 1;
} else if (srcamp < -1) {
srcamp = -1;
}
const instfreq = fmbasefreq + (fmbasefreq * fmq * srcamp);
const c = fcurrent_tick / 44100;
const pp = prevphase + c*(instfreq - prevfreq) + @floor(c * prevfreq - prevphase);
const newphase = pp - @floor(pp);
try self.soundnode.s("phase", newphase);
try self.soundnode.s("basefreq", instfreq);
}
pub fn am(self: *Activity) !void {
const current_tick: u32 = self.soundnode.fab.current_tick;
var srcamp: f64 = 0;
for (self.soundnode.wire_in.items, 0..) |wired_sn, i| {
const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick);
srcamp += relayed_r_amp;
_ = i;
}
for (self.soundnode.air_in.items, 0..) |aired_sn, i| {
const dist: f64 = self.soundnode.distance(aired_sn);
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 = aired_sn.fab.get_r_amp(b_sample_tick);
const n_r_amp = aired_sn.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;
srcamp += relayed_r_amp;
}
_ = i;
}
if (srcamp > 1) {
srcamp = 1;
} else if (srcamp < -1) {
srcamp = -1;
}
try self.soundnode.s("gain", srcamp);
}
pub fn mute(self: *Activity) !void {
try self.soundnode.s("gain", 0);
}
pub fn whitenoise(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const seed = self.operands[0];
const gainmult = self.operands[1];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const w = (seed*current_tick) / math.sin(current_tick);
const rnd = (2 * (w - @floor(w))) - 1;
const amp = r_amp * rnd;
self.soundnode.fab.add_r_amp(amp);
}
pub fn setadsrgain(self: *Activity) !void {
try self.soundnode.s("adsrgain", self.operands[0]);
}
pub fn setadsrsustain(self: *Activity) !void {
try self.soundnode.s("adsrsustain", self.operands[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.g("adsrgain");
const adsrsustain = self.soundnode.g("adsrsustain");
const attack_tick = self.operands[0];
const hold_tick = self.operands[1];
const decay_tick = self.operands[2];
const sustain_tick = self.operands[3];
const release_tick = self.operands[4];
const gainmult = self.operands[5];
if (gainmult > 0) {
adsrgain *= gainmult;
}
var gain: f64 = 0;
if (current_tick <= attack_tick) {
gain = adsrgain * current_tick / attack_tick;
} else if (current_tick <= hold_tick) {
gain = adsrgain;
} else if (current_tick <= decay_tick) {
gain = ((current_tick-hold_tick)*(adsrsustain-adsrgain)/(decay_tick - hold_tick)) + adsrgain;
} else if (current_tick <= sustain_tick) {
gain = adsrsustain;
} else if (current_tick <= release_tick) {
gain = (adsrsustain * (current_tick - sustain_tick) / (sustain_tick - release_tick)) + adsrsustain;
}
try self.soundnode.s("gain", gain);
}
};

View file

@ -35,29 +35,10 @@ pub const Activity = struct {
switch (self.opcode) {
4 => { self.relay(); },
5 => { self.setpos(); },
6 => { try self.setbasefreq(); },
7 => { try self.setgain(); },
8 => { try self.setphase(); },
6 => { self.setbasefreq(); },
7 => { self.setgain(); },
8 => { self.setbasephase(); },
9 => { self.sine(); },
10 => { self.triangle(); },
11 => { self.square(); },
12 => { self.sawtooth(); },
13 => { try self.setskew(); },
14 => { self.skewsine(); },
15 => { try self.slidebasefreq(); },
16 => { try self.slidegain(); },
17 => { try self.slidephase(); },
18 => { try self.slideskew(); },
19 => { self.slidepos(); },
20 => { self.pulse(); },
21 => { try self.fmsetup(); },
22 => { try self.fm(); },
23 => { try self.am(); },
24 => { try self.mute(); },
25 => { self.whitenoise(); },
26 => { try self.setadsrgain(); },
27 => { try self.setadsrsustain(); },
28 => { try self.adsr(); },
else => {},
}
}
@ -100,61 +81,21 @@ pub const Activity = struct {
pub fn relay(self: *Activity) void {
const current_tick: u32 = self.soundnode.fab.current_tick;
for (self.soundnode.wire_in.items, 0..) |wired_sn, i| {
if (wired_sn.active == 1) {
const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick);
self.soundnode.fab.add_r_amp(relayed_r_amp);
}
_ = i;
}
for (self.soundnode.air_in.items, 0..) |aired_sn, i| {
if (aired_sn.active == 1) {
const dist: f64 = self.soundnode.distance(aired_sn);
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 = aired_sn.fab.get_r_amp(b_sample_tick);
const n_r_amp = aired_sn.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.soundnode.fab.add_r_amp(relayed_r_amp);
}
}
_ = i;
}
self.soundnode.add_r_amp(self.soundnode.in_wire);
self.soundnode.add_r_amp(self.soundnode.in_air);
}
pub fn setbasefreq(self: *Activity) !void {
try self.soundnode.s("basefreq", self.operands[0]);
pub fn setbasefreq(self: *Activity) void {
self.soundnode.basefreq = self.operands[0];
}
pub fn setgain(self: *Activity) !void {
try self.soundnode.s("gain", self.operands[0]);
pub fn setgain(self: *Activity) void {
self.soundnode.gain = self.operands[0];
}
pub fn setphase(self: *Activity) !void {
try self.soundnode.s("phase", self.operands[0]);
pub fn setbasephase(self: *Activity) void {
self.soundnode.basephase = self.operands[0];
}
pub fn setpos(self: *Activity) void {
@ -168,463 +109,16 @@ pub const Activity = struct {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
var gain = self.soundnode.gain;
if (gainmult > 0) {
r_amp *= gainmult;
gain *= gainmult;
}
const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau);
self.soundnode.fab.add_r_amp(amp);
}
pub fn triangle(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const period = 44100 / freq;
const tp = (current_tick - (period * phase)) / period;
const amp = r_amp * (@abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1);
self.soundnode.fab.add_r_amp(amp);
}
pub fn square(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const sin = math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau);
if (sin > 0) {
self.soundnode.fab.add_r_amp(r_amp);
} else {
self.soundnode.fab.add_r_amp(-r_amp);
}
}
pub fn sawtooth(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const period = 44100 / freq;
const tp = (current_tick - (period * phase)) / period;
const amp = r_amp * (2 * (tp - @floor(0.5+tp)));
self.soundnode.fab.add_r_amp(amp);
}
pub fn setskew(self: *Activity) !void {
try self.soundnode.s("skew", self.operands[0]);
}
pub fn skewsine(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const skew = self.soundnode.g("skew");
if (skew == 0) {
const amp = r_amp * math.sin(utility.corrected_tau * freq * current_tick - phase * utility.tau);
self.soundnode.fab.add_r_amp(amp);
} else if (skew > 0) {
const m = (utility.corrected_tau * freq * current_tick) - (phase * utility.tau);
const sincos = skew * math.sin(m) / (1 - skew*math.cos(m));
const amp = r_amp * ((1/skew) * math.atan(sincos));
self.soundnode.fab.add_r_amp(amp);
} else if (skew < 0) {
const m = (utility.corrected_tau * freq * current_tick);
const sincos = skew * math.cos(m) / (1 + skew*math.sin(m));
const amp = r_amp * ((1/skew) * math.atan(sincos));
self.soundnode.fab.add_r_amp(amp);
}
}
pub fn slidebasefreq(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startfreq = self.operands[0];
const endfreq = self.operands[1];
const x = (current_tick * (current_tick / 2)) - (start_tick*current_tick);
const xx = ((endfreq - startfreq) / (end_tick - start_tick)) * x;
const freq = ((startfreq * current_tick) + xx) / current_tick;
try self.soundnode.s("basefreq", freq);
}
pub fn slidebasefreq_iterative(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startfreq = self.operands[0];
const endfreq = self.operands[1];
const instfreq = utility.interpolate(current_tick, start_tick, end_tick, startfreq, endfreq);
const c = current_tick / 44100;
const prevphase = self.soundnode.g("phase");
const prevfreq = self.soundnode.g("basefreq");
const pp = prevphase + c*(instfreq - prevfreq) + @floor(c * prevfreq - prevphase);
const newphase = pp - @floor(pp);
try self.soundnode.s("phase", newphase);
try self.soundnode.s("basefreq", instfreq);
}
pub fn slidegain(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startgain = self.operands[0];
const endgain = self.operands[1];
const gain = utility.interpolate(current_tick, start_tick, end_tick, startgain, endgain);
try self.soundnode.s("gain", gain);
}
pub fn slidephase(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startphase = self.operands[0];
const endphase = self.operands[1];
const phase = utility.interpolate(current_tick, start_tick, end_tick, startphase, endphase);
try self.soundnode.s("phase", phase);
}
pub fn slideskew(self: *Activity) !void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const startskew = self.operands[0];
const endskew = self.operands[1];
const skew = utility.interpolate(current_tick, start_tick, end_tick, startskew, endskew);
try self.soundnode.s("skew", skew);
}
pub fn slidepos(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const start_tick: f64 = @floatFromInt(self.start_tick);
const end_tick: f64 = @floatFromInt(self.end_tick);
const start_x = self.operands[0];
const start_y = self.operands[1];
const start_z = self.operands[2];
const end_x = self.operands[3];
const end_y = self.operands[4];
const end_z = self.operands[5];
const x = utility.interpolate(current_tick, start_tick, end_tick, start_x, end_x);
const y = utility.interpolate(current_tick, start_tick, end_tick, start_y, end_y);
const z = utility.interpolate(current_tick, start_tick, end_tick, start_z, end_z);
self.soundnode.x = @as(f32, @floatCast(x));
self.soundnode.y = @as(f32, @floatCast(y));
self.soundnode.z = @as(f32, @floatCast(z));
}
pub fn pulse(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const freq = self.soundnode.g("basefreq");
const phase = self.soundnode.g("phase");
const gainmult = self.operands[0];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const period = 44100 / freq;
const tp = current_tick / period;
const tp_detract = (current_tick - (period * phase)) / period;
const amp =2 * (tp - @floor(0.5+tp));
const amp_detract = 2 * (tp_detract - @floor(0.5+tp_detract));
const final_amp = r_amp * (amp - amp_detract);
self.soundnode.fab.add_r_amp(final_amp);
}
pub fn fmsetup(self: *Activity) !void {
try self.soundnode.s("fmbasefreq", self.operands[0]);
try self.soundnode.s("instfreq", self.operands[0]);
try self.soundnode.s("fmq", self.operands[1]);
}
pub fn fm(self: *Activity) !void {
const current_tick: u32 = self.soundnode.fab.current_tick;
const fcurrent_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
var fprev_tick: f64 = 0;
if (fcurrent_tick > 0) {
fprev_tick = @floatFromInt(current_tick - 1);
}
const fmq = self.soundnode.g("fmq");
const fmbasefreq = self.soundnode.g("fmbasefreq");
const prevphase = self.soundnode.g("phase");
const prevfreq = self.soundnode.g("basefreq");
var srcamp: f64 = 0;
for (self.soundnode.wire_in.items, 0..) |wired_sn, i| {
if (wired_sn.active == 1) {
const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick);
srcamp += relayed_r_amp;
}
_ = i;
}
for (self.soundnode.air_in.items, 0..) |aired_sn, i| {
if (aired_sn.active == 1) {
const dist: f64 = self.soundnode.distance(aired_sn);
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 = aired_sn.fab.get_r_amp(b_sample_tick);
const n_r_amp = aired_sn.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;
srcamp += relayed_r_amp;
}
}
_ = i;
}
if (srcamp > 1) {
srcamp = 1;
} else if (srcamp < -1) {
srcamp = -1;
}
const instfreq = fmbasefreq + (fmbasefreq * fmq * srcamp);
const c = fcurrent_tick / 44100;
const pp = prevphase + c*(instfreq - prevfreq) + @floor(c * prevfreq - prevphase);
const newphase = pp - @floor(pp);
try self.soundnode.s("phase", newphase);
try self.soundnode.s("basefreq", instfreq);
}
pub fn am(self: *Activity) !void {
const current_tick: u32 = self.soundnode.fab.current_tick;
var srcamp: f64 = 0;
for (self.soundnode.wire_in.items, 0..) |wired_sn, i| {
const relayed_r_amp = wired_sn.fab.get_r_amp(current_tick);
srcamp += relayed_r_amp;
_ = i;
}
for (self.soundnode.air_in.items, 0..) |aired_sn, i| {
const dist: f64 = self.soundnode.distance(aired_sn);
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 = aired_sn.fab.get_r_amp(b_sample_tick);
const n_r_amp = aired_sn.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;
srcamp += relayed_r_amp;
}
_ = i;
}
if (srcamp > 1) {
srcamp = 1;
} else if (srcamp < -1) {
srcamp = -1;
}
try self.soundnode.s("gain", srcamp);
}
pub fn mute(self: *Activity) !void {
try self.soundnode.s("gain", 0);
}
pub fn whitenoise(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const seed = self.operands[0];
const gainmult = self.operands[1];
var r_amp = self.soundnode.g("gain");
if (gainmult > 0) {
r_amp *= gainmult;
}
const w = (seed*current_tick) / math.sin(current_tick);
const rnd = (2 * (w - @floor(w))) - 1;
const amp = r_amp * rnd;
self.soundnode.fab.add_r_amp(amp);
}
pub fn setadsrgain(self: *Activity) !void {
try self.soundnode.s("adsrgain", self.operands[0]);
}
pub fn setadsrsustain(self: *Activity) !void {
try self.soundnode.s("adsrsustain", self.operands[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.g("adsrgain");
const adsrsustain = self.soundnode.g("adsrsustain");
const attack_tick = self.operands[0];
const hold_tick = self.operands[1];
const decay_tick = self.operands[2];
const sustain_tick = self.operands[3];
const release_tick = self.operands[4];
const gainmult = self.operands[5];
if (gainmult > 0) {
adsrgain *= gainmult;
}
var gain: f64 = 0;
if (current_tick <= attack_tick) {
gain = adsrgain * current_tick / attack_tick;
} else if (current_tick <= hold_tick) {
gain = adsrgain;
} else if (current_tick <= decay_tick) {
gain = ((current_tick-hold_tick)*(adsrsustain-adsrgain)/(decay_tick - hold_tick)) + adsrgain;
} else if (current_tick <= sustain_tick) {
gain = adsrsustain;
} else if (current_tick <= release_tick) {
gain = (adsrsustain * (current_tick - sustain_tick) / (sustain_tick - release_tick)) + adsrsustain;
}
try self.soundnode.s("gain", gain);
const amp = gain * math.sin(utility.corrected_tau * self.soundnode.basefreq * current_tick - self.soundnode.basephase * utility.tau);
self.soundnode.add_r_amp(amp);
}
};

267
zigsonnum/pin.zig Normal file
View file

@ -0,0 +1,267 @@
const std = @import("std");
const SoundNode = @import("soundnode.zig").SoundNode;
const Allocator = std.mem.Allocator;
pub const Pin = struct {
uid: usize = 0,
allocator: Allocator,
src_node: *SoundNode,
trg_node: *SoundNode,
src_pin: usize = 0,
trg_pin: usize = 0,
active: u8 = 0,
pub fn create(allocator: Allocator,
uid: usize,
src_node: *SoundNode,
trg_node: *SoundNode,
src_pin: usize,
trg_pin: usize) !*Pin {
const pin = try allocator.create(Pin);
pin.* = .{
.allocator = allocator,
.uid = uid,
.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 => {},
}
}
};

View file

@ -6,6 +6,7 @@ const ArrayList = std.ArrayList;
const Endian = std.builtin.Endian;
const SoundNode = @import("soundnode.zig").SoundNode;
const Pin = @import ("pin.zig").Pin;
const Activity = @import("activity.zig").Activity;
const SoundSettings = @import("settings.zig").SoundSettings;
const utility = @import("utility.zig");
@ -54,6 +55,44 @@ pub fn removeSoundNodeFromList(snlist: *ArrayList(*SoundNode), sn: *SoundNode) u
}
pub fn returnPinToList(pinlist: *ArrayList(*Pin), pn: *Pin) !void {
for (pinlist.items, 0..) |pin, ind| {
if (pn.uid < pin.uid) {
try pinlist.insert(ind, pn);
return;
}
}
try pinlist.append(pn);
return;
}
pub fn removePinFromList(pinlist: *ArrayList(*Pin), pn: *Pin) !void {
var found: u8 = 0;
var toremove: usize = 0;
for (pinlist.items, 0..) |pin, ind| {
if (pn.uid == pin.uid) {
toremove = ind;
found = 1;
}
}
if (found == 1) {
_ = pinlist.orderedRemove(toremove);
}
return found;
}
pub fn reactivateSoundNode(alist: *ArrayList(*SoundNode), plist: *ArrayList(*SoundNode), sn: *SoundNode) !void {
const remove_success = removeSoundNodeFromList(plist, sn);
@ -70,6 +109,22 @@ pub fn deactivateSoundNode(alist: *ArrayList(*SoundNode), plist: *ArrayList(*Sou
}
pub fn reactivatePin(alist: *ArrayList(*Pin), plist: *ArrayList(*Pin), pn: *Pin) !void {
const remove_success = removePinFromList(plist, pn);
_ = remove_success;
try returnSoundNodeToList(alist, pn);
}
pub fn deactivatePin(alist: *ArrayList(*Pin), plist: *ArrayList(*Pin), pn: *Pin) !void {
const remove_success = removePinFromList(alist, pn);
_ = remove_success;
try plist.append(pn);
}
pub fn main() !void {
const allocator = std.heap.c_allocator;
@ -81,11 +136,17 @@ pub fn main() !void {
var soundnodes = ArrayList(*SoundNode).init(allocator);
defer soundnodes.deinit();
// Active and passive soundnodes
var a_soundnodes = ArrayList(*SoundNode).init(allocator);
defer a_soundnodes.deinit();
var p_soundnodes = ArrayList(*SoundNode).init(allocator);
defer p_soundnodes.deinit();
// Creating a list of soundnodes
var pins = ArrayList(*Pin).init(allocator);
defer pins.deinit();
// Determining length of resulting audio in ticks
const start_tick: u32 = 0;
var end_tick: u32 = 44100 * 10;
@ -216,18 +277,12 @@ pub fn main() !void {
switch (opcode) {
0 => {
const nodename = try std.fmt.allocPrint(allocator, "{d}", .{src_node});
const uid: usize = @as(usize, src_node);
const sn = try SoundNode.create(allocator, nodename, uid);
const sn = try SoundNode.create(allocator, uid);
//print("Added node {s} at tick {d}\n", .{nodename, tick});
try soundnodes.append(sn);
try p_soundnodes.append(sn);
try sn.s("basefreq", @as(f64, 440));
try sn.s("gain", @as(f64, 1));
try sn.s("phase", @as(f64, 0));
},
1 => {
@ -235,29 +290,26 @@ pub fn main() !void {
const trg = soundnodes.items[trg_node];
//print("Wired nodes at tick {d}\n", .{tick});
try trg.wire_in.append(src);
try src.wire_targets.append(trg);
},
const uid: usize = pins.items.len;
const src_pin: usize = @intFromFloat(op1);
const trg_pin: usize = @intFromFloat(op2);
2 => {
const src = soundnodes.items[src_node];
const trg = soundnodes.items[trg_node];
const pin = try Pin.create(allocator, uid, src, trg, src_pin, trg_pin);
//print("Aired nodes at tick {d}\n", .{tick});
try trg.air_in.append(src);
try src.air_targets.append(trg);
try pins.append(pin);
try src.pins.append(pin);
},
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});
},
Endian.little);
},
else => {
@ -270,6 +322,12 @@ pub fn main() !void {
if (src.activities.items.len == 1 and src.active == 0) {
src.active = 1;
try reactivateSoundNode(&a_soundnodes, &p_soundnodes, src);
for (src.pins.items, 0..) |pin, zj| {
pin.active = 1;
_ = zj;
}
}
},
@ -282,38 +340,62 @@ pub fn main() !void {
}
for (soundnodes.items, 0..) |soundnode, i| {
soundnode.nullizeStartTick();
_ = i;
}
//All but left and right
for (soundnodes.items[2..], 0..) |soundnode, i| {
if (a_soundnodes.items.len > 2) {
for (a_soundnodes.items[2..], 0..) |soundnode, i| {
var toremove = ArrayList(usize).init(allocator);
defer toremove.deinit();
var toremove = ArrayList(usize).init(allocator);
defer toremove.deinit();
for (soundnode.activities.items, 0..) |activity, j| {
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 (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];
_ = soundnode.activities.swapRemove(activity_ind);
if (soundnode.activities.items.len == 0 and soundnode.active == 1) {
soundnode.active = 0;
try deactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode);
for (soundnode.pins.items, 0..) |pin, zj| {
pin.propagate();
_ = zj;
}
}
var j: usize = toremove.items.len;
while (j > 0) {
j -= 1;
const activity_ind = toremove.items[j];
_ = soundnode.activities.swapRemove(activity_ind);
if (soundnode.activities.items.len == 0 and soundnode.active == 1) {
soundnode.active = 0;
try deactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode);
for (soundnode.pins.items, 0..) |pin, zj| {
pin.active = 0;
_ = zj;
}
}
}
soundnode.fab.increment_tick();
_ = i;
}
}
// Incrementing passive ones too
for (p_soundnodes.items, 0..) |soundnode, i| {
soundnode.fab.increment_tick();
_ = i;
}
@ -335,6 +417,11 @@ pub fn main() !void {
}
for (soundnode.pins.items, 0..) |pin, jz| {
pin.propagate();
_ = jz;
}
var j: usize = toremove.items.len;
while (j > 0) {
@ -351,12 +438,10 @@ pub fn main() !void {
left = soundnodes.items[0];
right = soundnodes.items[1];
const current_r_amp_left = left.fab.get_current_r_amp();
sample = @intFromFloat(current_r_amp_left * settings.max_amp_multiplier);
sample = @intFromFloat(left.r_amp * settings.max_amp_multiplier);
try stdout.writeInt(i24, sample, Endian.little);
const current_r_amp_right = right.fab.get_current_r_amp();
sample = @intFromFloat(current_r_amp_right * settings.max_amp_multiplier);
sample = @intFromFloat(right.r_amp * settings.max_amp_multiplier);
try stdout.writeInt(i24, sample, Endian.little);
left.fab.increment_tick();

View file

@ -10,6 +10,7 @@ const StringHashMap = std.StringHashMap;
const pnt = @import("point.zig");
const Pnt = pnt.Pnt;
const Pin = @import("pin.zig").Pin;
const Activity = @import("activity.zig").Activity;
const SoundSettings = @import("settings.zig").SoundSettings;
const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer;
@ -22,6 +23,178 @@ pub const SoundNode = struct {
allocator: Allocator,
uid: usize = 0,
// 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),
pins: ArrayList(*Pin),
props: StringHashMap(f64),
x: f32 = 0,
y: f32 = 0,
z: f32 = 0,
fab: FreqAmpBuffer,
active: u8 = 1,
pub fn nullizeStartTick(self: *SoundNode) void {
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;
}
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 = 0,
.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 {
self.activities.deinit();
self.fab.deinit();
self.props.deinit();
}
pub fn current_tick(self: *SoundNode) u32 {
return self.fab.current_tick;
}
pub fn add_r_amp(self: *SoundNode, r_amp: f64) void {
self.fab.add_r_amp(r_amp);
self.r_amp += r_amp;
}
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);
}
};
pub const SoundNodeOld = struct {
allocator: Allocator,
name: []const u8 = "soundnode",
uid: usize = 0,