2013-07-21 2 views
1

Я использую следующий код для нормализации аудиоданных PCM. Правильно ли это нормализовать? После нормализации я применяю LPF. Требует ли порядок, нужно ли сначала выполнять LPF и нормализовать его выход, или мой текущий порядок лучше, только если это имеет значение. Также мой targetMax установлен в 8000, который я использовал из публикации этого форума. Каково оптимальное значение для него. Мой вход 16 бит моно PCM с частотой дискретизации 44100.Нормализуйте данные PCM

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

Ваш findMaxAmplitude смотрит только на положительные экскурсии. Он должен использовать что-то вроде

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

Ваша нормализация кажется довольно привлекательной. Более простой вариант будет использовать:

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

Является ли targetMax 8000 правильно это дело вкуса. Обычно я ожидал нормализации 16-битных выборок, чтобы использовать максимальный диапазон значений. Таким образом, targetMax 32767 кажется более логичным. Нормализация, вероятно, должна быть выполнена после операции LPF, так как усиление LPF может изменить максимальное значение вашей последовательности.

Смежные вопросы