Шумоподавление с помощью WebAudioApi и WebAssembly - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь создать фильтр шумоподавления в WebRt c, используя мою C библиотеку, скомпилированную в wasm и вызываемую из Javascript.

Я могу записать звук pcm с помощью WebAudioApi и обработать кадр с помощью wasm.

Вот мой код:

navigator.mediaDevices.getUserMedia(constraints).then(function success(stream) {
var audiocontext;
var audiosource;
var audiopreprocessnode;

 audiocontext = new (window.AudioContext || window.webkitAudioContext)();
 audiosource = audiocontext.createMediaStreamSource(stream);
 audioPreprocessNode = audioCtx.createScriptProcessor(2048,1,1);

 audiosource.connect(audioPreprocessNode);
 audioPreprocessNode.connect(audioCtx.destination);
 
 audioPreprocessNode.onaudioprocess = function(e) {
 
console.log(e.inputBuffer.getChannelData(0));

 // audio captured from mic is denoised using wasm
 var denoised_array = Module["_denoise"](e.inputBuffer.getChannelData(0));
 e.inputBuffer.getChannelData(0).set(denoised_array);
 
 console.log(e.inputBuffer.getChannelData(0)); 
 
 }
   
}

Я использовал onaudioprocess для захвата входного кадра и установки обработанного (с шумоподавлением) кадра во входном буфере. Я использовал два журнала, чтобы проверить, изменились ли значения после обработки и они меняются. Однако обработанные значения не отправляются в поток webrt c, неизмененный исходный кадр отправляется только в поток.

После изучения WebaudioApi docs, я обнаружил, что «Любые изменения скрипта в этом AudioBuffer за пределами этой области не будут давать никаких звуковых эффектов».

https://www.w3.org/2014/annotation/experiment/webaudio.html#AudioProcessingEvent -section

Есть ли вообще чтобы отправить этот обработанный (очищенный от шума) кадр в потоке webrt c. Любая помощь будет принята.

1 Ответ

1 голос
/ 10 июля 2020

Если вы хотите, чтобы ScriptProcessorNode выводил измененный сигнал, вам необходимо установить outputbuffer на AudioProcessingEvent.

// ...

var denoised_array = Module["_denoise"](e.inputBuffer.getChannelData(0));

e.outputbuffer.getChannelData(0).set(denoised_array);

// ...
...