Added examples, fixed samplerate issue on import, added to settings tab, fixed spread, added default wavetables, change default phaserand to 0

This commit is contained in:
Aria 2025-09-26 20:46:10 -07:00
parent 8b2c35b7a3
commit 97beaec25a
8 changed files with 311 additions and 38 deletions

View file

@ -988,7 +988,7 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
{ name: 'warpMode', defaultValue: 0 },
{ name: 'voices', defaultValue: 1, minValue: 1, maxValue: 32 },
{ name: 'spread', defaultValue: 0, minValue: 0, maxValue: 1 },
{ name: 'phaserand', defaultValue: 1, minValue: 0, maxValue: 1 },
{ name: 'phaserand', defaultValue: 0, minValue: 0, maxValue: 1 },
];
}
@ -1155,10 +1155,10 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
}
_sampleFrame(frame, phase) {
const pos = phase * (frame.length - 1);
const pos = phase * frame.length;
const i = pos | 0;
const frac = pos - i;
const a = frame[i];
const a = frame[i % frame.length];
const b = frame[(i + 1) % frame.length];
return a + (b - a) * frac;
}
@ -1181,7 +1181,6 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
for (let i = 0; i < outL.length; i++) {
const detune = pv(parameters.detune, i);
const spread = pv(parameters.spread, i) * 0.5 + 0.5;
const tablePos = pv(parameters.position, i);
const idx = tablePos * (this.numFrames - 1);
const fIdx = idx | 0;
@ -1189,11 +1188,13 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
const warpAmount = pv(parameters.warp, i);
const warpMode = pv(parameters.warpMode, i);
const voices = pv(parameters.voices, i);
const spread = voices > 1 ? pv(parameters.spread, i) : 0;
const phaseRand = pv(parameters.phaserand, i);
const gain1 = Math.sqrt(1 - spread);
const gain2 = Math.sqrt(spread);
const gain1 = Math.sqrt(0.5 - 0.5 * spread);
const gain2 = Math.sqrt(0.5 + 0.5 * spread);
let f = pv(parameters.frequency, i);
f = applySemitoneDetuneToFrequency(f, detune / 100); // overall detune
const normalizer = 0.3 / Math.sqrt(voices);
for (let n = 0; n < voices; n++) {
const isOdd = (n & 1) == 1;
let gainL = gain1;
@ -1206,19 +1207,19 @@ class WavetableOscillatorProcessor extends AudioWorkletProcessor {
const fVoice = applySemitoneDetuneToFrequency(f, getUnisonDetune(voices, detune, n)); // voice detune
const dPhase = fVoice / sampleRate;
const level = this._chooseMip(dPhase);
const bank = this.tables[level];
const table = this.tables[level];
// warp phase then sample
this.phase[n] = this.phase[n] ?? Math.random() * phaseRand;
const ph = this._warpPhase(this.phase[n], warpAmount, warpMode);
const s0 = this._sampleFrame(bank[fIdx], ph);
const s1 = this._sampleFrame(bank[Math.min(this.numFrames - 1, fIdx + 1)], ph);
const s0 = this._sampleFrame(table[fIdx], ph);
const s1 = this._sampleFrame(table[Math.min(this.numFrames - 1, fIdx + 1)], ph);
let s = s0 + (s1 - s0) * frac;
if (warpMode === WarpMode.FLIP && this.phase[n] < warpAmount) {
s = -s;
}
outL[i] += (s * gainL) / Math.sqrt(voices);
outR[i] += (s * gainR) / Math.sqrt(voices);
outL[i] += s * gainL * normalizer;
outR[i] += s * gainR * normalizer;
this.phase[n] = wrapPhase(this.phase[n] + dPhase);
}
}