javascript - 努力播放 Float 32 数组(Web 音频 API)
问题描述
我正在构建一个简单的循环器,以帮助我了解 Web Audio API,但努力获取缓冲源来播放录制的音频。
代码已尽可能简化,但注释仍然是 70 多行,省略了 CSS 和 HTML,因此对此深表歉意。可以在 JSFiddle 上找到包含 CSS 和 HTML 的版本:
https://jsfiddle.net/b5w9j4yk/10/
任何帮助将非常感激。谢谢 :)
// Aim of the code is to record the input from the mike to a float32 array. then prass that to a buffer which is linked to a buffer source, so the audio can be played back.
// Grab DOM Elements
const playButton = document.getElementById('play');
const recordButton = document.getElementById('record');
// If allowed access to microphone run this code
const promise = navigator.mediaDevices.getUserMedia({audio: true, video: false})
.then((stream) => {
recordButton.addEventListener('click', () => {
// when the record button is pressed clear enstanciate the record buffer
if (!recordArmed) {
recordArmed = true;
recordButton.classList.add('on');
console.log('recording armed')
recordBuffer = new Float32Array(audioCtx.sampleRate * 10);
}
else {
recordArmed = false;
recordButton.classList.remove('on');
// After the recording has stopped pass the recordBuffer the source's buffer
myArrayBuffer.copyToChannel(recordBuffer, 0);
//Looks like the buffer has been passed
console.log(myArrayBuffer.getChannelData(0));
}
});
// this should stat the playback of the source intended to be used adter the audio has been recorded, I can't get it to work in this given context
playButton.addEventListener('click', () => {
playButton.classList.add('on');
source.start();
});
//Transport variables
let recordArmed = false;
let playing = false;
// this buffer will later be assigned a Float 32 Array / I'd like to keep this intimediate buffer so the audio can be sliced and minipulated with ease later
let recordBuffer;
// Declear Context, input source and a block processor to pass the input sorce to the recordBuffer
const audioCtx = new AudioContext();
const audioIn = audioCtx.createMediaStreamSource(stream);
const processor = audioCtx.createScriptProcessor(512, 1, 1);
// Create a source and corrisponding buffer for playback and then assign link
const myArrayBuffer = audioCtx.createBuffer(1, audioCtx.sampleRate * 10, audioCtx.sampleRate);
const source = audioCtx.createBufferSource();
source.buffer = myArrayBuffer;
// Audio Routing
audioIn.connect(processor);
source.connect(audioCtx.destination);
// When recording is armed pass the samples of the block one at a time to the record buffer
processor.onaudioprocess = ((audioProcessingEvent) => {
let inputBuffer = audioProcessingEvent.inputBuffer;
let i = 0;
if (recordArmed) {
for (let channel = 0; channel < inputBuffer.numberOfChannels; channel++) {
let inputData = inputBuffer.getChannelData(channel);
let avg = 0;
inputData.forEach(sample => {
recordBuffer.set([sample], i);
i++;
});
}
}
else {
i = 0;
}
});
})
解决方案
推荐阅读
- mysql - 如何显示两个共享 id 的表的结果?
- c++ - std::is_same - 从integral_constant 继承函数的用例
- powershell - 使用 PowerShell 和新式身份验证连接到 Exchange Online(无任何依赖项)
- android - 如何为新创建的实例添加 Fragment 标签?
- php - PHP中如何让用户选择输出目录
- java - 队列实现不返回第一个元素
- r - 在 ggplot 中有多行(熔融数据)的工作日解决方法吗?
- python - Keras 多层神经网络精度
- css - 选择焦点后保持背景颜色 Microsoft Edge
- java - Android Asset Manager 无法从 assets 目录加载 wav 文件资源