从wav文件中读取样本

Read samples from wav-file

本文关键字:读取 样本 文件 wav      更新时间:2023-09-26

我正在尝试用html5制作一个网页,它将wav文件中的样本数据存储在数组中。有没有办法用javascript获取样本数据?我正在使用文件输入来选择wav文件。

在我已经添加的javascript中:

document.getElementById('fileinput').addEventListener('change', readFile, false);

但我不知道在readFile中该做什么。

编辑:我试图在ArrayBuffer中获取该文件,将其传递给decodeAudioData方法,并从中获取typedArraybuffer。这是我的代码:

var openFile = function(event) {
var input = event.target;
var audioContext = new AudioContext();
var reader = new FileReader();
reader.onload = function(){
var arrayBuffer = reader.result;
  console.log("arrayBuffer:");
  console.log(arrayBuffer);
  audioContext.decodeAudioData(arrayBuffer, decodedDone);
};
reader.readAsArrayBuffer(input.files[0]);
};
function decodedDone(decoded) {
var typedArray = new Uint32Array(decoded, 1, decoded.length);
  console.log("decoded");
  console.log(decoded);
  console.log("typedArray");
  console.log(typedArray);
for (i=0; i<10; i++)
{
    console.log(typedArray[i]);
}
}

typedArray的元素都是0。我创建typedArray的方式是错误的,还是我在上做了其他错误的事情?

编辑:我终于拿到了。这是我的代码:

var openFile = function(event) {
var input = event.target;
var audioContext = new AudioContext();
var reader = new FileReader();
reader.onload = function(){
var arrayBuffer = reader.result;
  console.log("arrayBuffer:");
  console.log(arrayBuffer);
  audioContext.decodeAudioData(arrayBuffer, decodedDone);
};
reader.readAsArrayBuffer(input.files[0]);
};
function decodedDone(decoded) {
 var typedArray = new Float32Array(decoded.length);
typedArray=decoded.getChannelData(0);
console.log("typedArray:");
console.log(typedArray);
}

谢谢你的回答!

要实现这一点,您需要学习很多关于Web API的知识,但最终很简单。

  1. 使用file API获取ArrayBuffer中的文件内容
  2. 将其传递给Web Audio API的decodeAudioData方法。
  3. 获取一个带有所需原始样本的类型化ArrayBuffer。

编辑:如果你想实现均衡器,你是在浪费时间,在音频API中有一个本地均衡器节点。根据波形文件的长度,最好不要将其全部加载到内存中,而只创建一个从中读取的源,并将该源连接到均衡器节点。

下面是一个简单的代码示例,用于从JavaScript中的wav音频文件中获取Float32Array

let audioData = await fetch("https://example.com/test.wav").then(r => r.arrayBuffer());
let audioCtx = new AudioContext({sampleRate:44100});
let decodedData = await audioCtx.decodeAudioData(audioData); // audio is resampled to the AudioContext's sampling rate
console.log(decodedData.length, decodedData.duration, decodedData.sampleRate, decodedData.numberOfChannels);
let float32Data = decodedData.getChannelData(0); // Float32Array for channel 0

用异步函数封装Joe的代码是有效的。像这样:

async function readAudio(url) {
  let audioData = await fetch(url).then(r => r.arrayBuffer());
  let audioCtx = new AudioContext({sampleRate:8000});
  // audio is resampled to the AudioContext's sampling rate
  let decodedData = await audioCtx.decodeAudioData(audioData);
  console.log(decodedData.length, decodedData.duration,
             decodedData.sampleRate, decodedData.numberOfChannels);
  let float32Data = decodedData.getChannelData(0); // Float32Array for channel 0
  processAudio(float32Data);  // PCM Float32 is between -1 to +1
}
readAudio("Something.wav");