Реализация фильтра нижних частот с постобработкой с использованием основного звука

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

- (void)processDataWithInBuffer:(const int16_t *)buffer outBuffer:(int16_t *)outBuffer sampleCount:(int)len {   
    BOOL positive;
    for(int i = 0; i < len; i++) {
        positive = (buffer[i] >= 0);
        currentFilteredValueOfSampleAmplitude = LOWPASSFILTERTIMESLICE * (float)abs(buffer[i]) + (1.0 - LOWPASSFILTERTIMESLICE) * previousFilteredValueOfSampleAmplitude;
        previousFilteredValueOfSampleAmplitude = currentFilteredValueOfSampleAmplitude; 
        outBuffer[i] = currentFilteredValueOfSampleAmplitude * (positive ? 1 : -1);
    }
}

Что я могу сделать, чтобы преобразовать этот код в код, который позволит мне обрезать частоты выше определенного Гц на определенный уровень дБ?


person coneybeare    schedule 12.11.2010    source источник


Ответы (3)


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

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

Это на C++, но оно должно помочь вам начать работу. . Извините, я не могу дать конкретный ответ.

person Stephen Furlani    schedule 12.11.2010
comment
Эта функция является ядром класса, выполняющего буферизацию и работу с файлами. Все работает правильно, но я хочу преобразовать в hz и db, а не использовать срез, основанный на времени, как единственную переменную. - person coneybeare; 12.11.2010
comment
Ах хорошо. Проверьте код, на который я ссылался в разделе C++, он действительно хорош. Он вернет фильтр на основе частоты. - person Stephen Furlani; 12.11.2010
comment
именно то, что я искал. потрясающая находка - person coneybeare; 13.11.2010
comment
@coneybeare, рад, что смог помочь. - person Stephen Furlani; 15.11.2010

У вас есть БИХ-фильтр, и для большего контроля я бы предложил использовать КИХ-фильтр, для которого легче вычислить коэффициенты. Я создаю оконную функцию, которая:

y = sin (x * bandwidth) / (sin (x) * windowWidth)

где windowWidth — это ширина вашего окна, x варьируется от -2 * PI до 2 * PI, а пропускная способность:

bandwidth = 2 * frequency * n / sampleRate;

Это создает массив чисел, который вы применяете к диапазону сэмплов, сосредоточенных вокруг того, который вы хотите вывести. Вы повторяете это для каждого образца.

Я обобщил свой собственный код для этого, так как исходный код довольно грубый.

person lucius    schedule 22.11.2010
comment
windowWidth - это длина буферного массива? Или это что-то меньшее? В итоге я остановился на фильтре нижних частот Баттерворта, на который ссылается Стивен Фурлани, и, кажется, он работает довольно хорошо, поэтому я попробую ваш, если у меня будет дополнительное время. - person coneybeare; 22.11.2010
comment
windowWidth является переменной от 3 и выше. Верхний предел основан на медленности, которую вы хотите, чтобы код был. Большее окно приводит к более крутой отсечке. Как правило, вам не нужно превышать 63. Кроме того, нечетные значения работают лучше всего. - person lucius; 23.11.2010
comment
отличный ответ. Я забыл большую часть своей обработки сигналов ... и публикую грубый код. :D - person Stephen Furlani; 10.01.2011

Я реализовал фильтр с помощью интерактивного конструктора фильтров.

Вот пример кода со встроенной функцией: https://github.com/davidcairns/MediaPlayerDemo

person David Cairns    schedule 22.04.2011