Use the per-sample frequency and properly wrap polyBlep
This commit is contained in:
parent
2e8a8b50df
commit
218952b8b6
1 changed files with 9 additions and 9 deletions
|
|
@ -18,9 +18,10 @@ function wrapPhase(phase, maxPhase = 1) {
|
||||||
return phase;
|
return phase;
|
||||||
}
|
}
|
||||||
const blockSize = 128;
|
const blockSize = 128;
|
||||||
// Smooth waveshape near discontinuities to remove frequencies above nyquist and prevent aliasing
|
// Smooth waveshape near discontinuities to remove frequencies above Nyquist and prevent aliasing
|
||||||
// referenced from https://www.kvraudio.com/forum/viewtopic.php?t=375517
|
// referenced from https://www.kvraudio.com/forum/viewtopic.php?t=375517
|
||||||
function polyBlep(phase, dt) {
|
function polyBlep(phase, dt) {
|
||||||
|
dt = Math.min(dt, 1 - dt);
|
||||||
// Start of cycle
|
// Start of cycle
|
||||||
if (phase < dt) {
|
if (phase < dt) {
|
||||||
phase /= dt;
|
phase /= dt;
|
||||||
|
|
@ -451,7 +452,6 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
// this.port.postMessage({ type: 'onended' });
|
// this.port.postMessage({ type: 'onended' });
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const frequency = applySemitoneDetuneToFrequency(params.frequency[0], params.detune[0] / 100);
|
|
||||||
|
|
||||||
const output = outputs[0];
|
const output = outputs[0];
|
||||||
const voices = params.voices[0];
|
const voices = params.voices[0];
|
||||||
|
|
@ -462,9 +462,6 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
|
|
||||||
for (let n = 0; n < voices; n++) {
|
for (let n = 0; n < voices; n++) {
|
||||||
const isOdd = (n & 1) == 1;
|
const isOdd = (n & 1) == 1;
|
||||||
|
|
||||||
//applies unison "spread" detune in semitones
|
|
||||||
const freq = applySemitoneDetuneToFrequency(frequency, getUnisonDetune(voices, freqspread, n));
|
|
||||||
let gainL = gain1;
|
let gainL = gain1;
|
||||||
let gainR = gain2;
|
let gainR = gain2;
|
||||||
// invert right and left gain
|
// invert right and left gain
|
||||||
|
|
@ -472,11 +469,14 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
|
||||||
gainL = gain2;
|
gainL = gain2;
|
||||||
gainR = gain1;
|
gainR = gain1;
|
||||||
}
|
}
|
||||||
// We must wrap this here because it is passed into sawblep below which
|
|
||||||
// has domain [0, 1]
|
|
||||||
const dt = wrapPhase(freq / sampleRate);
|
|
||||||
|
|
||||||
for (let i = 0; i < output[0].length; i++) {
|
for (let i = 0; i < output[0].length; i++) {
|
||||||
|
// Main detuning
|
||||||
|
let freq = applySemitoneDetuneToFrequency(params.frequency[i] ?? params.frequency[0], params.detune[0] / 100);
|
||||||
|
// Individual voice detuning
|
||||||
|
freq = applySemitoneDetuneToFrequency(freq, getUnisonDetune(voices, freqspread, n));
|
||||||
|
// We must wrap this here because it is passed into sawblep below which
|
||||||
|
// has domain [0, 1]
|
||||||
|
const dt = _mod(freq / sampleRate, 1);
|
||||||
this.phase[n] = this.phase[n] ?? Math.random();
|
this.phase[n] = this.phase[n] ?? Math.random();
|
||||||
const v = waveshapes.sawblep(this.phase[n], dt);
|
const v = waveshapes.sawblep(this.phase[n], dt);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue