Повторная выборка звукового сэмпла, какой фильтр мне использовать? - PullRequest
5 голосов
/ 09 декабря 2010

Я пытаюсь повторно сэмплировать сигнал (звуковой сэмпл) с одной частоты дискретизации до более высокой частоты дискретизации.К сожалению, для этого нужен какой-то фильтр, так как, похоже, происходит какое-то «наложение», и я не знаком с фильтрами.Вот что я придумал:

int i, j, a, b, z;

a = 44100;
b = 8363;

// upsample by a
for(i = z = 0; i < samplen; i++)
    for(j = 0; j < a; j++)
        cbuf[z++] = sampdata[i];

// some filter goes here???

// downsample by b
for(j = i = 0; i < z; i += b)
    buf[j++] = cbuf[i];

Новый сэмпл очень похож на оригинальный, но в нем есть какой-то шум.Подскажите, пожалуйста, какой фильтр мне нужно добавить, и, желательно, какой-нибудь код, связанный с этим фильтром?

Исходный звук: http://www.mediafire.com/?9gnga1in52d6t4x Повторный звук: http://www.mediafire.com/?x34h7ggk8n9k8z1

Ответы [ 6 ]

11 голосов
/ 09 декабря 2010

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

Вам нужен интерполяционный фильтр нижних частот со стоп-полосой, начинающейся ниже половины меньшей из двух частот дискретизации, с которыми вы имеете дело. Распространенными методами реализации этого являются повышающая / понижающая дискретизация с использованием БИХ-фильтров и многофазных КИХ-фильтров. Оконный интерполятор Sinc также хорошо подходит для этого, если вам не нужна производительность в реальном времени и вы не хотите повышать / понижать выборку. Вот Windowed Sinc интерполяционный фильтр нижних частот в Basic , который должен быть тривиальным для преобразования в C.

Если вы хотите использовать БИХ-фильтрацию, вот каноническая Кулинарная книга для биквадраческих БИХ-фильтров .

Если вы хотите получить лучшее объяснение теории передискретизации звука, вот Стэнфордская страница CCRMA Resampling .

10 голосов
/ 09 декабря 2010

Рассматривали ли вы использование для этого специализированной библиотеки, такой как libsamplerate ?

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

2 голосов
/ 09 декабря 2010

Несколько комментариев, хотя я только догадываюсь о ваших реальных намерениях:

  • Вы повышаете частоту дискретизации 44100 раз исходной частоты дискретизации. Например, если ваш вход был на частоте 10 кГц, ваш промежуточный cbuf[] был бы на частоте 441 МГц, что немного выше для большинства аудио анализа. Предполагая, что вы хотите, чтобы cbuf[] был на частоте 44100 Гц, вам нужно только создать 44100/OrigSampleRate семплов в cbuf[] для семпла в sampdata[].
  • Вы увеличиваете z в два раза в цикле повышающей дискретизации. В результате все нечетные элементы cbuf[] будут иметь свои исходные значения. Я полагаю, что в конечном итоге это приведет к тому, что в финале buf[] появятся недопустимые нечетные элементы, которые могут быть источником вашего шума. Существует также потенциальное переполнение буфера в cbuf, если вы не создали его хотя бы вдвое больше необходимого количества элементов.
  • Как уже упоминал Стив, линейная интерполяция, как правило, самая простая, которая создает хороший результат при повышающей дискретизации. При желании можно выполнить более сложное повышение дискретизации (полиномы, сплайны и т. Д.). Точно так же при понижающей дискретизации вы можете усреднить выборки, а не просто усекать.
1 голос
/ 04 апреля 2012

Лучший код повторной выборки, с которым я когда-либо сталкивался: http://shibatch.sourceforge.net/

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

0 голосов
/ 01 октября 2014

Прежде чем выполнить повторную выборку с более низкой частотой выборки, вы ДОЛЖНЫ отфильтровать низкие частоты оригинала менее чем в 1/2 раза, иначе вы будете вносить искажающие артефакты. Спектр сворачивается на себя для частот, больше чем половина частоты дискретизации. Поэтому, если вы хотите выполнить повторную выборку до 11025 из 44100, вы должны фильтровать 44100 нижних частот при 1/2 от 11025 или 5500 Гц, поскольку точность воспроизведения снижается при более низких полосах пропускания, лучше всего делать это с максимальной амплитудой, например, -10 дБ амплитуды. Для подписанных 16 битов значение равно 10 ^ (- 10/20) * 2 ^ (16-1) или 10362 +/- для максимальной амплитуды. Точные алгоритмы могут быть найдены в Интернете, так как не должно быть никаких интеллектуальных прав на эти старые и основные идеи. После выполнения всех вычислений без округления с плавающей запятой двойной точности вы округляете результаты до их целочисленных значений и интерполируете по шкале времени точно там, где один набор пересекает другой. Это требует большого воображения, памяти и предыдущего опыта, который затем ставит вас в область математики-программиста по физике. : -O: -)

0 голосов
/ 14 апреля 2011

Используйте FFMpeg и avcodec напрямую. Вот хороший пример, показывающий, как это сделать:

http://tdistler.com/projects/audio-resampling-with-ffmpeg

...