Javascript 使用Web audio API隔离音频上下文的频率

Javascript 使用Web audio API隔离音频上下文的频率,javascript,web-audio-api,Javascript,Web Audio Api,我正在试验WebAudio API,并试图构建一个分析仪,用户可以与之交互,并最终打开和关闭音乐中的不同频率,以隔离曲目中的不同节拍,即低音、基音等 我正在使用画布对频率数据进行可视化,希望用户能够突出显示可视化的部分,进而静音频率 默认情况下,可视化效果如下,用户将听到所有频率 但当用户选择几个条时,灰显的条将使相关频率静音: 我的想法是,我能对frequencyData数组进行反向工程,并基本上使相关频率静音吗 **更新** 因此,我一直在通过添加几个带有notch类型的biquadFi

我正在试验WebAudio API,并试图构建一个分析仪,用户可以与之交互,并最终打开和关闭音乐中的不同频率,以隔离曲目中的不同节拍,即低音、基音等

我正在使用画布对频率数据进行可视化,希望用户能够突出显示可视化的部分,进而静音频率

默认情况下,可视化效果如下,用户将听到所有频率

但当用户选择几个条时,灰显的条将使相关频率静音:

我的想法是,我能对frequencyData数组进行反向工程,并基本上使相关频率静音吗

**更新**

因此,我一直在通过添加几个带有
notch
类型的
biquadFilter
串联,然后调整它们的频率和Q值来进行研究。这确实有助于隔离音乐片段,但并不是我想要的。这是我目前使用的代码

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);
我不确定我是否设置正确,但它确实允许我非常粗略地操纵频率,但感觉这样做没有精确的科学依据


是我尝试的可能,如果是这样,任何建议都非常感谢:)

您正在处理音频,所以您需要的是带通滤波器。这将允许您只播放某些频率

我可以看到你已经在用FFT得到频率了。从那里,你有两个选择。一种是从FFT后获得的阵列中移除所需的频率。然后,为了得到声音,你需要时域中的信号,所以你需要一个逆FFT。另一种选择是在时域中制作滤波器,然后与原始信号进行卷积

我没有发布代码,因为我刚刚用C编写了这些代码,但我非常确定有许多库可以轻松地执行这些操作(卷积/IFFT)。

:)

您需要的是一个带通滤波器

带通滤波器(也称为带通滤波器,BPF)是一种通过 特定范围内的频率和抑制(衰减) 频率超出该范围。

幸运的是,web音频api通过BiquadFilterNode提供

因此,根据提供的演示代码,将400Hz频率范围的带通滤波器应用于html音频播放器

html音频元素必须由js创建,然后插入DOM,否则它将无法与web音频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>

var audioCtx=new(window.AudioContext | | window.webkitadiocontext)();
//创建新玩家
var a=document.createElement(“音频”);
//唱一首源歌
a、 src=“vorbis.ogg”;
//显示控件
a、 setAttribute(“控件”,“控件”);
//附加到DOM
你好,我的孩子(a);
//播放器现在可以使用web音频api了
变量mediaElement=a;
//设置我们将用于应用程序的不同音频节点
var gainNode=audioCtx.createGain();
var biquadFilter=audioCtx.createBiquadFilter();
//将节点连接在一起
source=audioCtx.createMediaElementSource(mediaElement);
source.connect(双四元滤波器);
双四元滤波器连接(增益节点);
gainNode.connect(audioCtx.destination);
//操纵双四元滤波器
biquadFilter.type=“带通”;
biquadFilter.frequency.value=400;
biquadFilter.gain.value=25;
biquadFilter.frequency.value表示范围频率的中心。范围随着增益值的增加而扩大

此过滤器可以像本例一样与其他一些GainNode链接,请参阅

以类似的方式,使用两个滤波器,一个低通滤波器和一个高通滤波器,用于1000hz到1500hz的范围


var audioCtx=new(window.AudioContext)()
var a=document.createElement(“音频”)
a、 src=“vorbis.ogg”
a、 setAttribute(“控件”、“控件”)
你好,孩子(a)
变量mediaElement=a
var gainNode=audioCtx.createGain()
var lowpass=audioCtx.createBiquadFilter()
var highpass=audioCtx.createBiquadFilter()
source=audioCtx.createMediaElementSource(mediaElement)
源连接(低通)
低通。连接(高通)
高通连接(增益节点)
gainNode.connect(audioCtx.destination)
lowpass.type=“低通”
低通频率值=1000
低通增益值=-1
highpass.type=“高通”
高通.frequency.value=1500
高通增益值=-1

删除频率并执行IFFT将不起作用。你没有相位信息。即使你有相位信息,它也不会起作用,因为这个操作不是带限的,所以你会在输出中引入混叠伪影。那么,你有什么建议吗?问题是有点指定不足,但可能是一堆陷波滤波器?或者用FFT模拟一个线性相位,用一个设计程序得到一个脉冲响应,然后在卷积器中使用它?(这是你建议的。)感谢RaymondToy的指点,我尝试过添加陷波滤波器,并更新了问题,希望它更有意义。如果你有时间给我更多的指导,我会非常感激:)你能不能就[].slice()画布绘图部分的数据?如果需要,您可以
Math.max.apply(0,arrData)
以JIT方式重新缩放它…是的,但这不会禁用它们所代表的音频。我可以使用
createMediaElementSource
而不是
createMediaStreamSource
获得相同的结果吗,由于我目前正在使用本机音频元素并播放MP3So,我尝试简单地用
const source=audioContext.createMediaElementSource(元素)替换该行,但现在无法再听到任何输出是。但它需要先由js创建,否则它将无法工作(花时间理解这一点)<
<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>