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; } };