Свёртка ACM
Свёртка ACM исполняет секционную реверберацию FMOD на CPU. Пакеты с общим входом преобразуют один сухой сигнал, применяют разделы импульса в float или half-float и складывают с перекрытием влажный результат.
Заметки репозитория по 10 октября 2026 г.
Какую ошибку это закрыло
Subnautica: Below Zero могла начинаться с треска, замолкать и восстанавливаться минуты спустя. PCM, доходивший до устройства хоста, содержал неконечные float. Трасса в памяти обратных вызовов DSP у FMOD показала конечный звук на входе свёрточной реверберации и мусор на выходе. Функции HLE sceAcm_ConvReverb_SharedInput, подача пакета и sceAcmBatchWait возвращали успех, не записывая выход.
Затем FMOD подмешивал этот незаписанный влажный буфер в граф. NaN расходились по более поздним эффектам. Очиститель AudioOut заменял их тишиной и не мог починить отравленную историю фильтра. Вторая ошибка заставляла ожидание начального идентификатора пакета -1 завершаться успехом. FMOD считает неудачное начальное ожидание признаком того, что предыдущего влажного буфера ещё нет, и смешивает только после реально завершённого задания.
Секционная свёртка
Раскладка дескриптора совпадает с той, что наблюдалась в бэкенде ACM у FMOD. Разделы импульсной характеристики — это чередующиеся комплексные бины. Блок из B бинов принадлежит преобразованию длины 2B. Буферы входа, выхода и перекрытия раздельные и планарные. Принимаются только наблюдавшиеся раскладки спектра float32 и float16 с нулевым смещением.
Пакет исполняется на CPU. История входа хранится между гранулами и через перенос кольца, а перекрытие переносится в следующую выходную гранулу. Несколько выходов могут делить одно входное преобразование и один шаг истории. Моновход может питать больше одного канала. Обратное преобразование нормируется. Независимое обратное преобразование раздела реального импульса кладёт его энергию в первую половину блока с дополнением нулями, что подтверждает знак спектра. Упакованный импульс, который использует игра, опускает бин Найквиста.
Ожидания, пределы и повторная проверка
Сборщики захватывают массивы указателей и усиления в ограниченную запись команды. Сам PCM читается, когда пакет начинается. Ожидание успешно только для пакета, который этот контекст действительно завершил. Уничтожение контекста освобождает историю. Недопустимые границы, неизвестные кодировки команд и неподдерживаемые раскладки возвращают ошибки.
Отдельные операции ACM FFT, IFFT и панорамирования не реализованы. Каналы ограничены 8, выходы — 32, блок — 1024. Хранилище истории ограничено. На подписанном runner 90 снимков PCM раз в секунду не содержали неконечных семплов, с пиком 0.1255 и первым звуком выше 0.001 на 11.03 секунды. Сопровождающий подтвердил звук. Снимки — это проба, а не каждый семпл, который издала игра.
Что реализовано
- Секционная свёртка FFT для пакетов реверберации FMOD с общим входом и общей IR.
- Комплексные спектры float32 и float16, сложение с перекрытием и история между гранулами.
- Ожидания, успешные только для завершённого пакета этого контекста. Начальный идентификатор -1 завершается неудачей.
- Конечный PCM на повторной проверке Subnautica: треск и поздняя тишина исчезли.
Чего ещё нет
- Отдельные вызовы ACM FFT, IFFT и панорамирования не реализованы.
- Ненулевые смещения спектра и неизмеренные раскладки маршрутизации отвергаются.
- Свёртка исполняется на CPU. Пути FFT на GPU нет.
Связанные механизмы
Чему посвящены эти страницы