【问题标题】:Downsampling a PCM audio buffer in javascript在javascript中对PCM音频缓冲区进行下采样
【发布时间】:2015-03-29 10:14:06
【问题描述】:

我正在尝试对从 audioContext 获得的采样率进行下采样。我相信它会在 44100 进入,我希望它是 11025。我以为我可以平均每 3 个样本并以正确的速率播放,但是音高太高,好像我们都在氦气上.

在 11025 个样本处将 float32Array 从 44100 下采样到 int16Array 的正确方法是什么。

var context = new Flash.audioContext();
var audioInput = context.createMediaStreamSource(stream);
var recorder = context.createScriptProcessor(null, 1, 1);
recorder.onaudioprocess = onAudio;
audioInput.connect(recorder);
recorder.connect(context.destination);

var onAudio = function (e) {
    var left = e.inputBuffer.getChannelData(0);
    bStream.write(Flash.convertFloat32ToInt16(left));
}

var convertFloat32ToInt16 = function(buffer) {
    var l = buffer.length;
    var point = Math.floor(l/3);
    var buf = new Int16Array(point);
    for (var x = l; x > 0;) {
        var average = (buffer[x] + buffer[x-1] +  buffer[x-2]) / 3;
        buf[point] = average*0x7FFF;
        point -= 1;
        x -= 3;
    }
    return buf.buffer;
}

【问题讨论】:

    标签: javascript html node.js audio webkitaudiocontext


    【解决方案1】:

    对于其他需要答案的人。

    var downsampleBuffer = function (buffer, sampleRate, outSampleRate) {
        if (outSampleRate == sampleRate) {
            return buffer;
        }
        if (outSampleRate > sampleRate) {
            throw "downsampling rate show be smaller than original sample rate";
        }
        var sampleRateRatio = sampleRate / outSampleRate;
        var newLength = Math.round(buffer.length / sampleRateRatio);
        var result = new Int16Array(newLength);
        var offsetResult = 0;
        var offsetBuffer = 0;
        while (offsetResult < result.length) {
            var nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
            var accum = 0, count = 0;
            for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
                accum += buffer[i];
                count++;
            }
    
            result[offsetResult] = Math.min(1, accum / count)*0x7FFF;
            offsetResult++;
            offsetBuffer = nextOffsetBuffer;
        }
        return result.buffer;
    }
    

    这将返回一个小于传递给它的采样率,同时还将其转换为 int16Array 而不是 float32。

    【讨论】:

    • 感谢上帝的这篇文章。帮了我很多你不知道。
    • 我很高兴它能够帮助某人 :) 解决这个问题。
    • 你拯救了我的一天:'D
    • 我发现用这种方法转换的声音有很多噪音。
    • 这个解决方案是 4 年前写的,从那以后整个音频库都发生了变化。不要以为它会像以前那样工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-21
    • 1970-01-01
    • 2012-02-03
    • 2013-03-26
    • 1970-01-01
    相关资源
    最近更新 更多