В частности, если аудиофайл содержит пики громкости, я пытаюсь их выровнять, поэтому тихие участки громче, а пики тише.
Я очень мало знаю о манипуляциях со звуком, кроме того, что я узнал, работая над этой задачей. Кроме того, мои математические расчеты до неприличия слабы.
Я провел небольшое исследование, и на сайте 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(), приведя их к нормализованному значению с учетом максимального/минимального значения в файле. (Подробнее см. ниже). У меня есть простой фильтр, позволяющий оставить без изменений «тишину» (т. е. все, что ниже значения).
Я обнаружил, что выходной файл имеет вид очень шумно (т. е. качество серьезно ухудшилось). Я предполагаю, что ошибка связана либо с моим алгоритмом нормализации, либо с тем, как я манипулирую байтами. Однако я не уверен, куда двигаться дальше.
Вот сокращенная версия того, чем я сейчас занимаюсь.
Шаг 1. Найдите пики в файле:
Читает весь аудиофайл и находит самые высокие и самые низкие значения buffer.get() для всех аудиосэмплов
Код: Выделить всё
@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);
}
В цикле, аналогичном шагу 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()?
- Почему это может привести к тому, что файл станет зашумлен, если аналогичный подход в демонстрационном коде нет?
Подробнее здесь: https://stackoverflow.com/questions/124 ... zing-audio