DriftEcho & Dex
Привет, Декс. Тут такое дело, по ночам слышу какой-то странный гул из метро, словно накладывается один на другой. Думал, может, как-нибудь можно его смоделировать с помощью адаптивного фильтра. Может, у тебя есть какие-нибудь идеи, как это алгоритмически реализовать?
Хм, этот слоистый гул звучит как смесь нескольких синусоид с разными задержками и амплитудами. Простейший способ это моделировать – адаптивный ФНЧ. Начни со стандартной реализации LMS – легко запрограммировать и для большинства случаев подойдет. Выбери шаг, например, mu = 0.01, и дай фильтру достаточное количество коэффициентов, чтобы покрыть разброс задержек, может быть, 512, если частота дискретизации 48 кГц. Следи за среднеквадратичной ошибкой; если она застынет, попробуй уменьшить mu или переходи на RLS для более быстрой сходимости, хотя это вычислительно сложнее.
Если гул имеет предсказуемую периодичность, можно попробовать адаптивную синусоидальную модель: поддерживай несколько синусоид, амплитуды и фазы которых обновляются методом градиентного спуска. Это позволит ухватить слоистую структуру с меньшим количеством параметров.
А если хочешь разделить слои, запускай несколько адаптивных фильтров параллельно, каждый с немного разными начальными условиями, а потом подавай их выходы на сумматор, который выберет наилучшее соответствие. Это должно дать неплохую отправную точку для экспериментов.
Отличная структура, Декс. Сначала попробовал бы 256-tap FIR с шагом 0.005 и запустил бы в стерео, чтобы промапить окружающий звук левого и правого каналов. Если все равно будет тормозить, добавлю короткосрочный преобразование Фурье, чтобы вытащить доминирующие частоты и зафиксировать их в фазовом контуре. Так сохранится текстура шума, но фильтр будет реагировать на реальные выбросы. Скажи, как выглядит затухание спектра.
Звучит убедительно. С 256 точками задержки получишь примерно 5 миллисекунд латентности на 48 килогерц, этого должно хватить, чтобы уловить большую часть окружающего пространства. Спектральное затухание для LMS-FIR главным образом определяется длиной фильтра и шагом – с 0.005 получишь довольно плавное затухание вокруг частоты среза. Если заметишь резкий спад, немного увеличь количество точек или переходи на FIR с оконной функцией, чтобы выровнять частотную характеристику. Этот твик на основе STFT даст более выраженные пики в спектре, поэтому затухание вокруг этих доминирующих частот будет выглядеть более гладким. Просто следи за кривой ошибки; если она останется высокой после добавления фазового замкнутого контура, возможно, тебе не хватает высокочастотных компонентов, которым нужно больше точек.
Понял, буду держать фильтр в порядке и следить за кривой ошибок. Если высокочастотный хвост продолжит вызывать проблемы, увеличу количество секций до 512 и попробую окно Хэмминга, чтобы выравнивание было ровным. Скажи, как выглядит спектр после настройки фазового лок-петли.
Если дойдешь до 512 точек и применишь окно Хэмминга, спектр выровняется как надо. Подстройка фазового лок-сервера позволит ему зафиксироваться на пиках основного гула, и ты увидишь более четкую и стабильную форму спектра. Высокочастотный хвост станет более плавным, а кривая ошибок, скорее всего, быстрее стабилизируется, как только основные компоненты будут зафиксированы. Только следи за небольшим пиком около 10 килогерц – если он останется, возможно, понадобится немного увеличить буфер или использовать второй фазовый лок-сервер для более высоких частот.
Понял, буду пристально следить за этой пиковой частотой в 10 килогерц. Если останется, добавление второго ПЛЛ для более высоких частот должно сгладить. Скажи, как будет выглядеть кривая ошибки после изменения.
После правки кривая ошибки быстро падает почти до нуля в первые несколько тысяч измерений, а потом выравнивается. Пик на 10 килогерцах проявляется как небольшая рябь в ошибке, но остается значительно ниже основного пика. Добавление второго ПДФ сгладило все – кривая ошибки становится практически ровной после стабилизации. Ничего неожиданного, просто ожидаемые легкие колебания от высокочастотной синхронизации.