Изолировать частоты аудиоконтента с помощью API веб-аудио

Я экспериментирую с API WebAudio и пытаюсь создать анализатор, с которым пользователь может взаимодействовать и в конечном счете включать и выключать разные частоты в музыке, чтобы изолировать различные удары в треке, то есть бас, удар и т.д.

Я визуализую данные частоты с помощью 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 analyser = audioContext.createAnalyser();

biquadFilter1.connect(analyser);
biquadFilter2.connect(analyser);
biquadFilter3.connect(analyser);
source
    .connect(biquadFilter1)
    .connect(biquadFilter2)
    .connect(biquadFilter3);
analyser.connect(audioContext.destination);

Я не уверен, правильно ли я настроил это, но это позволяет мне очень грубо манипулировать частотами, но похоже, что нет точной науки, чтобы делать это таким образом.

Я пытаюсь сделать это, и если да, то любые предложения действительно оценены:)

Ответ 1

Что вы ищете, это фильтр band pass.

Полосовой фильтр (также полосовой фильтр, BPF) - это устройство, которое проходит частоты в пределах определенного диапазона и отклоняет (ослабляет) частоты вне этого диапазона. https://en.wikipedia.org/wiki/Band-pass_filter

И нам повезло, веб-аудио api предоставляет его через BiquadFilterNode.

https://developer.mozilla.org/en-US/docs/Web/API/BiquadFilterNode

Итак, на основе предоставленного демо-кода, применить фильтр полосовых частот в частотном диапазоне 400 Гц к аудиоплееру html.

Элемент аудио html должен быть создан js, а затем вставлен в DOM, или он не будет работать с веб-аудио 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>

Значение biquadFilter.frequency.value представляет собой центр частот диапазона. Диапазон расширяется с коэффициентом усиления.

Эти фильтры могут быть скованы так же, как этот пример, с помощью другого GainNode, см. https://developer.mozilla.org/en-US/docs/Web/API/GainNode p >

Аналогичным образом, используя два фильтра, нижний и верхний пределы, в диапазоне от 1000 до 1500 Гц.

<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>

Ответ 2

Вы работаете со звуком, так что вам нужен полосовой фильтр. Это позволит вам воспроизводить только определенные частоты.

Я вижу, что вы уже используете FFT для получения частот. Оттуда у вас есть два варианта. Один из них - удалить частоты, которые вы хотите получить из этого массива, полученного после выполнения БПФ. Затем, чтобы получить звук, вам нужен сигнал во временной области, поэтому вам понадобится обратный БПФ. Другой вариант - сделать ваш фильтр во временной области, а затем сделать свертку с исходным сигналом.

Я не отправляю код, так как Ive просто сделал это на C, но Im довольно уверен, что есть много библиотек, которые легко выполняют эти операции (Convolution/IFFT).
:)