Wie wurde sfxr gemacht?

7

Ich denke, dies ist eine Frage zur Spieleentwicklung, da dies ein Tool zur Klangerzeugung ist, das speziell für Spiele entwickelt wurde (insbesondere für Ludum Dare-Spiele).

Ich habe ein grundlegendes Verständnis dafür, wie Schall funktioniert, wobei die sich ändernden Amplituden Druckänderungen verursachen, um Schall zu erzeugen. Was ich mich jedoch frage, ist, wie Sie durch Programmieren Sounds machen und genauer gesagt, wie sfxr das macht. Mein Ansatz wäre es, eine Reihe von Werten zu haben, die jede Amplitude darstellen, und dann einige, wie sie an die Lautsprecher gesendet werden. Aber wie machst du das? Gibt es Bibliotheken, die sfxr verwendet?

Jeff
quelle
2
Sie wissen, dass es Open Source ist, oder? Hier ist ein XNA-Port davon: xnasfxrsynth.codeplex.com
zfedoran
Mir ist aufgefallen, dass er gesagt hat, Sie könnten den Quellcode bekommen, aber wo ist der Code zum Original? Ich warf einen kurzen Blick auf den Link sfxr-sdl-1.1.tar.gz, den er dort hat, konnte aber die Audiobits nicht finden. Ich werde es mir später genauer ansehen, ebenso wie den Link zum XNA (der übrigens WIRKLICH nützlich ist. Ich hatte keine Ahnung, dass Sie so viel Kontrolle über den Sound in XNA bekommen können. Danke!)
Jeff

Antworten:

7

Normalerweise müssen Sie nicht auf einen niedrigen Pegel gehen und die Audiodaten zu den Lautsprechern transportieren. Das Betriebssystem hat dafür eine Schnittstelle (sei es ALSA , DirectSound , CoreAudio usw.). Wenn Sie diese Bibliothek verwenden, müssen Sie ihr nur regelmäßig einen Block mit Samples fester Länge geben (z. B. 512 Samples). Die Soundbibliothek speichert dieses Array in einem internen Puffer und spielt es ab.

Wenn Ihr Block beispielsweise 512 Samples lang ist und die Sampling-Frequenz 44,1 kHz beträgt, bedeutet dies, dass Sie 512/44100 = 11 Millisekunden haben, um den nächsten Block mit 512 Samples zu generieren. Wenn die Aktualisierung länger dauert, wird der alte Block normalerweise erneut abgespielt (der Ton hört nicht auf). Das klingt nach einer kaputten CD, sehr nervig. Das willst du nicht. Ich denke, was sfxr tut, ist die gesamte Welle zu speichern und nur den relevanten Block in den Speicher zu kopieren. Diese Operation benötigt praktisch nichts.

Darüber hinaus gibt es andere Bibliotheken, die eine abstrahierte API bereitstellen und mit der Soundarchitektur des Betriebssystems "sprechen". Auf diese Weise können Sie problemlos Multiplattform-Anwendungen schreiben, ohne Ihren Soundcode an jedes System anpassen zu müssen. Beispiele hierfür sind fmod , OpenAL , SDL , PortAudio und eine lange usw.

Update :

sfxr verwendet PortAudio für seine Windows-Version und SDL für die anderen Plattformen. Wenn Sie sich das Ende von main.cpp ansehen , werden Sie sehen, wie diese Engines initialisiert werden. PortAudio wird ein Zeiger auf eine Funktion namens AudioCallback übergeben , und SDL wird ein Zeiger auf SDLAudioCallback übergeben . Sie können sehen, dass diese Funktionen einen Block mit 512 Samples verarbeiten und in den Ausgabepuffer kopieren. Die Verarbeitung selbst erfolgt in einer ziemlich komplexen Funktion namens SynthSample , die die gewünschten Ausgabe-Samples für einen Block unter Berücksichtigung aller internen Parameter des Synthesizers von sfxr erzeugt.

CeeJay
quelle
Danke, genau das habe ich gesucht! Ich frage mich, warum nicht PortAudio oder SDL für beide verwenden? In den Kommentaren steht "altes Portaudio-Zeug", bevor es für win32 definiert wird. Aber sind SDL und PortAudio nicht beide plattformübergreifend?
Jeff
5

Ich habe angefangen, diese Antwort zu schreiben, und sie wurde immer länger, also wird dies die ausführliche Antwort sein, also nimm daraus, was du willst. Wie CeeJay jedoch sagte, müssen Sie sich normalerweise keine Sorgen um dieses Zeug machen. Besonders dann, wenn Sie eine API wie FMOD, Wwise oder XACT verwenden können, mit der Ihr Sounddesigner alles selbst anschließen kann, sodass Sie nicht "play this.wav" sagen, sondern "das 'PlayExplosionSound'-Ereignis auslösen" Es fällt Ihnen viel leichter, Sound in Ihr Spiel zu integrieren.


