major overhaul
This commit is contained in:
parent
8362e1643c
commit
3f30771451
9 changed files with 1213 additions and 581 deletions
9
mysynths/sintest.py
Normal file
9
mysynths/sintest.py
Normal 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)
|
||||||
|
|
@ -3,14 +3,13 @@ import struct
|
||||||
OPCODES = {
|
OPCODES = {
|
||||||
|
|
||||||
'create': 0,
|
'create': 0,
|
||||||
'wire': 1,
|
'pin': 1,
|
||||||
'air': 2,
|
|
||||||
'endtick': 3,
|
'endtick': 3,
|
||||||
'relay': 4,
|
'relay': 4,
|
||||||
'setpos': 5,
|
'setpos': 5,
|
||||||
'setbasefreq': 6,
|
'setbasefreq': 6,
|
||||||
'setgain': 7,
|
'setgain': 7,
|
||||||
'setphase': 8,
|
'setbasephase': 8,
|
||||||
'sine': 9,
|
'sine': 9,
|
||||||
'triangle': 10,
|
'triangle': 10,
|
||||||
'square': 11,
|
'square': 11,
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ class SonnumCompiler:
|
||||||
to_delete = []
|
to_delete = []
|
||||||
for activity in self.activities:
|
for activity in self.activities:
|
||||||
|
|
||||||
if activity.name in ('wire','air'):
|
if activity.name in ('wire','air','pin'):
|
||||||
new.append(activity)
|
new.append(activity)
|
||||||
to_delete.append(activity)
|
to_delete.append(activity)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ class Sonnum:
|
||||||
|
|
||||||
for src_node in src_nodes:
|
for src_node in src_nodes:
|
||||||
for trg_node in trg_nodes:
|
for trg_node in trg_nodes:
|
||||||
self.act('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):
|
def air(self, src_nodes, trg_nodes):
|
||||||
|
|
||||||
|
|
@ -91,4 +91,16 @@ class Sonnum:
|
||||||
|
|
||||||
for src_node in src_nodes:
|
for src_node in src_nodes:
|
||||||
for trg_node in trg_nodes:
|
for trg_node in trg_nodes:
|
||||||
self.act('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
593
zigsonnum/activity.bak.zig
Normal 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -35,29 +35,10 @@ pub const Activity = struct {
|
||||||
switch (self.opcode) {
|
switch (self.opcode) {
|
||||||
4 => { self.relay(); },
|
4 => { self.relay(); },
|
||||||
5 => { self.setpos(); },
|
5 => { self.setpos(); },
|
||||||
6 => { try self.setbasefreq(); },
|
6 => { self.setbasefreq(); },
|
||||||
7 => { try self.setgain(); },
|
7 => { self.setgain(); },
|
||||||
8 => { try self.setphase(); },
|
8 => { self.setbasephase(); },
|
||||||
9 => { self.sine(); },
|
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 => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -100,61 +81,21 @@ pub const Activity = struct {
|
||||||
|
|
||||||
pub fn relay(self: *Activity) void {
|
pub fn relay(self: *Activity) void {
|
||||||
|
|
||||||
const current_tick: u32 = self.soundnode.fab.current_tick;
|
self.soundnode.add_r_amp(self.soundnode.in_wire);
|
||||||
|
self.soundnode.add_r_amp(self.soundnode.in_air);
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setbasefreq(self: *Activity) !void {
|
pub fn setbasefreq(self: *Activity) void {
|
||||||
try self.soundnode.s("basefreq", self.operands[0]);
|
self.soundnode.basefreq = self.operands[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setgain(self: *Activity) !void {
|
pub fn setgain(self: *Activity) void {
|
||||||
try self.soundnode.s("gain", self.operands[0]);
|
self.soundnode.gain = self.operands[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setphase(self: *Activity) !void {
|
pub fn setbasephase(self: *Activity) void {
|
||||||
try self.soundnode.s("phase", self.operands[0]);
|
self.soundnode.basephase = self.operands[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setpos(self: *Activity) void {
|
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 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];
|
const gainmult = self.operands[0];
|
||||||
var r_amp = self.soundnode.g("gain");
|
|
||||||
|
var gain = self.soundnode.gain;
|
||||||
|
|
||||||
if (gainmult > 0) {
|
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
267
zigsonnum/pin.zig
Normal 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 => {},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -6,6 +6,7 @@ const ArrayList = std.ArrayList;
|
||||||
const Endian = std.builtin.Endian;
|
const Endian = std.builtin.Endian;
|
||||||
|
|
||||||
const SoundNode = @import("soundnode.zig").SoundNode;
|
const SoundNode = @import("soundnode.zig").SoundNode;
|
||||||
|
const Pin = @import ("pin.zig").Pin;
|
||||||
const Activity = @import("activity.zig").Activity;
|
const Activity = @import("activity.zig").Activity;
|
||||||
const SoundSettings = @import("settings.zig").SoundSettings;
|
const SoundSettings = @import("settings.zig").SoundSettings;
|
||||||
const utility = @import("utility.zig");
|
const utility = @import("utility.zig");
|
||||||
|
|
@ -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 {
|
pub fn reactivateSoundNode(alist: *ArrayList(*SoundNode), plist: *ArrayList(*SoundNode), sn: *SoundNode) !void {
|
||||||
|
|
||||||
const remove_success = removeSoundNodeFromList(plist, sn);
|
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 {
|
pub fn main() !void {
|
||||||
|
|
||||||
const allocator = std.heap.c_allocator;
|
const allocator = std.heap.c_allocator;
|
||||||
|
|
@ -80,12 +135,18 @@ pub fn main() !void {
|
||||||
// Creating a list of soundnodes
|
// Creating a list of soundnodes
|
||||||
var soundnodes = ArrayList(*SoundNode).init(allocator);
|
var soundnodes = ArrayList(*SoundNode).init(allocator);
|
||||||
defer soundnodes.deinit();
|
defer soundnodes.deinit();
|
||||||
|
|
||||||
|
// Active and passive soundnodes
|
||||||
|
|
||||||
var a_soundnodes = ArrayList(*SoundNode).init(allocator);
|
var a_soundnodes = ArrayList(*SoundNode).init(allocator);
|
||||||
defer a_soundnodes.deinit();
|
defer a_soundnodes.deinit();
|
||||||
var p_soundnodes = ArrayList(*SoundNode).init(allocator);
|
var p_soundnodes = ArrayList(*SoundNode).init(allocator);
|
||||||
defer p_soundnodes.deinit();
|
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
|
// Determining length of resulting audio in ticks
|
||||||
const start_tick: u32 = 0;
|
const start_tick: u32 = 0;
|
||||||
var end_tick: u32 = 44100 * 10;
|
var end_tick: u32 = 44100 * 10;
|
||||||
|
|
@ -216,18 +277,12 @@ pub fn main() !void {
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
|
||||||
0 => {
|
0 => {
|
||||||
const nodename = try std.fmt.allocPrint(allocator, "{d}", .{src_node});
|
|
||||||
|
|
||||||
const uid: usize = @as(usize, 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});
|
//print("Added node {s} at tick {d}\n", .{nodename, tick});
|
||||||
try soundnodes.append(sn);
|
try soundnodes.append(sn);
|
||||||
try p_soundnodes.append(sn);
|
try p_soundnodes.append(sn);
|
||||||
|
|
||||||
try sn.s("basefreq", @as(f64, 440));
|
|
||||||
try sn.s("gain", @as(f64, 1));
|
|
||||||
try sn.s("phase", @as(f64, 0));
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
1 => {
|
1 => {
|
||||||
|
|
@ -235,29 +290,26 @@ pub fn main() !void {
|
||||||
const trg = soundnodes.items[trg_node];
|
const trg = soundnodes.items[trg_node];
|
||||||
//print("Wired nodes at tick {d}\n", .{tick});
|
//print("Wired nodes at tick {d}\n", .{tick});
|
||||||
|
|
||||||
try trg.wire_in.append(src);
|
const uid: usize = pins.items.len;
|
||||||
try src.wire_targets.append(trg);
|
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];
|
|
||||||
|
|
||||||
//print("Aired nodes at tick {d}\n", .{tick});
|
const pin = try Pin.create(allocator, uid, src, trg, src_pin, trg_pin);
|
||||||
try trg.air_in.append(src);
|
|
||||||
try src.air_targets.append(trg);
|
try pins.append(pin);
|
||||||
|
try src.pins.append(pin);
|
||||||
},
|
},
|
||||||
|
|
||||||
3 => {
|
3 => {
|
||||||
|
|
||||||
end_tick = tick_end;
|
end_tick = tick_end;
|
||||||
|
|
||||||
try stdout.writeInt(
|
try stdout.writeInt(
|
||||||
u32,
|
u32,
|
||||||
end_tick * 2 * settings.sample_width,
|
end_tick * 2 * settings.sample_width,
|
||||||
Endian.little,
|
Endian.little);
|
||||||
);
|
|
||||||
//print("End tick set to {d}\n", .{end_tick});
|
},
|
||||||
},
|
|
||||||
|
|
||||||
else => {
|
else => {
|
||||||
|
|
||||||
|
|
@ -270,6 +322,12 @@ pub fn main() !void {
|
||||||
if (src.activities.items.len == 1 and src.active == 0) {
|
if (src.activities.items.len == 1 and src.active == 0) {
|
||||||
src.active = 1;
|
src.active = 1;
|
||||||
try reactivateSoundNode(&a_soundnodes, &p_soundnodes, src);
|
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
|
//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();
|
|
||||||
|
|
||||||
for (soundnode.activities.items, 0..) |activity, j| {
|
var toremove = ArrayList(usize).init(allocator);
|
||||||
|
defer toremove.deinit();
|
||||||
if (tick <= activity.end_tick and tick >= activity.start_tick) {
|
|
||||||
try activity.do();
|
for (soundnode.activities.items, 0..) |activity, j| {
|
||||||
} 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) {
|
for (soundnode.pins.items, 0..) |pin, zj| {
|
||||||
j -= 1;
|
pin.propagate();
|
||||||
const activity_ind = toremove.items[j];
|
_ = 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.activities.swapRemove(activity_ind);
|
soundnode.active = 0;
|
||||||
|
try deactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode);
|
||||||
if (soundnode.activities.items.len == 0 and soundnode.active == 1) {
|
|
||||||
|
for (soundnode.pins.items, 0..) |pin, zj| {
|
||||||
soundnode.active = 0;
|
pin.active = 0;
|
||||||
try deactivateSoundNode(&a_soundnodes, &p_soundnodes, soundnode);
|
_ = zj;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
soundnode.fab.increment_tick();
|
||||||
|
_ = i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Incrementing passive ones too
|
||||||
|
|
||||||
|
for (p_soundnodes.items, 0..) |soundnode, i| {
|
||||||
soundnode.fab.increment_tick();
|
soundnode.fab.increment_tick();
|
||||||
_ = i;
|
_ = 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;
|
var j: usize = toremove.items.len;
|
||||||
|
|
||||||
while (j > 0) {
|
while (j > 0) {
|
||||||
|
|
@ -351,12 +438,10 @@ pub fn main() !void {
|
||||||
left = soundnodes.items[0];
|
left = soundnodes.items[0];
|
||||||
right = soundnodes.items[1];
|
right = soundnodes.items[1];
|
||||||
|
|
||||||
const current_r_amp_left = left.fab.get_current_r_amp();
|
sample = @intFromFloat(left.r_amp * settings.max_amp_multiplier);
|
||||||
sample = @intFromFloat(current_r_amp_left * settings.max_amp_multiplier);
|
|
||||||
try stdout.writeInt(i24, sample, Endian.little);
|
try stdout.writeInt(i24, sample, Endian.little);
|
||||||
|
|
||||||
const current_r_amp_right = right.fab.get_current_r_amp();
|
sample = @intFromFloat(right.r_amp * settings.max_amp_multiplier);
|
||||||
sample = @intFromFloat(current_r_amp_right * settings.max_amp_multiplier);
|
|
||||||
try stdout.writeInt(i24, sample, Endian.little);
|
try stdout.writeInt(i24, sample, Endian.little);
|
||||||
|
|
||||||
left.fab.increment_tick();
|
left.fab.increment_tick();
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ const StringHashMap = std.StringHashMap;
|
||||||
|
|
||||||
const pnt = @import("point.zig");
|
const pnt = @import("point.zig");
|
||||||
const Pnt = pnt.Pnt;
|
const Pnt = pnt.Pnt;
|
||||||
|
const Pin = @import("pin.zig").Pin;
|
||||||
const Activity = @import("activity.zig").Activity;
|
const Activity = @import("activity.zig").Activity;
|
||||||
const SoundSettings = @import("settings.zig").SoundSettings;
|
const SoundSettings = @import("settings.zig").SoundSettings;
|
||||||
const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer;
|
const FreqAmpBuffer = @import("freqamp.zig").FreqAmpBuffer;
|
||||||
|
|
@ -22,6 +23,178 @@ pub const SoundNode = struct {
|
||||||
|
|
||||||
allocator: Allocator,
|
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",
|
name: []const u8 = "soundnode",
|
||||||
uid: usize = 0,
|
uid: usize = 0,
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue