我的应用程序中有预先录制的音频文件的音频缓冲区。 我试图获取整个音频轨道的频域数据,这是我尝试过的:
getAudioDataFromBuffer: function(buf){
var src = g.audioContext.createBufferSource();
src.buffer = buf;
var anal = src.context.createAnalyser();
src.connect(anal);
var dataArray = new Uint8Array(buf.length);
anal.fftSize = 2048;
anal.getByteFrequencyData(dataArray);
return dataArray;
},
但是这只给了我一个充满零的数组。
我需要这个来比较两个音轨,一个是预先录制的,另一个是在应用程序中录制的。我认为我可以测量它们的频域之间的相关性。
答案 0 :(得分:0)
我认为你需要更多像
这样的东西AudioBuffer.getChannelData()
返回一个Float32Array,其中包含与通道关联的PCM数据,由通道参数定义(0表示第一个通道)。
查看Mozilla或W3C文档。
干杯
Kilian的
答案 1 :(得分:0)
我到达了解决方案,看到this answer和this discussion。
基本上你需要使用OfflineAudioContext。这里的代码从已经加载的音频缓冲区开始:
var offline = new OfflineAudioContext(2, buffer.length ,44100);
var bufferSource = offline.createBufferSource();
bufferSource.buffer = buffer;
var analyser = offline.createAnalyser();
var scp = offline.createScriptProcessor(256, 0, 1);
bufferSource.connect(analyser);
scp.connect(offline.destination); // this is necessary for the script processor to start
var freqData = new Uint8Array(analyser.frequencyBinCount);
scp.onaudioprocess = function(){
analyser.getByteFrequencyData(freqData);
console.log(freqData);
};
bufferSource.start(0);
offline.oncomplete = function(e){
console.log('analysed');
};
offline.startRendering();
答案 2 :(得分:0)
这是一个使用最新版本的 Web Audio API 的工作示例:
注意:您需要从 audioBuffer
开始。您可以使用新的 File System Access API 获得:
const [fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const arrayBuffer = await file.arrayBuffer();
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
拥有 audioBuffer
后,您可以使用 offlineAudioContext
访问其内容:
const offlineAudioContext = new OfflineAudioContext(
audioBuffer.numberOfChannels,
audioBuffer.length,
audioBuffer.sampleRate
);
const bufferSourceNode = offlineAudioContext.createBufferSource();
bufferSourceNode.start(0);
offlineAudioContext
.startRendering()
.then(renderedBuffer => {
const data = renderedBuffer.getChannelData(0);
for (let i = 0, length = data.length; i < length; i += 1) {
// careful here, as you can hang the browser by logging this data
// because 1 second of audio contains 22k ~ 96k samples!
if (!(i % 1000) && i < 250000) console.log(data[i]);
}
}