Алгоритм PCM для повышения частоты дискретизации

У меня есть звук PCM 8k16bit, и я хочу увеличить его до 16k16bit. Я должен сделать это вручную.

Может кто-нибудь сказать мне алгоритм линейной интерполяции? Должен ли я интерполировать между каждыми двумя байтами?

Кроме того, когда я повышаю частоту дискретизации, мне нужно внести изменения в заголовок wav - что я должен изменить?


person gop    schedule 23.03.2011    source источник


Ответы (4)


Как уже упоминалось, линейная интерполяция не дает наилучшего качества звука, но она проста и дешева.

Для каждого нового образца, который вы создаете, просто усредняйте его со следующим, например.

short[] source = ...;
short[] result = new short[source.length * 2];
for(int i = 0; i < source.length; ++i) {
  result[i * 2] = source[i];
  result[i * 2 + 1] = (source[i] + source[i + 1]) / 2;
}

Вам обязательно следует поискать библиотеку, которая поможет вам работать с файлами WAV. Несмотря на то, что это простой формат, вам не нужно делать это самостоятельно, если есть доступный код, который будет делать то, что вам нужно. Кстати, зачем ты это делаешь в первую очередь? Возможно, вы могли бы просто использовать sox или аналогичный инструмент для этого.

person Martin Vilcans    schedule 24.03.2011

Может кто-нибудь сказать мне алгоритм линейной интерполяции? Должен ли я интерполировать между каждыми двумя байтами?

Конечно:

double interpolate_linear(double a, double b, double x) {
    assert(0.0 <= x);
    assert(1.0 >= x);

    if (0.0 >= x)
        return a;
    else if (1.0 <= x)
        return b;
    else
        return (1.0 - x) * a + x * b;
}

линейная интерполяция, хотя и лучше, чем ничего, имеет большое количество ошибок. лучше обнулить заполнение и окно, если у вас есть процессорное время.

Кроме того, когда я повышаю частоту дискретизации, мне нужно внести изменения в заголовок wav - что я должен изменить?

не уверен для java.

person justin    schedule 23.03.2011
comment
Обратите внимание, что окно — это нечто другое; фильтр тут самое подходящее слово... - person Oliver Charlesworth; 23.03.2011

Вот хорошая ссылка для работы с файлами WAV в java:

http://www.labbookpages.co.uk/audio/javaWavFiles.html

person MusiGenesis    schedule 24.03.2011

Не уверен насчет заголовка, но я бы рассмотрел интерполяцию кубических сплайнов. Вы можете посмотреть на этом веб-сайте. У него очень аккуратный способ выполнения кубической интерполяции. Я не уверен, как изменить заголовок, но я уверен, что в Stack Overflow есть ответы на этот вопрос, которые вы могли бы найти.

person Phonon    schedule 23.03.2011
comment
Хорошо, я использую линейную интерполяцию, и расчеты кажутся правильными, но все, что я получаю, это какой-то статический шум. Я интерполирую каждые два байта, добавляя между ними новый байт... но я думаю, что это моя ошибка. Поскольку PCM 16-битный, это означает, что на выборку приходится 16 бит, поэтому, возможно, мне следует интерполировать между каждыми двумя выборками (фрагментами по 16 бит). Это правильно, или я неправильно понял всю идею? - person gop; 23.03.2011
comment
Если вы покажете свой код, я могу взглянуть на него и посмотреть, если что-то не так (только часть интерполяции). - person Phonon; 23.03.2011
comment
@gosho: Да, конечно, вы должны интерполировать между парами выборок, а не парами байтов. Отдельные байты не имеют значения. - person Oliver Charlesworth; 23.03.2011
comment
@ Оли Чарльзворт, спасибо. Это имеет смысл... я не знаю, почему я начал интерполяцию между байтами. Итак, как я должен интерполировать целые образцы? Допустим, у меня есть образцы A и B (каждый по 16 бит). Как образуется полученный образец С? Он формируется как C[i]=(A[i]+B[i])/2 для каждого i? В настоящее время мой алгоритм в основном использует алгоритм, предложенный @Justin, с x = 1/2. Сейчас я не за компьютером, где код, но завтра могу показать код. - person gop; 23.03.2011
comment
да. Когда вы выполняете линейную интерполяцию, каждая новая выборка представляет собой среднее значение двух выборок, между которыми она находится. - person Phonon; 23.03.2011
comment
Еще раз спасибо за помощь завтра напишу о результатах - надеюсь удачно :) - person gop; 23.03.2011
comment
Спасибо, ребята, у меня не было времени, чтобы ответить последние несколько дней. Это сработало великолепно. У меня все еще есть вопросы о заголовке wav, но я создам для этого еще один вопрос. Было бы неплохо использовать некоторые API для манипуляций с wav, но я работаю над мобильной версией Blackberry Java и не знаю таких библиотек. Спасибо еще раз! - person gop; 28.03.2011
comment
Кубическая интерполяция лучше, чем линейная интерполяция, но все же не так хороша. stackoverflow.com/questions/1851384/ - person endolith; 23.09.2011