Я пытаюсь воспроизвести необработанные буферы PCM16 с объектом AudioContext
. Звук действительно играет, но очень насыщенно.Насыщенный звук при воспроизведении PCM16 с JavaScript
Проблема может возникнуть в результате преобразования беззнаковых 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 Chromium 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>
ОТВЕТ: выше для цикла преобразования PCM16 в PCM32 некорректен, так как это не правильно преобразовать двоичное дополнение.
О, ты прав, такая глупая ошибка. Большое спасибо! –
Если значение положительное деление на 32767, отрицательное 32768, т.е. '... = pcm16Buffer [i] <0? pcm16Buffer [i]/32768: pcm16Buffer [i]/32767; ' – K3N