标准化PCM数据

时间:2013-07-21 14:51:32

标签: java android audio

我使用以下代码来规范化PCM音频数据,这是规范化的正确方法吗?正常化后,我正在申请LPF。订单是否首先执行LPF以及对其输出进行标准化或者当前订单是否更好才有意义。此外,我的targetMax设置为8000,我在此论坛的帖子中使用了它。什么是它的最佳价值。我的输入是16位MONO PCM,采样率为44100。

private static int findMaxAmplitude(short[] buffer) {
    short max = Short.MIN_VALUE;
    for (int i = 0; i < buffer.length; ++i) {
        short value = buffer[i];
        max = (short) Math.max(max, value);
    }
    return max;
}

short[] process(short[] buffer) {
    short[] output = new short[buffer.length];
    int maxAmplitude = findMaxAmplitude(buffer);
    for (int index = 0; index < buffer.length; index++) {
        output[index] = normalization(buffer[index], maxAmplitude);
    }
    return output;
}

private short normalization(short value, int rawMax) {
    short targetMax = 8000;
    double maxReduce = 1 - targetMax / (double) rawMax;
    int abs = Math.abs(value);
    double factor = (maxReduce * abs / (double) rawMax);

    return (short) Math.round((1 - factor) * value);
}

1 个答案:

答案 0 :(得分:1)

您的findMaxAmplitude仅查看正偏移。它应该使用像

这样的东西
max = (short)Math.Max(max, Math.Abs(value));

您的正常化似乎非常复杂。更简单的版本将使用:

return (short)Math.Round(value * targetMax / rawMax);

8000的targetMax是否正确是一个品味问题。通常我会期望16位样本的归一化使用最大值范围。所以32767的targetMax似乎更合乎逻辑。 应该在LPF操作之后进行归一化,因为LPF的增益可能会改变序列的最大值。