Цифровая обработка звука и звуковые эффекты (часть 1)


Введение

Думаю никто не нуждается в объяснении что такое звук, чем и зачем мы его слышим и что из звуков можно сделать прикольное. Не буду лить воду, скажу только то, что далеко не все что мы слышим звучит в своем лучшем качестве, будь то чья-то речь или любимая композиция, все можно попробовать улучшить или испортить чтобы убедиться что улучшать звук больше некуда или хотя бы для разнообразия или интереса к сфере обработки звука.

Главное что необходимо понимать о звуке это то что он описывает давление воздуха во времени а потому удобно представляется в виде сигнала (функции от времени). Цифровой сигнал хранимый и обрабатываемый компьютерами представляет собой массив или поток из чисел взятых из этого сигнала или формирующих его путем преобразований в которые нет необходимости посвящать читателя. Этот сигнал иногда называют осциллограммой или амплитудной характеристикой и выглядит он вот так:
Когда передо мной возникла задача сделать частотный фильтр все чем я располагал это массив чисел из файла композиции и масса времени на изобретение велосипеда который получился весьма симпатичный. В этой статье я расскажу как сделать фильтр без библиотек при помощи простой арифметики.

Фильтр это устройство или преобразование усиливающее/ослабляющее выборочную область на частотном спектре сигнала. Спектр сигнала простыми словами это график отражающий интенсивность частот из которых состоит сигнал, выглядит он так:
Сложность задачи состоит в том, что от сигнала нельзя просто взять и получить интересующую гармонику с необходимой частотой, изменить ей амплитуду и вставить обратно. Преобразования сигнала в спектр и наоборот очень капризны и трудоемки, мы будем воздействовать на спектр сигнала косвенно при помощи простых операций. 
Простейшее что можно сделать с сигналом - сложить его с самим собой с небольшой задержкой (пару мс). Рассмотрим такое преобразование над сигналом s(t):
Здесь t - обрабатываемый момент времени, dt - величина задержки. Поскольку сигнал представляет собой сумму гармоник, преобразование сложением и умножением будет воздействовать на каждую из них независимо, поэтому рассмотрим его влияние на простой косинус:
Как видно, мы получили исходный косинус умноженный на коэффициент cos(wdt). Этот множитель зависит от циклической частоты гармоники (пропорциональной обычной частоте) и не зависит от прочих ее параметров, однако его зависимость от частоты (синяя) совсем не похожа на необходимую для фильтра (красная):

Если учесть то, что отрицательное усиление равносильно положительному с поворотом по фазе, то ослабление частот происходит вообще всего в двух точках на графике. Проблема решается весьма тривиально - нужно сложить много таких преобразований, вопрос только в том как при этом приблизиться к желаемой прямоугольной картине усиления F(w). Спасибо Фурье за то что я могу не приводить вывод его знаменитого преобразования в этой статье а просто его применить. Мы применим преобразование к вожделенной прямоугольной функции усиления F(w), которая равна 1 для частот меньших θ, а для больших - 0:
Как видно чем больше задержка тем менее она существенна, в идеале надо бесконечно много таких преобразований чтобы получить прямоугольную картину усиления но если не жалко точность можно ограничиться десятком-другим и получится такая картина:

В конечном счете получается такая функция FLT от входного сигнала s(t):
Можно заметить что на выход фильтра в момент времени t влияет входной сигнал в момент t+dt. Когда сигнал не известен целиком а мы располагаем только текущим его значением, нам стоит лишь записывать эти значения в какой-нибудь массив (буфер) и вести в нем расчеты с незначительным отставанием по времени. Заверяю на качестве звука это не сказывается.