mirror of https://github.com/nealey/vail.git
Noise generator, for #54
This commit is contained in:
parent
72f2df5d6c
commit
1c8ab50f0a
|
@ -268,6 +268,29 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">
|
||||
<span data-i18n="label.gain">noise</span>:
|
||||
<output for="noiseGain"></output>%
|
||||
<i class="mdi mdi-volume-off muted"></i>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input
|
||||
id="noiseGain"
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value="0"
|
||||
step="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
|
|
|
@ -1,35 +1,123 @@
|
|||
import {AudioSource, AudioContextTime} from "./audio.mjs"
|
||||
|
||||
/**
|
||||
* Create a noise generator with a low pass filter
|
||||
* Create a white noise generator with a biquad filter
|
||||
*
|
||||
* @param {AudioContext} context Audio context
|
||||
* @param {Number} lowpassFreq Low-pass filter frequency (Hz)
|
||||
* @returns {GainNode} Gain object for noise
|
||||
* @returns {BiquadFilterNode} Noise filter
|
||||
*/
|
||||
function Noise(context, lowpassFreq = 100) {
|
||||
function WhiteNoise(context) {
|
||||
let bufferSize = 17 * context.sampleRate
|
||||
let noiseBuffer = context.createBuffer(1, bufferSize, 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;
|
||||
output[i] = Math.random() * 2 - 1
|
||||
}
|
||||
|
||||
let whiteNoise = context.createBufferSource();
|
||||
whiteNoise.buffer = noiseBuffer;
|
||||
whiteNoise.loop = true;
|
||||
whiteNoise.start(0);
|
||||
let whiteNoise = context.createBufferSource()
|
||||
whiteNoise.buffer = noiseBuffer
|
||||
whiteNoise.loop = true
|
||||
whiteNoise.start(0)
|
||||
|
||||
let filter = context.createBiquadFilter()
|
||||
filter.type = "lowpass"
|
||||
filter.frequency.value = lowpassFreq
|
||||
|
||||
let gain = context.createGain()
|
||||
gain.gain.value = 0.1
|
||||
|
||||
whiteNoise.connect(filter)
|
||||
filter.connect(gain)
|
||||
|
||||
return gain
|
||||
}
|
||||
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),
|
||||
}
|
||||
|
||||
wn.modulator.frequency.value = 0
|
||||
wn.modulatorGain.gain.value = 0
|
||||
wn.filter.frequency.value = 800
|
||||
wn.filterGain.gain.value = 0.8 / noises
|
||||
|
||||
wn.modulator.connect(wn.modulatorGain)
|
||||
wn.modulatorGain.connect(wn.filter.frequency)
|
||||
wn.filter.connect(wn.filterGain)
|
||||
wn.filterGain.connect(this.masterGain)
|
||||
|
||||
wn.modulator.start()
|
||||
this.whiteNoise.push(wn)
|
||||
}
|
||||
|
||||
this.SetNoiseParams(0, 0.07, 70, 400, 0.4)
|
||||
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,
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import * as I18n from "./i18n.mjs"
|
|||
import * as time from "./time.mjs"
|
||||
import * as Music from "./music.mjs"
|
||||
import * as Icon from "./icon.mjs"
|
||||
import * as Noise from "./noise.mjs"
|
||||
|
||||
const DefaultRepeater = "General"
|
||||
|
||||
|
@ -46,6 +47,12 @@ class VailClient {
|
|||
// Outputs
|
||||
this.outputs = new Outputs.Collection(globalAudioContext)
|
||||
this.outputs.connect(globalAudioContext.destination)
|
||||
|
||||
// Noise
|
||||
this.noise = new Noise.Noise(globalAudioContext)
|
||||
this.noise.connect(globalAudioContext.destination)
|
||||
|
||||
// App icon
|
||||
this.icon = new Icon.Icon()
|
||||
|
||||
// Keyers
|
||||
|
@ -90,6 +97,9 @@ class VailClient {
|
|||
this.inputInit("#masterGain", e => {
|
||||
this.outputs.SetGain(e.target.value / 100)
|
||||
})
|
||||
this.inputInit("#noiseGain", e => {
|
||||
this.noise.SetGain(e.target.value / 100)
|
||||
})
|
||||
let toneTransform = {
|
||||
note: Music.MIDINoteName,
|
||||
freq: Music.MIDINoteFrequency,
|
||||
|
|
Loading…
Reference in New Issue