Como foi feito o sfxr?

7

Eu acho que essa é uma questão de desenvolvimento de jogos, pois é uma ferramenta de geração de som feita especificamente para jogos (em particular, jogos de Ludum Dare).

Eu tenho um entendimento básico de como o som funciona, com as mudanças de amplitude causando mudanças na pressão para produzir som. O que me pergunto é como você produz sons através da programação e, mais especificamente, como o sfxr faz isso. Minha abordagem seria ter uma matriz de valores representando cada amplitude e, em seguida, como enviar para os alto-falantes. Mas como você faz isso? Existem bibliotecas que o sfxr usa?

Jeff
fonte
2
Você sabe que é de código aberto, certo? Aqui está uma porta XNA dele: xnasfxrsynth.codeplex.com
zfedoran
Notei que ele disse que você poderia obter o código fonte, mas onde está o código original? Olhei rapidamente para o link sfxr-sdl-1.1.tar.gz que ele tem lá, mas não consegui encontrar os bits de áudio. Examinarei mais de perto mais tarde, assim como o link para o XNA (que é MUITO útil. Não fazia idéia de que você pudesse ter tanto controle sobre o som no XNA. Obrigado!)
Jeff

Respostas:

7

Bem, você geralmente não precisa diminuir o nível e transportar os dados de áudio para os alto-falantes. O sistema operacional possui uma interface para isso (seja ALSA , DirectSound , CoreAudio , etc). Usando essa biblioteca, você só precisa periodicamente fornecer um bloco de amostras de tamanho fixo (por exemplo, 512 amostras). A biblioteca de sons armazena essa matriz em um buffer interno e a reproduz.

Se o seu bloco tiver, por exemplo, 512 amostras e a frequência de amostragem for 44,1 Khz, isso significa que você tem 512/44100 = 11 milissegundos para gerar o próximo bloco de 512 amostras. Se você demorar mais para atualizar, geralmente o bloco antigo é repetido novamente (o som não para). Isso soa como um CD quebrado, muito irritante. Você não quer isso. Eu acho que o que o sfxr faz é armazenar toda a onda e apenas copiar o pedaço relevante na memória, essa operação não leva praticamente nada.

Além disso, existem outras bibliotecas que fornecem uma API abstraída e "conversam" com a arquitetura de som do sistema operacional. Dessa forma, você pode escrever facilmente aplicativos multiplataforma sem precisar adaptar seu código de som a cada sistema. Exemplos deles são fmod , OpenAL , SDL , PortAudio e muitos outros.

Atualização :

O sfxr usa o PortAudio para sua versão do Windows e o SDL para as outras plataformas. Se você observar o final do main.cpp , verá como esses mecanismos são inicializados. PortAudio é passado o ponteiro para uma função chamada AudioCallback e SDL é passado um ponteiro para SDLAudioCallback . Você pode ver que o que essas funções fazem é processar um bloco de 512 amostras e copiá-lo para o buffer de saída. O processamento em si é feito em uma função bastante complexa chamada SynthSample , que é a que produz as amostras de saída desejadas para um bloco, considerando todos os parâmetros internos do sintetizador do sfxr.

CeeJay
fonte
Obrigado, é exatamente isso que eu estava procurando! Gostaria de saber por que não usar o PortAudio ou SDL para ambos? Nos comentários, diz "material portaudio antigo" antes de defini-lo para o win32. Mas SDL e PortAudio não são multiplataforma?
22411 Jeff
5

Comecei a escrever essa resposta, e ela ficou cada vez mais longa, então essa será a resposta detalhada, portanto, faça o que quiser. Como CeeJay disse, porém, você não precisa se preocupar com esse tipo de coisa normalmente. Especialmente se você puder usar uma API como FMOD, Wwise ou XACT que permita que seu criador de som conecte tudo para que você não esteja dizendo "play this.wav", mas sim "acionar o evento 'PlayExplosionSound'". tenha muito mais facilidade para integrar o som ao seu jogo.


