Java алгоритм для нормализации звука

Я пытаюсь нормализовать аудиофайл речи.

В частности, где аудиофайл содержит пики в объеме, яЯ пытаюсь выровнять его, чтобы тихие участки были громче, а пики тише.

Я очень мало знаю о звуковых манипуляциях, помимо того, что ямы научились работать над этой задачей. Кроме того, моя математика смущающе слаба.

Мы провели некоторое исследование, и на сайте Xuggle приведен пример, показывающий уменьшение объема с помощью следующего кода: (полная версия здесь)

@Override
  public void onAudioSamples(IAudioSamplesEvent event)
{
  // get the raw audio byes and adjust it's value 

  ShortBuffer buffer = event.getAudioSamples().getByteBuffer().asShortBuffer();
  for (int i = 0; i < buffer.limit(); ++i)
    buffer.put(i, (short)(buffer.get(i) * mVolume));

  super.onAudioSamples(event);
}

Здесь они модифицируют байты вgetAudioSamples() константой.mVolume

Основываясь на этом подходе, япопытка нормализации изменяет байты вgetAudioSamples() к нормированному значению, учитывая максимум / мин в файле. (Подробности смотрите ниже). У меня есть простой фильтр, чтобы уйтитишина» один (то есть, что-нибудь ниже значения) .I '

обнаружив, что выходной файлочень шумно (т. е. качество серьезно ухудшается). Я предполагаю, что ошибка либо в моём алгоритме нормализации, либо в способе манипулирования байтами. Однако я'Я не уверен, куда идти дальше.

Вот'это сокращенная версия того, что ям в настоящее время занимаюсь.

Шаг 1: Найти пики в файле:

Читает полный аудиофайл и находит это самое высокое и самое низкое значенияbuffer.get() для всех AudioSamples

    @Override
    public void onAudioSamples(IAudioSamplesEvent event) {
        IAudioSamples audioSamples = event.getAudioSamples();
        ShortBuffer buffer = 
           audioSamples.getByteBuffer().asShortBuffer();

        short min = Short.MAX_VALUE;
        short max = Short.MIN_VALUE;
        for (int i = 0; i < buffer.limit(); ++i) {
            short value = buffer.get(i);
            min = (short) Math.min(min, value);
            max = (short) Math.max(max, value);
        }
        // assign of min/max ommitted for brevity.
        super.onAudioSamples(event);

    }
Шаг 2: нормализуйте все значения:

В цикле, подобном шагу 1, замените буфер нормализованными значениями, вызвав:

    buffer.put(i, normalize(buffer.get(i));

public short normalize(short value) {
    if (isBackgroundNoise(value))
        return value;

    short rawMin = // min from step1
    short rawMax = // max from step1
    short targetRangeMin = 1000;
    short targetRangeMax = 8000;

    int abs = Math.abs(value);
    double a = (abs - rawMin) * (targetRangeMax - targetRangeMin);
    double b = (rawMax - rawMin);
    double result = targetRangeMin + ( a/b );

     // Copy the sign of value to result.
    result = Math.copySign(result,value);
    return (short) result;
}
Вопросы:Это правильный подход для попытки нормализовать аудиофайл?Моя математика вnormalize() действует?Почему это может привести к шуму файла, когда подобный подход в демонстрационном коде нет? "Я

Ответы на вопрос(2)

Ваш ответ на вопрос