sonnum/zigsonnum/link.zig
2025-09-20 23:53:16 +03:00

92 lines
No EOL
2.3 KiB
Zig

const std = @import("std");
const print = std.debug.print;
const SoundNode = @import("soundnode.zig").SoundNode;
const Allocator = std.mem.Allocator;
pub const Link = struct {
allocator: Allocator,
src_node: *SoundNode,
trg_node: *SoundNode,
src_pin: usize = 0,
trg_pin: usize = 0,
active: u8 = 0,
pub fn create(allocator: Allocator,
src_node: *SoundNode,
trg_node: *SoundNode,
src_pin: usize,
trg_pin: usize) !*Link {
const link = try allocator.create(Link);
link.* = .{
.allocator = allocator,
.src_node = src_node,
.trg_node = trg_node,
.src_pin = src_pin,
.trg_pin = trg_pin,
.active = 0,
};
return link;
}
pub fn propagate(self: *Link) void {
// Special case for air_in (pin 2)
if (self.trg_pin == 2) {
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));
self.trg_node.pins[2] += (b_r_amp + (tick_diff * (n_r_amp - b_r_amp))) * attenuation;
}
// Special case: setting freq results in setting calculating new phase too
} else if (self.trg_pin >= 64 and self.trg_pin < 112) {
const freq_no = self.trg_pin - 64;
const fcurrent_tick: f64 = @floatFromInt(self.src_node.fab.current_tick);
const prevphase = self.trg_node.pins[208 + freq_no];
const prevfreq = self.trg_node.pins[self.trg_pin];
const newfreq = self.src_node.pins[self.src_pin];
self.trg_node.pins[self.trg_pin] = newfreq;
const c = fcurrent_tick / 44100;
const pp = prevphase + c * (newfreq - prevfreq) + @floor(c * prevfreq - prevphase);
self.trg_node.pins[208 + freq_no] = pp - @floor(pp);
} else {
self.trg_node.pins[self.trg_pin] += self.src_node.pins[self.src_pin];
}
}
};