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}