java - 规范化 PCM 数据

标签 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);
}

最佳答案

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

max = (short)Math.Max(max, Math.Abs(value));

您的规范化似乎很复杂。一个更简单的版本将使用:

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

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

关于java - 规范化 PCM 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17773602/

相关文章:

Java/Android - 将对象传递给打开资源的方法

java - 从字符串中删除后备数组

java - 堆栈 Pane 中的底部节点消失

android - 如何在 Android 上调试网站?

audio - 在树莓派上播放网站音频输出

java - 从预序位串构建二叉树

java - 就地复制位图会泄漏内存吗?

javascript - addJavascriptInterface 在 Android 中不返回字符串值

java - Java中的音频音量控制(增加或减少)

node.js - 将音频文件转换为 16 位线性 PCM