Intro
This time, I try "BiquadFilterNode" to control tone.
Sample code
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>xlsx sample</title>
<meta charset="utf-8">
</head>
<body>
<div>
<div>EQ</div>
<select id="eq_input">
<option>allpass</option>
<option>bandpass</option>
<option>highpass</option>
<option>highshelf</option>
<option>lowpass</option>
<option>lowshelf</option>
<option>notch</option>
<option>peaking</option>
</select>
<div>Frequency</div>
<select id="eq_frequency">
<option>10</option>
<option>100</option>
<option>350</option>
<option>1000</option>
<option>5000</option>
<option>10000</option>
<option>22050</option>
</select>
<div>Gain</div>
<select id="eq_gain">
<option>-40</option>
<option>-20</option>
<option>-10</option>
<option>0</option>
<option>10</option>
<option>20</option>
<option>40</option>
</select>
<div>Detune</div>
<select id="eq_detune">
<option>0</option>
<option>10</option>
<option>100</option>
<option>350</option>
<option>1000</option>
<option>5000</option>
<option>10000</option>
<option>22050</option>
</select>
<div>Q</div>
<select id="eq_q">
<option>0</option>
<option>0.0001</option>
<option>0.001</option>
<option>0.01</option>
<option>0.1</option>
<option>1</option>
<option>10</option>
<option>100</option>
<option>1000</option>
</select>
</div>
<script src="./js/main.page.js"></script>
<script>Page.init();</script>
</body>
</html>
main.page.ts
let audioContext: AudioContext;
export async function init(): Promise<void> {
const medias = await navigator.mediaDevices.getUserMedia({
video: false,
audio: true,
});
audioContext = new AudioContext();
const audioSourceNode = audioContext.createMediaStreamSource(medias);
const biquadFilter = audioContext.createBiquadFilter();
audioSourceNode
.connect(biquadFilter)
.connect(audioContext.destination);
const eqSelect = document.getElementById('eq_input') as HTMLSelectElement;
eqSelect.onchange = () => {
const eqValue = eqSelect.options[eqSelect.selectedIndex]?.text;
if(eqValue == null) {
return;
}
switch(eqValue) {
case 'allpass':
biquadFilter.type = 'allpass';
break;
case 'bandpass':
biquadFilter.type = 'bandpass';
break;
case 'highpass':
biquadFilter.type = 'highpass';
break;
case 'highshelf':
biquadFilter.type = 'highshelf';
break;
case 'lowpass':
biquadFilter.type = 'lowpass';
break;
case 'lowshelf':
biquadFilter.type = 'lowshelf';
break;
case 'notch':
biquadFilter.type = 'notch';
break;
case 'peaking':
biquadFilter.type = 'peaking';
break;
}
};
const eqFrequencySelect = document.getElementById('eq_frequency') as HTMLSelectElement;
eqFrequencySelect.onchange = () => {
const eqFrequencyText = eqFrequencySelect.options[eqFrequencySelect.selectedIndex]?.text;
if(eqFrequencyText == null) {
return;
}
const eqFrequency = parseInt(eqFrequencyText);
if(isNaN(eqFrequency)) {
return;
}
biquadFilter.frequency.setValueAtTime(eqFrequency, audioContext.currentTime);
};
const eqGainSelect = document.getElementById('eq_gain') as HTMLSelectElement;
eqGainSelect.onchange = () => {
const eqGainText = eqGainSelect.options[eqGainSelect.selectedIndex]?.text;
if(eqGainText == null) {
return;
}
const eqGain = parseInt(eqGainText);
if(isNaN(eqGain)) {
return;
}
biquadFilter.gain.setValueAtTime(eqGain, audioContext.currentTime);
};
const eqDetuneSelect = document.getElementById('eq_detune') as HTMLSelectElement;
eqDetuneSelect.onchange = () => {
const eqDetuneText = eqDetuneSelect.options[eqDetuneSelect.selectedIndex]?.text;
if(eqDetuneText == null) {
return;
}
const eqDetune = parseInt(eqDetuneText);
if(isNaN(eqDetune)) {
return;
}
biquadFilter.detune.setValueAtTime(eqDetune, audioContext.currentTime);
};
const eqQSelect = document.getElementById('eq_q') as HTMLSelectElement;
eqQSelect.onchange = () => {
const eqQText = eqQSelect.options[eqQSelect.selectedIndex]?.text;
if(eqQText == null) {
return;
}
const eqQ = parseInt(eqQText);
if(isNaN(eqQ)) {
return;
}
biquadFilter.Q.setValueAtTime(eqQ, audioContext.currentTime);
};
}
type
"BiquadFilterNode" has preset filters. I can use them by "BiquadFilterNode.type".
- allpass
- bandpass
- highpass
- highshelf
- lowpass
- lowshelf
- notch
peaking
Modify filters
I can modify the selected filter by "gain", "frequency", "detune", "Q".
gain
I can control gain of filter by "BiquadFilterNode.gain".
Only "highshelf", "lowshelf", "peaking" of "BiquadFilterNode.type" can use.
The lowest value is -40(dB) and the highest one is 40(dB).
frequency, detune
"frequency", "detune" are used to compute frequency of the filter.
computedFrequency(t) = frequency(t) * pow(2, detune(t) / 1200)
- Web Audio API #BiquadFilterNode
- BiquadFilterNode.frequency - Web APIs | MDN
- BiquadFilterNode.detune - Web APIs | MDN
Because some types emphasize specific frequency by default, I can't hear the sound when I set specific values into them.
type | the value what I can't hear the sound |
---|---|
bandpass | 10 |
highpass | 22050 |
lowpass | 10 |
I can't feel the differences when I change the values with "highshelf", "lowshelf", "peaking".
Q
This express Quality factor.
I haven't understood what is Quality factor.
So maybe I will wrtite more about it later.
The max value and min value are different per types.
For example, when I use "bandpass" and set Q value as 100, I can't hear the sound.
When I use "highpass" and set Q value as 100, I hear some noize like howling.
Top comments (0)