[Web Audio API #12] 오디오 필터 사용하기
웹 오디오 필터를 만들고 사용하는 것은 어렵지 않다. 2011년 이후로 W3C(World Wide Web Consortium)에서 계속해서 보완하고 발전시켜온 덕택이다.
오디오 필터는 Biquad 필터(전달함수의 분자 분모가 각각 2차 함수(quadratic)인 필터)를 기반으로 하고 있으며 변수들을 설정해 저역통과필터(Low Pass Filter), 고역통과필터(Hig Pass Filter), 그리고 대역통과필터(Band Pass Filter)를 만들 수 있다. 아래는 값 설정이 가능한 저역통과 필터의 예이다(예에서 Q값은 1dB로 설정하였다).
<html>
<div id="filter_control_div">
<div id="lpf_contol_div">
<label for="lpf_freq_control">LPF cutoff frequency control</label>
<input type="range" min="0" max="20000" value="15000" step="500" id="lpf_freq_control">
</div>
</div>
<html>
<script>
const LPF = audioContext.createBiquadFilter();
// 초기값 설정
LPF.type = 'lowpass';
LPF.frequency.setValueAtTime(24000, audioContext.currentTime);
LPF.gain.setValueAtTime(1, audioContext.currentTime);
LPF.Q.setValueAtTime(1, audioContext.currentTime);
// 차단 주파수 변경
const lpfFreqControl = document.querySelector('#lpf_freq_control');
lpfFreqControl.addEventListener('input', (event) => {
var targetValue = event.target.value;
LPF.frequency.setValueAtTime(parseFloat(targetValue), audioContext.currentTime);
lpfFreqValue.innerHTML = targetValue + 'Hz';
});
</script>
필터를 설정하는 변수들인 cutoff frequency, Q 값의 의미는 이전 포스팅 '오디오 필터 - filters'를 참조하기 바란다.
2021.07.28 - [웹 오디오 프로그래밍] - [Web Audio API] 오디오 필터 - filters
필터의 타입을 BiquadFilterNode 객체의 type 속성에 지정해 줄 수 있다. 총 8가지 타입이 있으며 이 중 'lowpass', 'highpass', 그리고 'bandpass' 속성들을 가장 많이 사용한다. 필터가 지원하는 형식을 아래 웹 페이지에서 볼 수 있다.
https://developer.mozilla.org/ko/docs/Web/API/BiquadFilterNode
BiquadFilterNode - Web API | MDN
The BiquadFilterNode interface represents a simple low-order filter, and is created using the AudioContext.createBiquadFilter() (en-US) method. It is an AudioNode that can represent different kinds of filters, tone control devices, and graphic equalizers.
developer.mozilla.org
일정 대역의 주파수 성분만 통과시키는 band pass filter(BPF)를 LPF와 HPF의 조합으로 구성할 수 있다. 현실적으로 이렇게 구현하는 것이 band pass filter 하나만 가지는 것 보다 주파수 특성이 좋다. 왜냐하면 복잡한 속성들을 필터 하나의 한정된 전달함수 변수들만 가지고 만족스럽게 표현하기 쉽지 않기 때문이다.
const LPF = audioContext.createBiquadFilter();
const HPF = audioContext.createBiquadFilter();
// 초기값 설정
LPF.type = 'lowpass';
LPF.frequency.setValueAtTime(20000, audioContext.currentTime);
LPF.gain.setValueAtTime(1, audioContext.currentTime);
LPF.Q.setValueAtTime(1, audioContext.currentTime);
HPF.type = 'lowpass';
HPF.frequency.setValueAtTime(5000, audioContext.currentTime);
HPF.gain.setValueAtTime(1, audioContext.currentTime);
HPF.Q.setValueAtTime(1, audioContext.currentTime);
LPF.connect(HPF);
음원(Oscillator), 필터들, 그리고 차단 주파수 조절 인터페이스를 포함하는 코드의 예는 아래와 같다.
<!DOCTYPE html>
<html>
<body>
<div id="filter_control_div">
<div id="lpf_contol_div">
<label for="lpf_freq_control">LPF cutoff frequency control</label>
<input type="range" min="0" max="20000" value="15000" step="500" id="lpf_freq_control">
<span id="lpf_freq_value">15000Hz</span>
</div>
<div id="hpf_contol_div">
<label for="hpf_freq_control">HPF cutoff frequency control</label>
<input type="range" min="0" max="20000" value="1000" step="500" id="hpf_freq_control">
<span id="hpf_freq_value">1000Hz</span>
</div>
</div>
</body>
<script>
const audioContext = new(window.AudioContext || window.webkitAudioContext)();
const osc = audioContext.createOscillator();
const LPF = audioContext.createBiquadFilter();
const HPF = audioContext.createBiquadFilter();
osc.frequency.setValueAtTime(5000, audioContext.currentTime);
LPF.type = 'lowpass';
LPF.frequency.setValueAtTime(24000, audioContext.currentTime);
LPF.gain.setValueAtTime(1, audioContext.currentTime);
LPF.Q.setValueAtTime(1, audioContext.currentTime);
HPF.type = 'highpass';
HPF.frequency.setValueAtTime(1000, audioContext.currentTime);
HPF.gain.setValueAtTime(1, audioContext.currentTime);
HPF.Q.setValueAtTime(1, audioContext.currentTime);
osc.connect(LPF);
LPF.connect(HPF);
HPF.connect(audioContext.destination);
const lpfFreqControl = document.querySelector('#lpf_freq_control');
const lpfFreqValue = document.querySelector('#lpf_freq_value');
lpfFreqControl.addEventListener('input', (event) => {
var targetValue = event.target.value;
LPF.frequency.setValueAtTime(parseFloat(targetValue), audioContext.currentTime);
lpfFreqValue.innerHTML = targetValue + 'Hz';
});
const hpfFreqControl = document.querySelector('#hpf_freq_control');
const hpfFreqValue = document.querySelector('#hpf_freq_value');
hpfFreqControl.addEventListener('input', (event) => {
var targetValue = event.target.value;
HPF.frequency.setValueAtTime(parseFloat(targetValue), audioContext.currentTime);
hpfFreqValue.innerHTML = targetValue + 'Hz';
});
osc.start(0);
</script>
</html>
■