O SFXR trabalha construindo alguns geradores de som fundamentais e oferece os parâmetros que você vê na GUI. O XNA e o ActionScript 3 recentemente forneceram uma maneira de passar amostras diretamente para o mecanismo de mixagem subjacente on-the-fly. O XNA já pode definir buffers de amostra estáticos (parece que o XNASfxrSynth usa isso), mas agora você pode ter um DynamicSoundEffectInstance acionando um evento solicitando que você alimente um buffer de amostra. Isso reduz muito o espaço ocupado pela memória para sinais de áudio gerados continuamente. Tecnicamente, você também pode escrever seu próprio mecanismo de mixagem, apenas ter uma única instância de som principal para a qual todos os seus buffers de amostra são enviados para mixagem.

Um exemplo geral de criação de um gerador de ondas senoidais pode ser encontrado na documentação da Adobe para seu novo evento sampleDataEvent na classe Sound. É realmente apenas saber como o áudio digital funciona e construir os buffers de amostra corretos para obter o som que você deseja. Além disso, consulte o site de Andre Michelle para obter um processamento de áudio avançado mais impressionante no Flash.

Como CeeJay disse, os dados de áudio geralmente têm uma frequência de amostragem associada (geralmente 44,1kHz ou 48kHz - a Battlefield Bad Company usa 48 para obter uma reprodução de alta fidelidade quando você tem um bom sistema 5.1 conectado). Ao trabalhar com áudio digital, você precisa se preocupar com algo chamado frequência Nyquist. Basicamente, a frequência mais alta que você pode representar em um sinal de áudio é metade da sua frequência de amostragem. A razão pela qual 44,1kHz e 48kHz são as frequências de amostragem mais comuns é que o alcance da audição humana é de aproximadamente 0 a 20kHz. Assim, 44,1kHz e 48kHz fazem um bom trabalho na reconstrução de um som de alta fidelidade na maioria dos sistemas de consumo.

Ele também tem um pouco de profundidade, que normalmente é de 16 para a mistura final. Isso significa que você tem 16 bits para representar a amplitude de cada amostra, -32768 a 32767. Isso significa aproximadamente ter um intervalo de volume de 96 dB para trabalhar. O limite de intensidade padrão para o som em um cinema é de 85 dB SPL (o bit SPL é uma maneira de padronizar o volume, uma vez que o sistema de decibéis é relativo), então 16 bits funcionam muito bem para um mix final na maioria dos sistemas de consumo.

Geralmente, um jogo faz mixagem interna usando valores de ponto flutuante de 32 bits e depois converte para 16 bits antes de enviar para a placa de som. A razão para isso é a mesma razão pela qual você gravará em 24 bits com uma frequência de amostragem de 96kHz. Quando você começa a manipular o som, deseja o máximo de espaço possível. Às vezes, os efeitos de áudio digital podem introduzir novos e legais sinais de alta frequência, que são manipulados ainda mais na cadeia de sinal e afetam a saída final. Eles podem ser cortados quando você mistura até 16 bits, 48 ​​/ 44,1k, mas você preservou todos os dados ao longo do caminho. É como manter uma cópia do seu arquivo .PSD de alta resolução que apenas é reexportado toda vez que você precisa alterar um ativo artístico. Exceto que tudo isso está acontecendo em tempo real no mecanismo de áudio.

Se você quiser ler mais sobre os conceitos de nível inferior de programação de áudio, recomendo consultar O livro de programação de áudio de Richard Boulanger e Victor Lazzarini. Acabei de receber minha cópia há algumas semanas, e ele faz um ótimo trabalho em facilitar a compreensão dos conceitos de programação de áudio (o capítulo introdutório do C é meio tedioso, já que existem conceitos importantes que você não pode perder, mas você também tem que passar por explicações sobre a aritmética dos ponteiros).

Outro bom livro é Quem é Fourier? . Ele pressupõe pouco conhecimento matemático e cobre o básico da transformação de Fourier e da teoria geral das ondas no contexto de pesquisadores da linguagem que tentam estudar padrões de fala. O tipo de livro didático introdutório para crianças japonesas parece com personagens fofinhos desenhados à mão, mas ao mesmo tempo fala sobre as somas de Riemann no segundo capítulo.

michael.bartnett
fonte
Eu já tenho uma familiaridade básica com a frequência de Nyquist e alguns entendimentos da transformação de Fourier. Estou mais interessado em como você envia, digamos, uma amostra que você fez para os palestrantes. Os links que você postou parecem interessantes, estou especialmente interessado em obter esse livro de programação de áudio, obrigado!
22411 Jeff