proper dry wet + pull out noise to extra file

This commit is contained in:
Felix Roos 2023-10-03 12:19:30 +02:00
parent 484bb6b11f
commit 2bc6d08410
3 changed files with 80 additions and 63 deletions

View File

@ -112,3 +112,25 @@ export function createFilter(
return filter;
}
// stays 1 until .5, then fades out
let wetfade = (d) => (d < 0.5 ? 1 : 1 - (d - 0.5) / 0.5);
// mix together dry and wet nodes. 0 = only dry 1 = only wet
// still not too sure about how this could be used more generally...
export function drywet(dry, wet, wetAmount = 0) {
const ac = getAudioContext();
if (!wetAmount) {
return dry;
}
let dry_gain = ac.createGain();
let wet_gain = ac.createGain();
dry.connect(dry_gain);
wet.connect(wet_gain);
dry_gain.gain.value = wetfade(wetAmount);
wet_gain.gain.value = wetfade(1 - wetAmount);
let mix = ac.createGain();
dry_gain.connect(mix);
wet_gain.connect(mix);
return mix;
}

View File

@ -0,0 +1,51 @@
import { drywet } from './helpers.mjs';
// expects one of noises as type
export function getNoiseOscillator(type = 'white', t) {
const ac = getAudioContext();
const bufferSize = 2 * ac.sampleRate;
const noiseBuffer = ac.createBuffer(1, bufferSize, ac.sampleRate);
const output = noiseBuffer.getChannelData(0);
let lastOut = 0;
let b0, b1, b2, b3, b4, b5, b6;
b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;
for (let i = 0; i < bufferSize; i++) {
if (type === 'white') {
output[i] = Math.random() * 2 - 1;
} else if (type === 'brown') {
let white = Math.random() * 2 - 1;
output[i] = (lastOut + 0.02 * white) / 1.02;
lastOut = output[i];
} else if (type === 'pink') {
let white = Math.random() * 2 - 1;
b0 = 0.99886 * b0 + white * 0.0555179;
b1 = 0.99332 * b1 + white * 0.0750759;
b2 = 0.969 * b2 + white * 0.153852;
b3 = 0.8665 * b3 + white * 0.3104856;
b4 = 0.55 * b4 + white * 0.5329522;
b5 = -0.7616 * b5 - white * 0.016898;
output[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;
output[i] *= 0.11;
b6 = white * 0.115926;
}
}
const o = ac.createBufferSource();
o.buffer = noiseBuffer;
o.loop = true;
o.start(t);
return {
node: o,
stop: (time) => o.stop(time),
};
}
export function getNoiseMix(inputNode, wet, t) {
const noiseOscillator = getNoiseOscillator('pink', t);
const noiseMix = drywet(inputNode, noiseOscillator.node, wet);
return {
node: noiseMix,
stop: (time) => noiseOscillator?.stop(time),
};
}

View File

@ -1,6 +1,7 @@
import { midiToFreq, noteToMidi } from './util.mjs';
import { registerSound, getAudioContext } from './superdough.mjs';
import { gainNode, getEnvelope, getExpEnvelope } from './helpers.mjs';
import { getNoiseMix } from './noise.mjs';
const mod = (freq, range = 1, type = 'sine') => {
const ctx = getAudioContext();
@ -35,7 +36,7 @@ export function registerSynthSounds() {
if (waveforms.includes(s)) {
sound = getOscillator(s, t, value);
} else {
sound = getNoiseOscillator(t, s);
sound = getNoiseOscillator(s, t);
}
let { node: o, stop, triggerRelease } = sound;
@ -96,47 +97,6 @@ export function waveformN(partials, type) {
return osc;
}
// expects one of noises as type
export function getNoiseOscillator(t, type = 'white') {
const ac = getAudioContext();
const bufferSize = 2 * ac.sampleRate;
const noiseBuffer = ac.createBuffer(1, bufferSize, ac.sampleRate);
const output = noiseBuffer.getChannelData(0);
let lastOut = 0;
let b0, b1, b2, b3, b4, b5, b6;
b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;
for (let i = 0; i < bufferSize; i++) {
if (type === 'white') {
output[i] = Math.random() * 2 - 1;
} else if (type === 'brown') {
let white = Math.random() * 2 - 1;
output[i] = (lastOut + 0.02 * white) / 1.02;
lastOut = output[i];
} else if (type === 'pink') {
let white = Math.random() * 2 - 1;
b0 = 0.99886 * b0 + white * 0.0555179;
b1 = 0.99332 * b1 + white * 0.0750759;
b2 = 0.969 * b2 + white * 0.153852;
b3 = 0.8665 * b3 + white * 0.3104856;
b4 = 0.55 * b4 + white * 0.5329522;
b5 = -0.7616 * b5 - white * 0.016898;
output[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;
output[i] *= 0.11;
b6 = white * 0.115926;
}
}
const o = ac.createBufferSource();
o.buffer = noiseBuffer;
o.loop = true;
o.start(t);
return {
node: o,
stop: (time) => o.stop(time),
};
}
// expects one of waveforms as s
export function getOscillator(
s,
@ -224,32 +184,16 @@ export function getOscillator(
vibratoOscillator.start(t);
}
let noiseOscillator, noiseMix;
// noise mix
if (noise > 0) {
// Two gain nodes to set the oscillators to their respective levels
noise = noise > 1 ? 1 : noise;
let o_gain = ac.createGain();
let n_gain = ac.createGain();
o_gain.gain.setValueAtTime(1 - noise, ac.currentTime);
n_gain.gain.setValueAtTime(noise, ac.currentTime);
// Instanciating a mixer to blend sources together
noiseMix = ac.createGain();
// Connecting the main oscillator to the gain node
o.connect(o_gain).connect(noiseMix);
// Instanciating a noise oscillator and connecting
noiseOscillator = getNoiseOscillator(t, 'pink');
noiseOscillator.node.connect(n_gain).connect(noiseMix);
let noiseMix;
if (noise) {
noiseMix = getNoiseMix(o, noise, t);
}
return {
node: noiseMix || o,
node: noiseMix?.node || o,
stop: (time) => {
vibratoOscillator?.stop(time);
noiseOscillator?.stop(time);
noiseMix?.stop(time);
stopFm?.(time);
o.stop(time);
},