sonnum/zigsonnum/activity.zig

149 lines
No EOL
4.2 KiB
Zig

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 utility = @import("utility.zig");
const basicsynths = @import ("activities/basicsynths.zig");
const spatial = @import ("activities/spatial.zig");
const generators = @import ("activities/generators.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) {
//STARTOPCODES
4 => { self.relay(); },
5 => { self.copy(); },
6 => { self.mute(); },
7 => { self.rerange(); },
10 => { spatial.setpos(self); },
50 => { basicsynths.sine(self); },
51 => { basicsynths.triangle(self); },
52 => { basicsynths.square(self); },
53 => { basicsynths.sawtooth(self); },
54 => { basicsynths.skewsine(self); },
55 => { basicsynths.pulse(self); },
56 => { basicsynths.whitenoise(self); },
//100 => { generators.singenN(self); },
150 => { generators.adsr(self); },
//ENDOPCODES
else => {},
}
}
pub fn relay(self: *Activity) void {
self.soundnode.add_r_amp(self.soundnode.pins[1] * self.soundnode.pins[32]);
self.soundnode.add_r_amp(self.soundnode.pins[2] * self.soundnode.pins[32]);
}
pub fn copy(self: *Activity) void {
const from_pin: usize = @intFromFloat(self.operands[0]);
const to_pin: usize = @intFromFloat(self.operands[1]);
// Special case: setting freq results in setting calculating new phase too
if (to_pin >= 64 and to_pin < 112) {
const freq_no = to_pin - 64;
const fcurrent_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const prevphase = self.soundnode.pins[208 + freq_no];
const prevfreq = self.soundnode.pins[to_pin];
const newfreq = self.soundnode.pins[from_pin];
self.soundnode.pins[to_pin] = newfreq;
const c = fcurrent_tick / 44100;
const pp = prevphase + c * (newfreq - prevfreq) + @floor(c * prevfreq - prevphase);
self.soundnode.pins[208 + freq_no] = pp - @floor(pp);
} else {
self.soundnode.pins[to_pin] = self.soundnode.pins[from_pin];
}
}
pub fn rerange(self: *Activity) void {
const from_pin: usize = @intFromFloat(self.operands[0]);
const to_pin: usize = @intFromFloat(self.operands[1]);
const from_lo = self.operands[2];
const from_hi = self.operands[3];
const to_lo = self.operands[4];
const to_hi = self.operands[5];
// Special case: setting freq results in setting calculating new phase too
if (to_pin >= 64 and to_pin < 112) {
const freq_no = to_pin - 64;
const fcurrent_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const prevphase = self.soundnode.pins[208 + freq_no];
const prevfreq = self.soundnode.pins[to_pin];
//const newfreq = self.soundnode.pins[from_pin];
const share = (self.soundnode.pins[from_pin] - from_lo) / (from_hi - from_lo);
const newfreq = to_lo + ((to_hi - to_lo) * share);
//print("ORIG {d} SHARE {d} NEWFREQ {d} ", .{self.soundnode.pins[from_pin], share, newfreq});
self.soundnode.pins[to_pin] = newfreq;
const c = fcurrent_tick / 44100;
const pp = prevphase + c * (newfreq - prevfreq) + @floor(c * prevfreq - prevphase);
//print("OLDPHASE {d} NEWPHASE {d} :: ", .{self.soundnode.pins[208 + freq_no], pp - @floor(pp)});
self.soundnode.pins[208 + freq_no] = pp - @floor(pp);
} else {
const share = (self.soundnode.pins[from_pin] - from_lo) / (from_hi - from_lo);
self.soundnode.pins[to_pin] = to_lo + ((to_hi - to_lo) * share);
}
}
pub fn mute(self: *Activity) void {
self.soundnode.fab.set_r_amp(0);
self.soundnode.pins[0] = 0;
}
};