mirror of https://github.com/nealey/vail.git
127 lines
3.5 KiB
JavaScript
127 lines
3.5 KiB
JavaScript
import {AudioSource, AudioContextTime} from "./audio.mjs"
|
|
|
|
/**
|
|
* Create a white noise generator with a biquad filter
|
|
*
|
|
* @param {AudioContext} context Audio context
|
|
* @returns {BiquadFilterNode} Noise filter
|
|
*/
|
|
function WhiteNoise(context) {
|
|
let bufferSize = 17 * context.sampleRate
|
|
let noiseBuffer = new AudioBuffer({
|
|
sampleRate: context.sampleRate,
|
|
length: bufferSize,
|
|
})
|
|
let output = noiseBuffer.getChannelData(0)
|
|
for (let i = 0; i < bufferSize; i++) {
|
|
output[i] = Math.random() * 2 - 1
|
|
}
|
|
|
|
let whiteNoise = context.createBufferSource()
|
|
whiteNoise.buffer = noiseBuffer
|
|
whiteNoise.loop = true
|
|
whiteNoise.start(0)
|
|
|
|
let noiseFilter = new BiquadFilterNode(context, {type: "bandpass"})
|
|
whiteNoise.connect(noiseFilter)
|
|
|
|
return noiseFilter
|
|
}
|
|
|
|
class Noise extends AudioSource {
|
|
/**
|
|
*
|
|
* @param {AudioContext} context
|
|
*/
|
|
constructor(context, noises=2) {
|
|
super(context)
|
|
|
|
this.whiteNoise = []
|
|
|
|
for (let i = 0; i < noises; i++) {
|
|
let wn = {
|
|
modulator: new OscillatorNode(context),
|
|
modulatorGain: new GainNode(context),
|
|
filter: WhiteNoise(context),
|
|
filterGain: new GainNode(context),
|
|
filterGainModulator: new OscillatorNode(context),
|
|
filterGainModulatorGain: new GainNode(context),
|
|
}
|
|
|
|
wn.modulator.frequency.value = 0
|
|
wn.modulatorGain.gain.value = 0
|
|
wn.filter.frequency.value = 800
|
|
wn.filterGain.gain.value = 0.8 / noises
|
|
wn.filterGainModulator.frequency.value = 1
|
|
wn.filterGainModulatorGain.gain.value = 1
|
|
|
|
wn.modulator.connect(wn.modulatorGain)
|
|
wn.modulatorGain.connect(wn.filter.frequency)
|
|
wn.filter.connect(this.masterGain)
|
|
|
|
wn.modulator.start()
|
|
this.whiteNoise.push(wn)
|
|
}
|
|
|
|
this.SetNoiseParams(0, 0.07, 70, 400, 0.0)
|
|
this.SetNoiseParams(1, 0.03, 200, 1600, 0.4)
|
|
this.masterGain.gain.value = 0.5
|
|
}
|
|
|
|
/**
|
|
* Set modulator frequency
|
|
*
|
|
* You probably want this to be under 1Hz, for a subtle sweeping effect
|
|
*
|
|
* @param {Number} n Which noise generator
|
|
* @param {Number} frequency Frequency (Hz)
|
|
*/
|
|
SetNoiseModulator(n, frequency) {
|
|
this.whiteNoise[n].modulator.frequency.value = frequency
|
|
}
|
|
|
|
/**
|
|
* Set modulator depth
|
|
*
|
|
* The output of the modulator [-1,1] is multiplied this and added to the
|
|
* base frequency of the filter.
|
|
*
|
|
* @param {Number} n Which noise generator
|
|
* @param {Number} depth Depth of modulation
|
|
*/
|
|
SetNoiseDepth(n, depth) {
|
|
this.whiteNoise[n].modulatorGain.gain.value = depth
|
|
}
|
|
|
|
/**
|
|
* Set noise filter base frequency
|
|
*
|
|
* @param {Number} n Which noise generator
|
|
* @param {Number} frequency Frequency (Hz)
|
|
*/
|
|
SetNoiseFrequency(n, frequency) {
|
|
this.whiteNoise[n].filter.frequency.value = frequency
|
|
}
|
|
|
|
/**
|
|
* Set gain of a noise generator
|
|
*
|
|
* @param {Number} n Which noise generator
|
|
* @param {Number} gain Gain level (typically [0-1])
|
|
*/
|
|
SetNoiseGain(n, gain) {
|
|
this.whiteNoise[n].filterGain.gain.value = gain
|
|
}
|
|
|
|
SetNoiseParams(n, modulatorFrequency, depth, baseFrequency, gain) {
|
|
this.SetNoiseModulator(n, modulatorFrequency)
|
|
this.SetNoiseDepth(n, depth)
|
|
this.SetNoiseFrequency(n, baseFrequency)
|
|
this.SetNoiseGain(n, gain)
|
|
}
|
|
}
|
|
|
|
export {
|
|
Noise,
|
|
}
|