Nowoczesny sposób
Web Audio API używa interfejsu AudioContext() do zarządzania źródłami, filtrami i miejscami docelowymi. Po utworzeniu nowego interfejsu AudioContext() utwórz węzeł źródła dźwięku, np. AudioBufferSourceNode lub OscillatorNode. Jako przykład weźmy podstawowy oscylator z zastosowanym filtrem dolnoprzepustowym.
Używanie metody createBiquadFilter()
Najpierw utwórz nowy interfejs AudioContext(). Następnie utwórz węzeł źródła dźwięku, np. AudioBufferSourceNode lub OscillatorNode. W tym przykładzie utworzysz węzeł oscylatora sine, który od momentu rozpoczęcia odtwarzania ma częstotliwość 420 Hz.
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator()
oscillator.type = 'sine';
// Value is in hertz.
oscillator.frequency.setValueAtTime(420, audioCtx.currentTime);
Następnie utwórz węzeł efektu za pomocą createBiquadFilter(). Ustaw typ na lowpass i częstotliwość tak, aby zaczynała się sekundę po rozpoczęciu odtwarzania. Następnie połącz biquadFilter z oscillator.
const biquadFilter = audioCtx.createBiquadFilter();
biquadFilter.type = 'lowpass';
biquadFilter.frequency.setValueAtTime(200, audioCtx.currentTime + 1);
oscillator.connect(biquadFilter);
Na koniec połącz biquadFilter z miejscem docelowym audioCtx, zanim uruchomisz oscillator i zatrzymasz go po 2 sekundach odtwarzania.
biquadFilter.connect(audioCtx.destination);
oscillator.start();
oscillator.stop(2);
Dźwięk z oscylatora jest przekazywany przez filtr bez efektów do miejsca docelowego, czyli głośników komputera. Po sekundzie odtwarzania zaczyna działać filtr lowpass. Po 2 sekundach oscylator zostaje zatrzymany.
Inne dostępne filtry i efekty
Do interfejsu AudioContext można dodać inne węzły filtrów, aby tworzyć różne efekty:
createWaveShaper()służy do dodawania zniekształceń do źródła.createGain()służy do wzmacniania ogólnego sygnału źródła, do którego jest stosowany.createConvolver()jest najczęściej używany do dodawania pogłosu do źródła.createDelay()służy do dodawania opóźnienia do początku źródła.createDynamicsCompressor()służy do zwiększania głośności najcichszej części źródła i zmniejszania głośności najgłośniejszych części.createPanner()icreateStereoPanner()służą do zmiany położenia przestrzennego wyjścia dźwięku.
Klasyczny sposób
Zanim pojawił się Web Audio API, nie było możliwości dodawania efektów do dźwięku w przeglądarce. Możliwe są obejścia polegające na renderowaniu po stronie serwera i przełączaniu się między strumieniami, ale może to powodować duże obciążenie sieci.
Używanie elementu audio
Jedynymi efektami dźwiękowymi, którymi można bezpośrednio sterować, są odtwarzanie i głośność.
const audio = document.querySelector('audio');
// Sets audio volume to 50%
audio.volume = 0.5;
// Doubles the playback rate.
audio.playbackRate = 2;
Więcej informacji
Prezentacja
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🔉</text></svg>"
/>
<title>How to add effects to audio</title>
</head>
<body>
<h1>How to add effects to audio</h1>
<button type="button">Press to hear audio effect</button>
</body>
</html>CSS
:root {
color-scheme: dark light;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 1rem;
font-family: system-ui, sans-serif;
}
JS
const button = document.querySelector('button');
button.addEventListener('click', () => {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator();
oscillator.type = 'sine';
// Value is in hertz.
oscillator.frequency.setValueAtTime(420, audioCtx.currentTime);
const biquadFilter = audioCtx.createBiquadFilter();
biquadFilter.type = 'lowpass';
biquadFilter.frequency.setValueAtTime(200, audioCtx.currentTime + 1);
oscillator.connect(biquadFilter);
biquadFilter.connect(audioCtx.destination);
oscillator.start();
oscillator.stop(2);
});