Ir para o conteúdo
PS5PCEM
ParcialÁudio e vídeo

Convolução ACM

A convolução ACM executa na CPU a reverberação particionada do FMOD. Lotes de entrada compartilhada transformam um sinal seco, aplicam partições de impulso em float ou em meia precisão e fazem overlap-add do resultado úmido.

Notas do repositório até 10 de outubro de 2026

O erro que ela fechou

Subnautica: Below Zero podia começar com estalos, cair em silêncio e se recuperar minutos depois. O PCM que chegava ao dispositivo do anfitrião continha floats não finitos. Um rastreio em memória dos callbacks de DSP do FMOD mostrou áudio finito entrando na reverberação por convolução e lixo saindo dela. As funções HLE sceAcm_ConvReverb_SharedInput, o envio do lote e sceAcmBatchWait devolviam sucesso sem escrever uma saída.

O FMOD então misturava esse buffer úmido não escrito no grafo. Os NaNs se espalhavam pelos efeitos posteriores. O saneador do AudioOut os substituía por silêncio e não conseguia reparar o histórico envenenado do filtro. Um segundo erro fazia a espera no identificador inicial de lote -1 ter sucesso. O FMOD trata uma espera inicial que falhou como 'ainda não há buffer úmido anterior' e só mistura depois de um trabalho de fato concluído.

Convolução particionada

O layout do descritor corresponde ao observado no backend ACM do FMOD. As partições da resposta ao impulso são bins complexos intercalados. Um bloco de B bins pertence a uma transformada de comprimento 2B. Os buffers de entrada, de saída e de sobreposição são separados e planares. Só são aceitos os layouts de espectro float32 e float16 de deslocamento zero que foram observados.

Um lote roda na CPU. O histórico de entrada é mantido entre grãos e através da volta do anel, e a sobreposição é carregada para o grão de saída seguinte. Várias saídas podem compartilhar uma transformada de entrada e um avanço de histórico. A entrada mono pode alimentar mais de um canal. A transformada inversa é normalizada. Uma inversa independente de uma partição de impulso real colocou a energia na primeira metade do bloco preenchido com zeros, o que confirma o sinal do espectro. O impulso empacotado que o jogo usa omite o bin de Nyquist.

Esperas, limites e o reteste

Os construtores capturam arrays de ponteiros e ganhos num registro de comando limitado. O próprio PCM é lido quando o lote começa. Uma espera só tem sucesso para um lote que este contexto de fato concluiu. Destruir o contexto libera o histórico. Limites inválidos, codificações de comando desconhecidas e layouts sem suporte devolvem erros.

Operações isoladas de FFT, de IFFT e de panner do ACM não estão implementadas. Os canais têm teto de 8, as saídas de 32 e o bloco de 1024. O armazenamento do histórico é limitado. No runner da compilação assinada, 90 instantâneos de PCM, um por segundo, não continham amostras não finitas, com pico de 0.1255 e o primeiro áudio acima de 0.001 aos 11.03 segundos. O mantenedor confirmou o som. As amostras são uma sonda, não toda amostra que o jogo emitiu.

O que está implementado

  • Convolução FFT particionada para os lotes de reverberação de entrada compartilhada e de IR compartilhada do FMOD.
  • Espectros complexos em float32 e float16, overlap-add e histórico entre grãos.
  • Esperas que só têm sucesso para um lote concluído daquele contexto. O identificador inicial -1 falha.
  • PCM finito no reteste de Subnautica, com os estalos e o silêncio posterior já ausentes.

O que ainda falta

  • Chamadas isoladas de FFT, de IFFT e de panner do ACM não estão implementadas.
  • Deslocamentos de espectro diferentes de zero e layouts de roteamento não medidos são rejeitados.
  • A convolução roda na CPU. Não há caminho de FFT na GPU.

Mecanismos relacionados

O que estas páginas descrevem

O texto segue as notas de arquitetura e os relatórios de outubro de 2026 no repositório do PS5PCEM. Um teste pontual que passa não é uma nova taxa de quadros nem uma nova conclusão de jogo.

Todas as tecnologias