我正在嘗試使用AudioContext
對象播放原始PCM16緩衝區。聲音的確在播放,但是以非常飽和的方式播放。使用JavaScript播放PCM16時的飽和聲音
該問題可能來自將無符號16位整數轉換爲[-1.0; 1.0]漂浮,但我沒有看到我在做什麼的問題。
我在下面做了一個最小的html示例以方便複製。該output.raw
文件可以從MP3文件用下面的命令來獲得:
MP3FILE=myfile.mp3
ffmpeg -i $MP3FILE -f s16le -ac 1 -acodec pcm_s16le output.raw
我使用Linux鉻Version 38.0.2125.111 (290379) (64-bit)
。
感謝您的幫助!
編輯:直接加載PCM32(s32le)樣品表現出同樣的問題。
<html>
<head>
</head>
<body>
<script>
var oReq = new XMLHttpRequest();
oReq.open("GET", "output.raw", true);
oReq.responseType = "arraybuffer";
oReq.onload = function (oEvent) {
var context = new window.AudioContext();
var pcm16Buffer = new Uint16Array(oReq.response);
var frameCount = pcm16Buffer.length;
var channels = 1;
var buffer = context.createBuffer(channels, frameCount, context.sampleRate);
for (var channel = 0; channel < channels; ++channel) {
var channelBuffer = buffer.getChannelData(channel);
for (var i = 0; i < frameCount; ++i) {
channelBuffer[i] = pcm16Buffer[i] * 2/65535 - 1;
}
}
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start();
};
function run() {
oReq.send();
}
</script>
<a href="javascript:run()">run</a>
</body>
</html>
答: 以上的for循環轉換PCM16到PCM32是不正確,因爲它不正確地轉換二進制補碼。
哦,你是對的,這樣一個愚蠢的錯誤。非常感謝你! – 2014-11-08 19:15:02
如果一個值是正的,則在32767上除,否則爲32768,即。 '... = pcm16Buffer [i] <0? pcm16Buffer [i]/32768:pcm16Buffer [i]/32767;' – K3N 2015-05-14 13:27:32