This commit is contained in:
Jade (Rose) Rowland 2024-03-14 20:35:56 -04:00
parent 83145784d7
commit fd946107df
3 changed files with 20 additions and 9 deletions

View File

@ -890,7 +890,7 @@ export const { lock } = registerControl('lock');
* @param {number | Pattern} amount * @param {number | Pattern} amount
* @synonyms det * @synonyms det
* @example * @example
* note("d f a a# a d3").fast(2).s("supersaw").detune("<.4 1 3 200>") * note("d f a a# a d3").fast(2).s("supersaw").detune("<.1 .2 .5 24.1>")
* *
*/ */
export const { detune, det } = registerControl('detune', 'det'); export const { detune, det } = registerControl('detune', 'det');

View File

@ -64,8 +64,8 @@ export function registerSynthSounds() {
'supersaw', 'supersaw',
(begin, value, onended) => { (begin, value, onended) => {
const ac = getAudioContext(); const ac = getAudioContext();
let { duration, n, unison = 6, spread = 0.3, detune } = value; let { duration, n, unison = 5, spread = 0.6, detune } = value;
detune = detune ?? n ?? 2; detune = detune ?? n ?? 0.18;
const frequency = getFrequencyFromValue(value); const frequency = getFrequencyFromValue(value);
const [attack, decay, sustain, release] = getADSRValues( const [attack, decay, sustain, release] = getADSRValues(

View File

@ -161,10 +161,21 @@ const saw = (phase, dt) => {
return v - polyBlep(phase, dt); return v - polyBlep(phase, dt);
}; };
function lerp(a, b, n) {
return n * (b - a) + a;
}
function getUnisonDetune(unison, detune, voiceIndex) {
if (unison < 2) {
return 0;
}
return lerp(-detune, detune, voiceIndex / (unison - 1));
}
class SuperSawOscillatorProcessor extends AudioWorkletProcessor { class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
constructor() { constructor() {
super(); super();
this.phase = []; this.phase = [];
this.logged = 0;
} }
static get parameterDescriptors() { static get parameterDescriptors() {
return [ return [
@ -207,7 +218,7 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
{ {
name: 'voices', name: 'voices',
defaultValue: 6, defaultValue: 5,
min: 1, min: 1,
}, },
]; ];
@ -233,13 +244,13 @@ class SuperSawOscillatorProcessor extends AudioWorkletProcessor {
const gain2 = Math.sqrt(panspread); const gain2 = Math.sqrt(panspread);
for (let n = 0; n < voices; n++) { for (let n = 0; n < voices; n++) {
let adj = 0;
const isOdd = (n & 1) == 1; const isOdd = (n & 1) == 1;
//adjust the detune amount for each voice
if (n > 0) { if (this.logged < 10) {
adj = isOdd ? n * freqspread : -((n - 1) * freqspread); this.logged += 1;
} }
const freq = Math.min(16744, Math.max(1, frequency + adj * 0.01 * frequency)); //applies unison "spread" detune in semitones
const freq = frequency * Math.pow(2, getUnisonDetune(voices, freqspread, n) / 1.2);
let gainL = gain1; let gainL = gain1;
let gainR = gain2; let gainR = gain2;
// invert right and left gain // invert right and left gain