SFXR baut einige grundlegende Klangerzeuger auf und bietet die Parameter, die Sie in der GUI sehen. Sowohl XNA als auch ActionScript 3 haben kürzlich eine Möglichkeit bereitgestellt, Samples direkt an die zugrunde liegende Mischmaschine im laufenden Betrieb weiterzuleiten. XNA konnte bereits statische Beispielpuffer definieren (sieht so aus, als würde XNASfxrSynth dies verwenden), aber jetzt können Sie einen haben DynamicSoundEffectInstance -Ereignis ein Ereignis auslösen , bei dem Sie aufgefordert werden, ihm einen Beispielpuffer zuzuführen . Dies reduziert Ihren Speicherbedarf für kontinuierlich erzeugte Audiosignale erheblich. Sie können auch technisch Ihre eigene Mischmaschine schreiben, indem Sie nur eine einzige Master-Sound-Instanz haben, an die alle Ihre Sample-Puffer zum Mischen gesendet werden.

Ein allgemeines Beispiel für die Erstellung eines Sinusgenerators finden Sie in der Dokumentation von Adobe für das neue sampleDataEvent-Ereignis in der Sound-Klasse. Es geht wirklich nur darum zu wissen, wie digitales Audio funktioniert, und die richtigen Sample-Puffer zu erstellen, um den gewünschten Sound zu erhalten. Schauen Sie sich auch die Website von Andre Michelle an , um mehr über die erweiterte Audioverarbeitung in Flash zu erfahren.

Wie CeeJay sagte, haben Audiodaten normalerweise eine zugehörige Abtastfrequenz (normalerweise 44,1 kHz oder 48 kHz - Battlefield Bad Company verwendet 48, um eine Wiedergabe mit hoher Wiedergabetreue zu erzielen, wenn Sie ein gutes 5.1-System angeschlossen haben). Wenn Sie mit digitalem Audio arbeiten, müssen Sie sich um die sogenannte Nyquist-Frequenz kümmern. Grundsätzlich ist die höchste Frequenz, die Sie in einem Audiosignal darstellen können, die Hälfte Ihrer Abtastfrequenz. Der Grund, warum 44,1 kHz und 48 kHz die häufigsten Abtastfrequenzen sind, liegt darin, dass der Bereich des menschlichen Gehörs ungefähr 0 bis 20 kHz beträgt. Somit leisten 44,1 kHz und 48 kHz einen ziemlich guten Job bei der Rekonstruktion eines High-Fidelity-Sounds auf den meisten Verbrauchersystemen.

Es hat auch eine Bittiefe, die typischerweise 16 für die endgültige Mischung beträgt. Dies bedeutet, dass Sie 16 Bit zur Darstellung der Amplitude jedes Samples haben, -32768 bis 32767. Dies entspricht in etwa einem Lautstärkebereich von 96 dB, mit dem Sie arbeiten können. Die Standardintensitätsgrenze für Ton in einem Kino beträgt 85 dB SPL (das SPL-Bit ist eine Möglichkeit, die Lautstärke zu standardisieren, da das Dezibel-System relativ ist), sodass 16 Bit für eine endgültige Mischung auf den meisten Verbrauchersystemen sehr gut funktionieren.

Oft mischt ein Spiel intern mit 32-Bit-Gleitkommawerten und konvertiert dann in 16-Bit, bevor es auf die Soundkarte übertragen wird. Der Grund dafür ist der gleiche Grund, warum Sie in 24 Bit mit einer Abtastfrequenz von 96 kHz aufnehmen. Wenn Sie anfangen, den Sound zu manipulieren, möchten Sie so viel Headroom wie möglich. Digitale Audioeffekte können manchmal coole neue Hochfrequenzsignale einführen, die dann weiter unten in der Signalkette manipuliert werden und sich auf die endgültige Ausgabe auswirken. Diese werden möglicherweise abgeschnitten, wenn Sie auf 16 Bit (48 / 44,1 KB) mischen, aber Sie haben alle Daten auf dem Weg erhalten. Es ist so, als würde man eine Kopie Ihrer hochauflösenden .PSD-Datei behalten, die jedes Mal neu exportiert wird, wenn Sie ein Kunstobjekt ändern müssen. Nur dass dies alles in Echtzeit in der Audio-Engine geschieht.

Wenn Sie mehr über die untere Ebene Konzepte von Audio-Programmierung lesen wollen, empfehle ich Ihnen Blick auf die Audio - Programmierung Buch von Richard Boulanger & Victor Lazzarini. Ich habe mein Exemplar erst vor ein paar Wochen erhalten, und es macht einen großartigen Job, um Sie in die Konzepte der Audioprogrammierung einzuführen (das einleitende C-Kapitel ist allerdings etwas langweilig, da es wichtige Konzepte enthält, die Sie nicht verpassen dürfen, aber Sie auch Erklärungen der Zeigerarithmetik durchstehen müssen).

Ein weiteres gutes Buch ist Who Is Fourier? . Es setzt wenig mathematischen Hintergrund voraus und behandelt die Grundlagen der Fourier-Transformation und der allgemeinen Wellentheorie im Kontext von Sprachforschern, die versuchen, Sprachmuster zu untersuchen. Das Kiddie-Einführungsbuch in japanischer Sprache fühlt sich mit niedlichen handgezeichneten Zeichen an, aber gleichzeitig geht es im zweiten Kapitel um Riemann-Summen.

michael.bartnett
quelle
Ich bin bereits mit der Nyquist-Frequenz und einigen Fourier-Transformations-Verständnissen vertraut. Ich bin mehr daran interessiert, wie Sie tatsächlich ein Beispiel senden, das Sie an die Sprecher gemacht haben. Die Links, die Sie gepostet haben, sehen interessant aus. Ich bin besonders daran interessiert, dieses Audio-Programmierbuch zu bekommen, danke!
Jeff