74 lines
2.1 KiB
Zig
74 lines
2.1 KiB
Zig
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 pin 40
|
|
// Takes sustain gain from pin 41
|
|
// 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.pins[40];
|
|
var adsrsustain = self.soundnode.pins[41];
|
|
|
|
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;
|
|
adsrsustain *= 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.pins[32] = gain;
|
|
|
|
}
|