Автоматическая регулировка усиления с помощью веб-аудио API
Это код, который я сделал для добавления AGC к аудио в формате mp3. Он показывает два метра, один для исходного сигнала, один для нормализованного сигнала.
- ScriptProcessor получить информацию о томе
- Узловая сеть используется для изменения окончательного сигнала из данных скриптового процессора.
Кажется, что 2-й измеритель работает только графически, но я не могу прослушать разницу между оригинальным звуком и звуком, контролируемым AGC, хотя я подключил его к выходу назначения.
<script>
var audioContext = null;
var canvasContext = null;
var canvasContextAGC = null;
window.onload = function() {
canvasContext = document.getElementById( "meterSong" ).getContext("2d");
canvasContextAGC = document.getElementById( "meterAGC" ).getContext("2d");
audioContext = new AudioContext();
var audio = new Audio();
audio.src = 'test4.mp3';
audio.autoplay = true;
mediaStreamSource = audioContext.createMediaElementSource(audio);
gainNode = audioContext.createGain();
processor = audioContext.createScriptProcessor();
processor.volume = 1;
processor.onaudioprocess = function volumeAudioProcess(event) {
var buf = event.inputBuffer.getChannelData(1);
var bufLength = buf.length;
var sum = 0;
var x;
for (var i=0; i<bufLength; i++) {
x = buf[i];
sum += x * x;
}
var rms = Math.sqrt(sum / bufLength);
this.volume = Math.max(rms, this.volume*0.2);
gainNode.gain.setTargetAtTime(1-this.volume, audioContext.currentTime, 0);
};
processor.connect(audioContext.destination);//This is a well-known bug
mediaStreamSource.connect(gainNode);
mediaStreamSource.connect(processor);
gainNode.connect(audioContext.destination);
drawLoop();
drawLoopACG();
}
function drawLoop(time) {
canvasContext.clearRect(0,0,500,200);
canvasContext.fillRect(0, 0, processor.volume*1000, 20);
window.requestAnimationFrame(drawLoop);
}
function drawLoopACG(time) {
canvasContextAGC.clearRect(0,0,500,200);
canvasContextAGC.fillRect(0, 0, gainNode.gain.value*200, 20);
window.requestAnimationFrame(drawLoopACG);
}
</script>
<canvas id="meterSong" width="500" height="50"></canvas>
<br/>
<canvas id="meterAGC" width="500" height="50"></canvas>