使用 Web Audio API 隔离音频上下文的频率 [英] Isolate frequencies of audio context using the Web Audio API
问题描述
我正在试验 WebAudio API 并尝试构建一个分析器,用户可以与之交互并最终打开和关闭音乐中的不同频率以隔离音轨中的不同节拍,即低音、底鼓等.
我正在使用 Canvas 将频率数据可视化,并希望用户能够突出显示可视化的部分,并依次静音频率.
默认情况下,可视化效果如下所示,用户会听到所有频率.
但是当用户选择多个条形时,灰色的条形会将相关频率静音:
我的想法是我可以对 frequencyData 数组进行逆向工程并基本上使相关频率静音吗?
** 更新 **
所以我一直在尝试通过添加几个 biquadFilter
和一种 notch
串联,然后调整它们的频率和 Q 值.这确实有助于隔离音乐的轻拍,但不完全是我想要的.这是我目前使用的代码...
const audioContext = new window.AudioContext();const source = audioContext.createMediaElementSource(element);const biquadFilter1 = audioContext.createBiquadFilter();const biquadFilter2 = audioContext.createBiquadFilter();const biquadFilter3 = audioContext.createBiquadFilter();const 分析器 = audioContext.createAnalyser();biquadFilter1.connect(分析仪);biquadFilter2.connect(分析仪);biquadFilter3.connect(分析仪);来源.connect(biquadFilter1).connect(biquadFilter2).connect(biquadFilter3);analyzer.connect(audioContext.destination);
我不确定我的设置是否正确,但它确实允许我非常粗略地操纵频率,但感觉这样做没有准确的科学.
我正在尝试的可能吗,如果是的话,任何建议都非常感谢:)
您正在寻找的是带通滤波器.
<块引用>带通滤波器(也称为带通滤波器,BPF)是一种通过一定范围内的频率并拒绝(衰减)超出该范围的频率.https://en.wikipedia.org/wiki/Band-pass_filter
我们很幸运,网络音频 API 通过 BiquadFilterNode 提供它.
https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode
因此,根据提供的演示代码,将 400Hz 频率范围内的带通滤波器应用于 html 音频播放器.
html 音频元素必须由 js 创建然后插入到 DOM 中,否则它将无法与 web 音频 api 一起使用.
<div id="hello"></div><脚本>var audioCtx = new (window.AudioContext || window.webkitAudioContext)();//创建新玩家var a = document.createElement("audio");//给出源歌曲a.src = "vorbis.ogg";//显示控件a.setAttribute("控件", "");//附加到 DOMhello.appendChild(a);//播放器现在准备好使用网络音频 apivar mediaElement = a;//设置我们将用于应用程序的不同音频节点var gainNode = audioCtx.createGain();var biquadFilter = audioCtx.createBiquadFilter();//将节点连接在一起source = audioCtx.createMediaElementSource(mediaElement);source.connect(biquadFilter);biquadFilter.connect(gainNode);gainNode.connect(audioCtx.destination);//操作双二阶滤波器biquadFilter.type = "带通";biquadFilter.frequency.value = 400;biquadFilter.gain.value = 25;
biquadFilter.frequency.value 表示范围频率的中心.范围随着增益值而扩大.
这个过滤器可以像这个例子一样与其他一些GainNode链接,参见https://developer.mozilla.org/en-US/docs/Web/API/GainNode
以类似的方式,在 1000hz 到 1500hz 的范围内使用两个滤波器,一个低通和一个高通.
<块引用><脚本>var audioCtx = new (window.AudioContext)()var a = document.createElement("audio")a.src = "vorbis.ogg"a.setAttribute("控件", "")hello.appendChild(a)var mediaElement = avar gainNode = audioCtx.createGain()var lowpass = audioCtx.createBiquadFilter()var highpass = audioCtx.createBiquadFilter()源 = audioCtx.createMediaElementSource(mediaElement)source.connect(低通)低通连接(高通)高通.connect(gainNode)gainNode.connect(audioCtx.destination)lowpass.type = "低通"低通频率值 = 1000低通增益值 = -1highpass.type = "高通"高通频率值 = 1500高通增益值 = -1
I'm experimenting with the WebAudio API and am attempting to build an analyser that a user can interact with and ultimately turn on and off different frequencies within the music to isolate different beats within the track, i.e bass, kick etc.
I'm visualising the frequency data using the Canvas, and would like the user to be able to highlight parts of the visualisation, and in-turn muting frequencies.
By default the visualisation would look like this and the user would hear all frequencies.
But when the user selects several bars, the greyed out ones would mute the related frequencies:
My thinking is can I reverse-engineer the frequencyData array and essentially mute the associated frequencies?
** Update **
So I've been playing around by adding several biquadFilter
s with a type of notch
in series, and then adjusting their frequency and Q values. This does sort of help isolate pats of the music, but not exactly how I want. This is the code I'm using so far...
const audioContext = new window.AudioContext();
const source = audioContext.createMediaElementSource(element);
const biquadFilter1 = audioContext.createBiquadFilter();
const biquadFilter2 = audioContext.createBiquadFilter();
const biquadFilter3 = audioContext.createBiquadFilter();
const analyser = audioContext.createAnalyser();
biquadFilter1.connect(analyser);
biquadFilter2.connect(analyser);
biquadFilter3.connect(analyser);
source
.connect(biquadFilter1)
.connect(biquadFilter2)
.connect(biquadFilter3);
analyser.connect(audioContext.destination);
I'm not sure if I've set this up correctly, but it does allow me to very roughly manipulate the frequencies, but it feels like there is no accurate science to doing it this way.
Is what I'm attempting possible, and if so, any suggestions are really appreciated :)
What you are looking for is a band pass filter.
A band-pass filter (also bandpass filter, BPF) is a device that passes frequencies within a certain range and rejects (attenuates) frequencies outside that range. https://en.wikipedia.org/wiki/Band-pass_filter
And we are lucky, the web audio api provide it via the BiquadFilterNode.
https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode
So, based on the demo code provided, to apply a band pass filter at the 400Hz frequency range to an html audio player.
The html audio element must be created by js then inserted into the DOM, or it won't works with the web audio api.
<div id="hello"></div>
<script>
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// Create new player
var a = document.createElement("audio");
// Give a source song
a.src = "vorbis.ogg";
// Show the controls
a.setAttribute("controls", "");
// Append to the DOM
hello.appendChild(a);
// Player now ready for the web audio api
var mediaElement = a;
//set up the different audio nodes we will use for the app
var gainNode = audioCtx.createGain();
var biquadFilter = audioCtx.createBiquadFilter();
// connect the nodes together
source = audioCtx.createMediaElementSource(mediaElement);
source.connect(biquadFilter);
biquadFilter.connect(gainNode);
gainNode.connect(audioCtx.destination);
// Manipulate the Biquad filter
biquadFilter.type = "bandpass";
biquadFilter.frequency.value = 400;
biquadFilter.gain.value = 25;
</script>
The biquadFilter.frequency.value represent the center of the range frequencies. The range expands with the gain value.
This filters can be chained just like this example with some other GainNode, see https://developer.mozilla.org/en-US/docs/Web/API/GainNode
In a similar way, using two filters, a lowpass and a highpass, for the range 1000hz to 1500hz.
<div id="hello"></div> <script> var audioCtx = new (window.AudioContext)() var a = document.createElement("audio") a.src = "vorbis.ogg" a.setAttribute("controls", "") hello.appendChild(a) var mediaElement = a var gainNode = audioCtx.createGain() var lowpass = audioCtx.createBiquadFilter() var highpass = audioCtx.createBiquadFilter() source = audioCtx.createMediaElementSource(mediaElement) source.connect(lowpass) lowpass.connect(highpass) highpass.connect(gainNode) gainNode.connect(audioCtx.destination) lowpass.type = "lowpass" lowpass.frequency.value = 1000 lowpass.gain.value = -1 highpass.type = "highpass" highpass.frequency.value = 1500 highpass.gain.value = -1 </script>
这篇关于使用 Web Audio API 隔离音频上下文的频率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!