vail

Internet morse code repeater
git clone https://git.woozle.org/neale/vail.git

vail / static / scripts
Neale Pickett  ·  2023-02-25

noise.mjs

  1import {AudioSource, AudioContextTime} from "./audio.mjs"
  2
  3/**
  4 * Create a white noise generator with a biquad filter
  5 * 
  6 * @param {AudioContext} context Audio context
  7 * @returns {BiquadFilterNode} Noise filter
  8 */
  9 function WhiteNoise(context) {
 10    let bufferSize = 17 * context.sampleRate
 11    let noiseBuffer = new AudioBuffer({
 12        sampleRate: context.sampleRate,
 13        length: bufferSize,
 14    })
 15    let output = noiseBuffer.getChannelData(0)
 16    for (let i = 0; i < bufferSize; i++) {
 17        output[i] = Math.random() * 2 - 1
 18    }
 19    
 20    let whiteNoise = context.createBufferSource()
 21    whiteNoise.buffer = noiseBuffer
 22    whiteNoise.loop = true
 23    whiteNoise.start(0)
 24
 25    let noiseFilter = new BiquadFilterNode(context, {type: "bandpass"})
 26    whiteNoise.connect(noiseFilter)
 27
 28    return noiseFilter
 29}
 30
 31class Noise extends AudioSource {
 32    /**
 33     * 
 34     * @param {AudioContext} context 
 35     */
 36    constructor(context, noises=2) {
 37        super(context)
 38
 39        this.whiteNoise = []
 40        
 41        for (let i = 0; i < noises; i++) {
 42            let wn = {
 43                modulator: new OscillatorNode(context),
 44                modulatorGain: new GainNode(context),
 45                filter: WhiteNoise(context),
 46                filterGain: new GainNode(context),
 47                filterGainModulator: new OscillatorNode(context),
 48                filterGainModulatorGain: new GainNode(context),
 49            }
 50
 51            wn.modulator.frequency.value = 0
 52            wn.modulatorGain.gain.value = 0
 53            wn.filter.frequency.value = 800
 54            wn.filterGain.gain.value = 0.8 / noises
 55            wn.filterGainModulator.frequency.value = 1
 56            wn.filterGainModulatorGain.gain.value = 1
 57    
 58            wn.modulator.connect(wn.modulatorGain)
 59            wn.modulatorGain.connect(wn.filter.frequency)
 60            wn.filter.connect(this.masterGain)
 61
 62            wn.modulator.start()
 63            this.whiteNoise.push(wn)
 64        }
 65
 66        this.SetNoiseParams(0, 0.07, 70, 400, 0.0)
 67        this.SetNoiseParams(1, 0.03, 200, 1600, 0.4)
 68        this.masterGain.gain.value = 0.5
 69    }
 70
 71    /**
 72     * Set modulator frequency
 73     * 
 74     * You probably want this to be under 1Hz, for a subtle sweeping effect
 75     * 
 76     * @param {Number} n Which noise generator
 77     * @param {Number} frequency Frequency (Hz)
 78     */
 79    SetNoiseModulator(n, frequency) {
 80        this.whiteNoise[n].modulator.frequency.value = frequency
 81    }
 82
 83    /**
 84     * Set modulator depth
 85     *
 86     * The output of the modulator [-1,1] is multiplied this and added to the
 87     * base frequency of the filter.
 88     *
 89     * @param {Number} n Which noise generator
 90     * @param {Number} depth Depth of modulation
 91     */
 92    SetNoiseDepth(n, depth) {
 93        this.whiteNoise[n].modulatorGain.gain.value = depth
 94    }
 95
 96    /**
 97     * Set noise filter base frequency
 98     * 
 99     * @param {Number} n Which noise generator
100     * @param {Number} frequency Frequency (Hz)
101     */
102    SetNoiseFrequency(n, frequency) {
103        this.whiteNoise[n].filter.frequency.value = frequency
104    }
105
106    /**
107     * Set gain of a noise generator
108     * 
109     * @param {Number} n Which noise generator
110     * @param {Number} gain Gain level (typically [0-1])
111     */
112    SetNoiseGain(n, gain) {
113        this.whiteNoise[n].filterGain.gain.value = gain
114    }
115
116    SetNoiseParams(n, modulatorFrequency, depth, baseFrequency, gain) {
117        this.SetNoiseModulator(n, modulatorFrequency)
118        this.SetNoiseDepth(n, depth)
119        this.SetNoiseFrequency(n, baseFrequency)
120        this.SetNoiseGain(n, gain)
121    }
122}
123
124export {
125    Noise,
126}