const std = @import("std"); const math = std.math; const print = std.debug.print; const Activity = @import ("../activity.zig").Activity; const SoundNode = @import("../soundnode.zig").SoundNode; const utility = @import("../utility.zig"); const dbg = utility.dbg; const idbg = utility.idbg; // Produces a sine wave (range N) // y = M * sin(TF + P) + L pub fn singenN(self: *Activity) void { const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick); const magnitude = self.operands[0]; const phase = self.operands[1]; const freq = self.operands[2]; const ylevel = self.operands[3]; var y = magnitude * math.sin(current_tick * freq + phase) + ylevel; if (y < 0) { y = 0; } self.soundnode.basefreq = y; self.soundnode.out10 = y; self.soundnode.out11 = y; } // Generates a linear ADSR envelope (range 0) to GAIN // Takes attack gain from OUT8 // Takes sustain gain from OUT9 // Tick count starts from 0, as if start_tick was 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.out8; const adsrsustain = self.soundnode.out9; 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; } self.soundnode.gain = gain; }