Anonymous Me
Anonymous Me

Reputation: 1238

Normalize the PCM data

I am using following code to normalize PCM audio data, Is this the correct way to normalize? After Normalization I am applying LPF. Does the order matters whether to do LPF first and Normalization on its output or my current order is better only if that matters. Also my targetMax is set to 8000 which I used from on of this forum's posting. What is the optimal value for it. My input is 16 bit MONO PCM with sample rate of 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);
}

Upvotes: 2

Views: 1950

Answers (1)

Han
Han

Reputation: 2037

Your findMaxAmplitude only looks at the positive excursions. It should use something like

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

Your normalization seems quite involved. A simpler version would use:

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

Whether a targetMax of 8000 is correct is a matter of taste. Normally I would expect normalisation of 16-bit samples to use the maximum range of values. So a targetMax of 32767 seems more logical. The normalization should probably be done after the LPF operation, as the gain of the LPF may change the maximum value of your sequence.

Upvotes: 1

Related Questions