Hallo Besucher, der Thread wurde 2,2k mal aufgerufen und enthält 4 Antworten

letzter Beitrag von aitsch am

Wie lasse ich Soundeffekte / Musik im Hintergrund abspielen

  • Wie werden Soundeffekte (Explosionen, Schussgeräusch, Bewegungsgeräusche,...) üblicherweise im Hintergrund realisiert?

    Natürlich ohne den Spielfluss zu behindern.


    Ich tippe mal auf eine Interruptroutine, tue mich aber schwer den richtigen Ansatz zu finden.


    Mir geht es dabei nicht darum, was zu tun ist um einen Sound zu erzeugen sondern darum, dass es mit dem Spiel "harmoniert".


    Genaugenommen würde ich mir gerne mal ein ganz einfaches Codebeispiel ansehen um die Mechanik dahinter zu verstehen, finde aber nichts.


    aitsch


    P.S.: Etwas speicherschonendes wäre cool, da ich mein Spiel auf dem VC-20 umsetzte und praktisch keinen freien Speicher mehr habe.

  • Im Prinzip laeuft das so ab: Du hast ja sowieso ueblicherweise 1x pro Bildaufbau irgendwo Deine Interrupt-Routine, die das Spielgeschehen steuert. Diese rufst Du ja immer zum selben Zeitpunkt auf. Und das erste, was Du tun solltest, also noch bevor Du irgendwelche anderen Berechnungen ausfuehrst (die evtl unterschiedlich lang sein koennen), ist es, die Musikabspielroutine aufzurufen, die sich dann drum kuemmert, dass die SID-Register korrekt befuellt werden. Viele Entwickler erstellen ihre Musik und auch Soundeffekt in einem separaten Tool, welches diese Routine dann gleich auch bereitstellt, wenn man das Musikstueck bzw. die Sounds exportiert.


    Bei Shadow Switcher habe ich meine eigene Routine geschrieben, die Musik ist aber auch sehr simpel und es gibt keine Soundeffekte. Hier wird einfach 1x pro Frame geprueft, ob neue Noten abgespielt werden sollen, und wenn ja, werden diese gesetzt. Gaebe es nun noch Soundeffekte, muesste halt auch irgendwo hinterlegt sein, dass eine Aktion im Spiel gerade einen Soundeffekt getriggert hat, und dann wuerde die Musikroutine halt an dieser Stelle statt der Musiknote das Abspielen eines Soundeffekts einleiten.

  • Im Prinzip was ZeHa geschrieben hat. Bei 8192 habe ich nur eine Routine, die pro Frame die Werte für den SID berechnet, die kümmert sich auch um die Soundeffekte. In einer ISR (Interrupt Service Routine), die immer an der gleichen Stelle vom Screen aufgerufen wird, habe ich dann einfach das hier ganz am Anfang (damit das Timing exakt ist):

    Code
    1. jsr snd_out ; schreibt die zuletzt berechneten SID Werte in die Register
    2. jsr snd_step ; berechnet die Werte für das nächste Frame

    Die Effekte selbst sind abgelegt wie "Instrumente", nutzen genau wie die eine Wave- und eine Pulse-Tabelle, außerdem gibt es eine kleine Queue für Effekte (man muss ja überlegen, was passieren soll, wenn ein Sound-Effekt starten müsste, während ein anderer noch abgespielt wird -- Queue ist eine Möglichkeit) und der Player ist so gebaut, dass Soundeffekte immer auf Channel 3 gespielt werden. Deshalb wird im Code, der eigentlich Musik abspielen soll, geprüft, ob gerade ein Soundeffekt aktiv ist, wenn ja wird Channel 3 übersprungen. Im Spiel hört man das gar nicht, weil ich am Ende Musik gebastelt habe, die sowieso nur Channels 1 und 2 nutzt.


    Eventuell interessante Codestellen:

    Aufruf vom Player aus dem Interrupt

    Deklaration der Soundeffekte

    "Normale" Abspielroutine mit überspringen von Channel 3 falls Soundeffekt aktiv

    Abspielen eines Soundeffekts

    Routine um neuen Soundeffekt zu starten (in die Queue legen)

    Beispiel Start eines Soundeffekts aus dem "Hauptprogramm"

  • Danke für eure Antworten.


    ich habe mir eine super-schlanke und ganz simple Soundroutine bebastelt, weil ich nicht so viel Bytes dafür opfern kann.

    Jeder Ton wird in die SID-Adresse $900a - $900d geschrieben und parallel dazu die Tonlänge.

    Im IRQ wird für alle 4 Kanäle der jeweilige Timer runtergezählt und der Ton bei Timer=0 ausgeschschaltet.

    Damit der Ton nicht so öde klingt decrementiere ich ihn parallel zum Timer.

    So kann ich mit wenigen Bytes meine Sounds erzeugen. Das muss (leider) so reichen.


    Meine Routine (im IRQ) sieht so aus:


    Vielleich inspiriert es den einen oder anderen.


    Hier noch ein kleines VC20-Demoprogramm (ziemlich zusammengefrickelt):


    aitsch