sonnum/zigsonnum/activities/basicsynths.zig

222 lines
No EOL
6.4 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 to r_amp pin
pub fn sine(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const maingain = self.soundnode.corrGain(self.operands[0]);
var final_amp: f64 = 0;
const max_freq_pin = 64 + self.soundnode.freq_q;
for (64..max_freq_pin) |freq_pin| {
const gain = self.soundnode.pins[freq_pin + 48];
const shift = self.soundnode.pins[freq_pin + 96];
const phase = self.soundnode.pins[freq_pin + 144];
const totalphase = self.soundnode.pins[33] + shift + phase;
const amp = math.sin(utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau);
final_amp += maingain * gain * amp;
}
self.soundnode.add_r_amp(final_amp);
}
// Produces a triangle wave to r_amp pin
pub fn triangle(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const maingain = self.soundnode.corrGain(self.operands[0]);
var final_amp: f64 = 0;
const max_freq_pin = 64 + self.soundnode.freq_q;
for (64..max_freq_pin) |freq_pin| {
const gain = self.soundnode.pins[freq_pin + 48];
const shift = self.soundnode.pins[freq_pin + 96];
const phase = self.soundnode.pins[freq_pin + 144];
const totalphase = self.soundnode.pins[33] + shift + phase;
const period = 44100 / self.soundnode.pins[freq_pin];
const tp = (current_tick - (period * totalphase)) / period;
const amp = @abs(2 * (2 * ( tp - @floor(tp + 0.5) ) )) - 1;
final_amp += maingain * gain * amp;
}
self.soundnode.add_r_amp(final_amp);
}
// Produces a square wave to r_amp pin
pub fn square(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const maingain = self.soundnode.corrGain(self.operands[0]);
var final_amp: f64 = 0;
const max_freq_pin = 64 + self.soundnode.freq_q;
for (64..max_freq_pin) |freq_pin| {
const gain = self.soundnode.pins[freq_pin + 48];
const shift = self.soundnode.pins[freq_pin + 96];
const phase = self.soundnode.pins[freq_pin + 144];
const totalphase = self.soundnode.pins[33] + shift + phase;
const sin = math.sin(utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau);
if (sin > 0) {
final_amp += maingain * gain;
} else {
final_amp += -(maingain * gain);
}
self.soundnode.add_r_amp(final_amp);
}
}
// Produces a sawtooth wave to r_amp pin
pub fn sawtooth(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const maingain = self.soundnode.corrGain(self.operands[0]);
var final_amp: f64 = 0;
const max_freq_pin = 64 + self.soundnode.freq_q;
for (64..max_freq_pin) |freq_pin| {
const gain = self.soundnode.pins[freq_pin + 48];
const shift = self.soundnode.pins[freq_pin + 96];
const phase = self.soundnode.pins[freq_pin + 144];
const totalphase = self.soundnode.pins[33] + shift + phase;
const period = 44100 / self.soundnode.pins[freq_pin];
const tp = (current_tick - (period * totalphase)) / period;
const amp = 2 * (tp - @floor(0.5+tp));
final_amp += maingain * gain * amp;
}
self.soundnode.add_r_amp(final_amp);
}
// Produces a skewed sine wave to R_AMP pin
// Operand 1 is pin number containing skewness factor
pub fn skewsine(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const skew = self.soundnode.pins[@intFromFloat(self.operands[0])];
const maingain = self.soundnode.corrGain(self.operands[1]);
var final_amp: f64 = 0;
const max_freq_pin = 64 + self.soundnode.freq_q;
for (64..max_freq_pin) |freq_pin| {
const gain = self.soundnode.pins[freq_pin + 48];
const shift = self.soundnode.pins[freq_pin + 96];
const phase = self.soundnode.pins[freq_pin + 144];
const totalphase = self.soundnode.pins[33] + shift + phase;
if (skew == 0) {
final_amp += maingain * gain * (math.sin(utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau));
} else if (skew > 0) {
const m = (utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau);
const sincos = skew * math.sin(m) / (1 - skew*math.cos(m));
final_amp += maingain * gain * (1/skew) * math.atan(sincos);
} else if (skew < 0) {
const m = (utility.corrected_tau * self.soundnode.pins[freq_pin] * current_tick - totalphase * utility.tau);
const sincos = skew * math.cos(m) / (1 + skew*math.sin(m));
final_amp += maingain * gain * (1/skew) * math.atan(sincos);
}
}
self.soundnode.add_r_amp(final_amp);
}
// Produces a pulse wave to r_amp pin
// Operand 1 is pin number containing pulse shift
pub fn pulse(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const pulse_shift = self.soundnode.pins[@intFromFloat(self.operands[0])];
const maingain = self.soundnode.corrGain(self.operands[1]);
var final_amp: f64 = 0;
const max_freq_pin = 64 + self.soundnode.freq_q;
for (64..max_freq_pin) |freq_pin| {
const gain = self.soundnode.pins[freq_pin + 48];
const shift = self.soundnode.pins[freq_pin + 96];
const phase = self.soundnode.pins[freq_pin + 114];
const totalphase = self.soundnode.pins[33] + shift + phase;
const period = 44100 / self.soundnode.pins[freq_pin];
const tp = (current_tick - (period * totalphase)) / period;
const tp_detract = (current_tick - (period * (pulse_shift + totalphase))) / period;
const amp = 2 * (tp - @floor(0.5 + tp));
const amp_detract = 2 * (tp_detract - @floor(0.5+tp_detract));
final_amp += maingain * gain * (amp - amp_detract);
}
self.soundnode.add_r_amp(final_amp);
}
// Whitenoise
// Seed is taken from OUT8
//
pub fn whitenoise(self: *Activity) void {
const current_tick: f64 = @floatFromInt(self.soundnode.fab.current_tick);
const seed = self.soundnode.pins[@intFromFloat(self.operands[0])];
const maingain = self.soundnode.corrGain(self.operands[1]);
const w = (seed*current_tick) / math.sin(current_tick);
const amp = (2 * (w - @floor(w))) - 1;
const final_amp = maingain * amp;
self.soundnode.fab.add_r_amp(final_amp);
}