Shop OBEX P1 Docs P2 Docs Learn Events
Defender: Sound — Parallax Forums

Defender: Sound

epmoyerepmoyer Posts: 314
edited 2007-12-06 16:41 in Propeller 1
Greetings everyone!

Steve (a.k.a. CardboardGuru) invited me to work on the sound for Defender and I eagerly jumped on board. I've got a crazy lot of stuff going on, but the opportunity was just too fun to pass up!

I thought that since Steve has been so good about exposing the game writing process in his posts it might be interesting for me to expose the sound creation process as well, so here we go.....

If you look at the Donkey Kong port all the sound there is "musical". With the exception of a few bits of colored noise (like the donkey kong stomp), and some pitch slides (bouncing jackhammers, Kong falling etc.), all the sounds are basically little "songs" in that they are collections of sinusoidal pitches played in order. For that project there were also a lot of actual music, so Nick's sound driver and HDMF were an ideal fit. Things like the jump sound, the hammer sound, etc. were just implemented as rapid HDMF songs, and the few bits of noise were adequately covered by the white noise effect in Nick's driver.

Defender is at the total opposite end of the spectrum. Its sounds consist entirely of effects. There are no songs, the effects are not simple sinusoids, the effect complexities are too high to keep up with using a 60hz "tickle" from the game's main loop, and we have 1 cog to work with. This calls for a dedicated ASM sound effects driver.

Now, the original effects in Defender were implemented using a AY8910 chip. One possibility would be to write an emulator for that chip. The downside is that having done so, I don't know what the setup to the chip was to produce the effects, so I'd then have to go disassemble the Defender ROMs to figure it out. If this were a real commercial project and we had a man month to burn on sound R&D perhaps I'd go down that path but the path has a few pitfalls. #1 I'm not confident I could pull off the AY8910 emulation in a single cog (without a bunch of research), and #2 there would be WHOLE LOT of research and coding before any sound would actually be produced.

Instead I'm going to opt for the second possibility: Brute force analysis of the original sound waveforms and individual code implementations tailored specifically to each one. There are about 15 sounds to emulate, so each will be taken in turn.

A quick inspection of the waveforms shows that they all follow structures which are pretty apparent through graphical observation, so a structural approach to reproduction should be possible. For starters I've begun with the "level done" sound. This is also the first sound that plays during the game's splash screen, and I personally identify it as the main "Identity" sound of the game from my quarter pumping youth, so its a good jumping off point. The sound is also pretty unusual, so reproducing it accurately will be personally encouraging (which will help to keep me going), and will be a fair indication of the probability of reproducing the rest of the sounds accurately.

The first code will be kind of sloppy, because I'm still playing around, and then I'll clean up the implementation before proceeding to the other sounds once I've figured out what it will take.

The "level Done" sound consists of what are basically square waves (although there is a little interesting "ringing" to them). Observation shows two superimposed square waves whose low times become increasingly smaller, played in successive groups whose high times become increasingly smaller. The attached files are the first approximation of this (the menu's don't do anything yet; the demo just plays the "level done" sound in a continuous loop).

Now, if you compare the original sound to my sound on an oscilloscope you'll find that the PWM implementation in the Hydra rolls off the edges of the square waves a bit. I played some square waves through Nick's sound driver and his driver has the same effect. Theoretically it should be possible to compensate for this by over-biasing the PWM duty cycle after an edge transition to force a faster edge rate. For the moment I am going to suppose that the primary reason for the difference in tone between the original and my version is the rolled off edge of my square waves. If I can fix that, then we'll see what we have, and whether I need to simulate the post-edge transition "ringing" of the original.

Post Edited (epmoyer) : 12/6/2007 7:05:43 AM GMT
«1

Comments

  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-11-18 21:26
    I'm over the moon that Eric said yes to my pleading for help on the sound for Defender! A good game requires good sound, and DK would have been a pale shadow of what it is without Eric's sounds. And so would Defender be. I asked him only yesterday if he was interested, and already he's got some code up and running.

    Cheers Eric! And it's great that you're doing a log for us. smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Prop Room Robotics - my web store for Roomba spare parts in the UK

    Post Edited (CardboardGuru) : 11/18/2007 10:03:25 PM GMT
  • epmoyerepmoyer Posts: 314
    edited 2007-11-19 08:17
    I succeeded in significantly increasing the edge rates of the square waves for the "Level Done" sound. It still lacks some of the magic of the original, but its a fair approximation and its in a good enough state to move on. My thinking at this point is to create a good base line version of all the sounds, and then refine them as much as possible.

    The attached demo now has a working menu and contains 3 working sounds: Level Done, Lander Die, and Fire.

    I just had to do the Lander Die sound second because it's one of my favorite effects in the game, and like the "Level Done" sound I wanted to nail it early on so that the flavor of the game was captured from the outset. The arcade sound is actually not too complex when you look at it graphically, but the final sonic effect is very cool. Its basically a sine wave of decreasing frequency, played in 4 successive iterations, with each iteration scaled down in magnitude by 1/4 of full(100%, 75%, 50%, 25%), and with wave clipping at the 50% mark (so the first iteration is 1/2 clipped, the second is 1/4 clipped, and the last two are unclipped). There's also a noise component which gets increasingly louder each iteration, but I have not modeled that. For now the sound would be quite playable as is, and captures the feel of the original very nicely. The noise will come later in the refinement phase as time/memory/patience/horsepower allows [noparse]:)[/noparse]

    The fire sound is not finished yet, and does not implement the edge rate fix so it sounds more timid than it ultimately should and is missing some high frequency spectral components.

    The proper handling of multiple concurrent SFX play requests is not yet implemented. In the actual game very few sounds actually play concurrently. I haven't finished analyzing the original, but I believe only the thrust sound overlaps any other effects, and that the rest are mutually exclusive. It is likely that this engine will have the horsepower to layer effects more than the original did, so for now I'm going to table the sound mixing/exclusivity issue and focus on the effect algorithms first.

    Once I fix up the edge rate on the Fire sound I'll implement Thrust. Those first 4 sounds should be enough to create a decent audio backdrop as the game comes together. Then I'll drop in new sounds as they are completed. Hopefully I can keep up with Steve's implementation of the game mechanics.

    I'm turning in for the night, but I'll add some audio clips next time around. For now you'll have to run the code to hear it.

    Post Edited (epmoyer) : 11/19/2007 8:27:24 AM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-11-19 09:30
    Thanks for that Eric. Integrated and released.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • epmoyerepmoyer Posts: 314
    edited 2007-11-19 23:39
    I have gone to a 4 channel model with a mixer stage. Now you can have up to 4 sounds playing at a time, as long as they are from different channel groups. The channel assignments are fixed, but I will allocate the channels intelligently so that the sounds which we might want to play concurrently appear in different channels.

    I fixed the edge rates on the fire sound (using the same trick as for the level done sound) so it sounds much crisper now.

    I implemented the mechanics behind starting and stopping the thrust sound, but I'm borrowing the algorithm for the fire sound right now which is a square wave and the thrust sound on the actual game is a triangle wave, so there's a little more work to do on it.

    I should be able to release a version with Level Done, Lander Die, Thrust, and Fire some time tonight. Player death (the big explosion) will be next up.
  • epmoyerepmoyer Posts: 314
    edited 2007-11-20 06:59
    Hmmm. I expected the thrust sound to be one of the easiest. The waveform is very simple looking, but the underlying algorithm is eluding me at the moment. I've generated a random signal which you can't tell from the original by looking at the waveform, but they sound very different. Mine sounds like a motor or something instead of like a rocket. Time to sleep on it.
  • epmoyerepmoyer Posts: 314
    edited 2007-11-27 23:30
    The attached version now includes the "Start Game" sound and an early version of the "Thrust" sound.

    I've tweaked this version of the thrust sound to the point where it's playable, buts its going to need a little work before its done.· Its a little rumblier and bassier than the original, but it's passable for now.· The Fire, Lander Die, and Thrust sounds are the most frequently occuring during gameplay, so I wanted to get them in as early as possible.

    The "Start Game" sound was a real challenge.· I stared at the waveform of the original for a very long time before being able to divine what was going on algorithmically.· This version replicates the fundamental behavior of the oringal enough to sound pretty darn good with a relatively small code footprint.·· It lacks some of the "vocal" quality of the orginal, but we'll see how much code space / processor time is available for polishing once all the necessary sounds are in.

    This version of the sound engine now implements a 4 channel mixer.· Sounds are currently·assigned to the 4 channels as follows:
    '  Audio channel usage:
    '     0: Level Done, Start Game
    '     1: Lander Die
    '     2: Fire
    '     3: Thrust
    

    The 4 channels are rendered simultaneously, so at the moment it is possible (for example) to concurrently play Thrust, Fire, Lander Die, and Start Game.· It turns out that in the original game only the "Thrust" sound ever overlaps any other sounds; all other sounds are mututally exclusive.· Since Steve is doing his best to emulate the gameplay of the original as nearly as possible (flukes and all), I'll probably take the same approach with the sounds and drop back to two channels before I'm done.

    I also did a little level balancing in this version, so that the relative volumes of the current sounds are reasonably close to where they should be.·

    The "Fire" and "Thrust" sounds interact a little strangely at the moment (i.e. "Fire" sounds different if played while thrusting).· I may be clipping or something; will chase that down.


    Post Edited (epmoyer) : 11/27/2007 11:37:09 PM GMT
  • epmoyerepmoyer Posts: 314
    edited 2007-11-28 00:54
    Added "You Die" sound.· Long and rumbly.· Used square wave instead of the original's odd triangle functions for the lingering rumble, which lacks some of the heavy feeling but decreases the code footprint.· Again; will polish as space allows once I've managed to shoe horn all the basic sounds into place.

    The start of this sound uses basically a similar algorithm to the fire sound (a square wave of randomly chosen high/low times which are multiples of an increasingly expanding "chunk" size).· The explosion uses a state timer to transition between 3 phases.· The first transition resets the chunk size to cause the secondary explosion (per the explosion sound in the original game), and the second transition introduces a random "rumble" to the pulse width while introducing a volume decay.

    I've been listening to the thrust sound on headphones and it sounds less rocketlike than it did through my speakers.· Definitely need some tweaking there.

    Post Edited (epmoyer) : 11/28/2007 1:44:29 AM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-11-28 03:18
    Good stuff! YOU DIE sounds pretty authentic.

    On my TV the THRUST sounds a bit like heavy machinery in the next room. A low rumble rather than a hiss. I've just loaded Mame up and I noticed something I hadn;t realised before. When you start a level, there is silence (appart from the odd Lander shot). But after the first time you thrust, from then on there is a low rumble in the background. I think THRUST sounds a bit like that rumble. Maybe there's just one parameter difference between the sound of thrust and the background rumble?

    BTW, I've rediscovered today that Mame can be configured with cheats, and one makes your ship invincible. Makes exploration a lot easier not having to fight your way all the time.

    I'll try to get some sort of Defender release out today with the new sounds.

    Cheers!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • epmoyerepmoyer Posts: 314
    edited 2007-11-28 03:52
    Verion 6 attached.· Added "Warp", "Mutant" and "Lander Fire".

    It turns out that the algorithm for Warp is the same as Fire, but backwards and with some modified parameter settings.

    Mutant and Lander Fire were interesting to implement, because they both have some oddly patterned repeating square waves.· I decided to implement them both using samples stored in a couple long words.· Mutant is a 4 level square wave, so it uses 2 bit sampling, and Lander Fire is a 2 level square wave so it uses 1 bit sampling.

    CardboardGuru:
    ···· Yeah, I noticed the same thing about the thrust sound.· Its funny how you don't notice the background rumble until you are thinking about sound design!· The rumble persists from the first time you hit thrust to the time you die.·· I wonder if it was a "bug" they liked and decided to keep?· I'll implement the background rumble too.
    ···· I agree that the current Thrust sound stinks.· I've been wearing headphones for the last couple hours and it sounds just terrible in them.·· I've come·to·loathe it. ·It's funny, because I can make the waveform on my oscilloscope look identical to the .wav file plot (to my eye), but something subtle is still missing.· Will go off and focus on thrust again now.· I continue to be amazed that this is the one tripping me up!
  • epmoyerepmoyer Posts: 314
    edited 2007-11-28 04:11
    I suspect that my issues with the Thrust sound may stem from the periodicity of my pseudo-random number generator. I hacked it together and it's not particlarly random. Anyone have any source code for good Pseudo random algorithm either in Prop ASM, or which I can readily port? I'll start hunting for one...
  • epmoyerepmoyer Posts: 314
    edited 2007-11-28 04:57
    Seems that the best weay to get a random number generator is to roll my own 32 bit LFSR in assembly. Can't find one in propeller assembly allready out there, but it doesn't seem too hard. Will give it a go...
  • epmoyerepmoyer Posts: 314
    edited 2007-11-28 06:05
    Got an LFSR random number generator written. Appears to work in PASD but I have some kind of bug inegrating it into my defender sound engine. I'll sleep on it and try again tomorrow.

    I'm starting to bang into the 512 word limit with the sound engine now with 9 out of about 15 sounds coded. To be sure my code is not optimized and there is some room for squeezing, but I'm guessing I'll end up hitting 11 or 12 sounds by the time I'm done, so I'll probably have to pick and choose which ones make the cut.
  • epmoyerepmoyer Posts: 314
    edited 2007-11-28 17:22
    Wooohoooo!!!!!

    I got the LFSR pseudo-random generator working and what do you know?· It WAS the distribution of my random number generator which was causing the thrust to sound like machinery instead of rockets!

    The version posted here is the very first that has a working LFSR implementation so I haven't done any tweaks to the thrust sound yet, but allready it sounds 20 times better than the previous version so I thought I'd post it in case Steve wants to throw it into the game demo before I get back to tweaking.

    It took me a while to figure out what LFSR's (Linear Feedback Shrft Registers) were all about, and how to implement one in Propeller assembly.· Its the same type of random generator built into spin (accessible via the "?" operator), but I had a hard time finding code examples on the web.· It's really not rocket science (except, in my case I'm using it for the Thrust sound, so I guess it is [noparse];)[/noparse] but it's probably worth me writing a quick LFSR thread in the Prop forum and posting my code once I clean it up a little.· I can't be the only one who wants pseudo-randoms in Prop assembly.

    I had to temprarily drop the "Lander Fire" sound to conserve code space while working on the Thrust, so you'll find that even though "Lander Fire" appears on the menu of version 7 it doesn't do anything.··I'll optimize my code a bit and turn it back on in the next pass.

    Enjoy!
  • epmoyerepmoyer Posts: 314
    edited 2007-11-28 17:27
    BTW I also discovered while working on the LFSR code that random noise sounds just about as rocket-like as the more structured triangle waves of the current rocket sound (which are modelled after the structure of the waveforms output by the original game). When it comes down to compressing code and optimizing space I may find that using a random noise implementation of the Thrust sound is worth the code savings.
  • epmoyerepmoyer Posts: 314
    edited 2007-11-29 07:11
    Cardboard Guru,
    ·
    I've attached a spreadsheet listing the currently implemented sounds, and the ones remaining.·· The numbers in the LWORD column are the approximate implementation sizes of each of the effects (not including·setup and registers, which are more or less the same size for each effect).· The currently implemented set occupies a full cog, so its time to make some decisions.
    ·
    I listed the remaining unimplemented sounds in priority order from most important to least except the red ones, which are not necessarily highest priority but I believe I can probably combine all the effects colored in red into the same handler since they all have very similar algorithms (and in the real game they do not play simultaneously anyway).· With a little work it may also be possible to include the warp sound in that handler as well, since it's essentially the same algorithm only in reverse.· If I can pull that off, and shrink the thrust code as I suspect I can, then I can probably fit another sound or two in.· HUMAN_ABDUCTED should fit, and is probably the most essential of the remaining sounds.· I might be able to get HUMAN_FALLING as well, since a simple pitch slide will probably suffice and shouldn't take much code.
    ·
    If I pull all that off (which will require some significant belt tightening) we're still left with 5 or 6 unimplemented sounds, plus any still missing from my list.
    ·
    First of all, I've kind of been assuming that since I have one cog I have ~512 LWORDS of code space to work with, but I haven't actually paid any attention to the current size or your code, or asked you where you think you'll end up.· My current code image is 438 longs.· Is that reasonable?
    ·
    If it turns out that you think you’ll have even MORE than 512 words available for sound then I could move all the “out-of-game” sounds (LEVEL_DONE, START_GAME, YOU_DIE, HIGHSCORE) into a second module and we would have two different sound engines; one for in-game sounds and one for out-of-game sounds.· We could then re-load the cog with the appropriate sound engine whenever the game transitions between in-game and out-of-game.
    ·
    Let me know your thoughts.· In the meantime I’ll work on combining the explosion effects (the ones in red, plus potentially WARP) to conserve space.
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-11-29 08:41
    Hi Eric,

    Thanks for the splendid work. Thrust really does sound much better.

    I've picked up your release 007 and done a release of defender with the mutant sound added. It occurred to me as I did so that there's a change needed in your driver for cross platform compatibility as mentioned by OBC. Perhaps you could add a 3rd parameter to the initialization block for me to set? You may like to know that the sound effects work without any pin changes on the Hybrid, but they are just a bit higher and faster because it's working at 96MHz rather than 80MHz.

    I don't think hub memory is an issue. We're way past 50% implemented and we've not used up half the memory yet. So your second driver for out of game effects sounds like a good idea.

    I'll have to play some MAME and have a think about the priorities. I'd say the HUMAN_ABDUCTED one is absolutely essential, even more so than some of the ones you've already done as it forms part of the gameplay. It's an alert to the user of something happening off screen that they need to deal with.

    Here's another idea - you'll have to judge how feasible it is... The AY8910 has 3 channels. So three possible sound effects can play at once. How about having 3 blocks of cog memory allocated one for each channel. When a new sound is requested on a channel, you load the appropriate block of code for that sound effect from HUB memory, into the appropriate space for that channel, then start playing it. Does that make sense?

    Say the blocks were at $100, $120, $140

    In your code, you'd use the same ORG $100 for each sound that's destined for channel 1. ORG $120 for each sound for channel 2 etc. And you'd fill out the shorter sounds with NOPs such that each block is a standard length ($20 in this example)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Prop Room Robotics - my web store for Roomba spare parts in the UK

    Post Edited (CardboardGuru) : 11/29/2007 8:51:36 AM GMT
  • epmoyerepmoyer Posts: 314
    edited 2007-11-29 16:59
    CardboardGuru said...
    you could add a 3rd parameter to the initialization block for me to set?


    Will do!
    CardboardGuru said...
    I'd say the HUMAN_ABDUCTED one is absolutely essential, even more so than some of the ones you've already done ...
    Oh I absolutely agree.· I was only attempting to prioritize the remaining unimplemented sounds, by way of figuring out what to attack next.· Given that we've got a good amount of memory available I think we'll manage to get pretty good coverage by the time we're through.· I think I'll head down the 2 image path for now since it's more straightforward and easier to test at the expense of a little extra space and cog load time.· If I manage to cover all the effects that way then great, and if not we'll look at a more complex block swapping solution like you suggested.

    I've been playing·a lot of the original lately and one thing that struck me last night is that I've been in this mindset of "the original played only one effect at a time because of limited resources, and we could play more simultaneoiusly, but we won't because we're cloning, so we're intentionally dumbing it down a little".· But what I realized is that the fact that all other sounds stop when a lander explodes really makes the explosion more powerful.· It has such a contrasting sound to all the others, so weird and alien, and you get this feeling that the shock waves have silenced the world around it.··I just love it! ·I'll add the exclusivity into the next release so that silencing effect comes through as intended.
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-11-29 18:01
    Hi Eric,

    Yes, I get the same thing with the graphics. I COULD do some parts of the graphics better than the original. But then it'd lose the right feel.

    I've looked at the list of sounds, and the order you've listed them looks about right. It doesn't really matter to me what order you do them in as you are already ahead of me in terms of implementing features. And I have this feeling you'll find a way to do them all! smile.gif

    I'm going to continue to try and get this kb/tv driver working, then I'll probably do swarmers, humanoid catching, then enemy bullets.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • epmoyerepmoyer Posts: 314
    edited 2007-11-30 07:08
    I made lots of progress on shrinking the sound code.· Version 009 of the demo is attached.

    -· Combined all the "Explosion" sounds (HumanDie, Fire, Warp, YouDie, PlanetExplode) into a common parameterized handler.
    -··Added HumanDie and PlanetExplode.
    -· Shrunk the thrust code significantly by going to a random noise model (the output wavefore is now essentially just random noise stretched in time a little so each radom value is a few samples wide.· The old implementation used the random generator to control the height of (and separation between) peaks of a triangle wave.·· It matched the original, but took a lot more code and sounded almost the same as the new algorithm.
    -· Shrunk the infrastructure code (inits, mixing, and sound list processing)
    -· Instituted a heirarchy of sound priority.· Lander Die now overrides the sounds with lower priority (like Fire), to emulate the original.
    -· Went to a 2 channel sound model.· Thrust is on channel 0, all others are on channel 1.

    With the above changes the code dropped from 450 to 380 Longs, and the number of registers dropped by about 15 or 20, so I've gained back something like 85 to 90 words while adding two new sounds.· I could probably implement the next 2 to 4 of the 6 remaining sounds without going to a 2 image model.· In any case I'm pretty confident that with a 2 image model I'll be able to cover all the sounds.

    I haven't added the cross platform compatibility changes yet, and I haven't done the bakground thrust sound.· Those are next on deck.

    The driver in the attached zip (EPM_Defender_Sound_Engine_025.spin) can be dropped directly into Steve's latest release (sw_defender_009) if you want to hear the new sound prioritization & exclusivity in action.· I think LanderDie sounds much better now that it trumps all the other sounds.

    One of the cool things I did was to re-seed the random number generator each time an explosion sound starts, using the same seed every time.· All the explosion sounds contain radom elements, but PlanetExplode in particular has this huge perceivable granularity determining when all the secondary explosions go off.· Rather than create some code heavy model for the firing of the secondary explosions I just made them "random" and then tried a bunch of different seed values until I found a particlar "random" sequence that sounded good.·· Since I use the same seed every time, I'll always get the same explosion sequence I chose with very little code overhead.

    Post Edited (epmoyer) : 11/30/2007 7:23:19 AM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-11-30 11:40
    I knew you'd come up with something! smile.gif

    Great release. I particularly like LANDER FIRE.

    I hope I'll be able to graphically do justice to PLANET EXPLODE!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • epmoyerepmoyer Posts: 314
    edited 2007-12-02 02:02
    Finished "Human Abducted". Man oh man that was a CRAY hard sound to do! Its arguably the most important sound in the game, in that its really the only sound that has a bearing on game play (all other sounds are kind of "ear candy" that reinforce what's gong on visually, but the "Human Abducted" sound tells you that something is going on in the world, quite possibly off screen). Its the one sound you have to listen for, because the corresponding visual cue (aliens carrying humans away on the scanner) is very difficult to detect and process mentally.

    The sound is just insane algorithmically. Very odd waveforms which are hard to decompose into their component pieces. The whole structure of it reeks of something that was arrived at by poking and prodding the sound chip until the resulting odd behavior sounded "cool". The real thing no doubt relies on all kinds of chaotic overflows and wrap arounds. In the end I broke the base sound down into two separate components; a complex sinusoidal component, and a sharp pulse train. I modelled the sinudoid with a two stage FM synthesis to get it sounding similar to the original (the first FM synthesis in this driver)

    After that, I went through the original and determined the relative amounts of the two component sounds for each of the 15 segments (the original sound is composed of 15 distinct segments, which short gaps of silence between them). Then I built a 2 bit volume sample envelope for each segment of each of the two sounds.

    Oh, and on top of all that the base sounds also have a frequency swell where during each segment they swell and then dip back to normal in frequency. Whew!

    Time to go make dinner. I have to d a little code polishing before I post. This sound ran me just barely over on space, so perhaps its time for me to split into two modules now.
  • epmoyerepmoyer Posts: 314
    edited 2007-12-02 08:04
    Sound Demo Version 011 (Bring on the Humans!)

    Here is demo version 011 with lots of new changes:

    - Split the sound engine into two modules, one for in-game sounds and one for out-of-game sounds.· Only one gets loaded in the sound cog at a time. Load/unload are managed by the calling app.
    - Added HUMAN_ABDUCTED, HUMAN_FALLING, and HUMAN_CAUGHT
    - Added support for the Hybrid
    - Adopted a new menu system which will support more items than can fit on one screen
    - The sfx_stop_flags field can now be used to stop any sound in progress (used to only work with thrust).· I added it specifically to support stopping the HUMAN_FALLING sound when the human is caught (or dies), but it may be useful in other cases I didn't think of.

    Note: For the moment the copyright on the menu system in the demo app excludes it's use in other software; its part of the work I've been doing for my guitar pedal project and for the moment I want to maintain control of it.

    The new demo works a lot like the old one with the following three differences:
    - There are more sounds than visible on screen at one time.· Scroll up or down to get to them.
    -·The demo starts with·Engine 1 loaded.· Press the "B" button to switch back and forth between engine 1 and engine 2.· Each sound is listed identifying the engine in which it resides.· If you try to play an engine 2 sound while engine 1 is loaded nothing will happen (and vice versa).
    - Hybrid users can change the line "sfx_hardware_type := sfx1#HARDWARE_HYDRA" to "sfx_hardware_type := sfx1#HARDWARE_HYBRID"·for Hybrid support.

    Steve,
    · For the added Hybrid support you need to add one additional word to the sfx config block like so:

      'Sound control block
      long sfx_start_flags             
      long sfx_stop_flags
      long sfx_hardware_type           ' Defines the hardware platform type (Hydra, Hydbrid)
    

    ·There are two separate engines (and the name has changed a little), so you need to declare the modules like so:

      sfx1      : "EPM_Defender_Sound_Engine1_027.spin" ' Defender Sound Driver
      sfx2      : "EPM_Defender_Sound_Engine2_001.spin" ' Defender Sound Driver 
    


    There is now an init call which helps the cog managment protect iteself from bad start/stop calls, so you must call init before calling start:

      'Start the sound effects engine
      sfx_start_flags := 0
      sfx_stop_flags := 0
      sfx_hardware_type := sfx1#HARDWARE_HYDRA
      sfx1.init
      sfx2.init
      sfx1.start(@sfx_start_flags)
    


    Once the engine is started you can switch engines by doing a stop on the old one and a start on the new one like so:

      sfx1.stop
      sfx2.start(@sfx_start_flags)
    

    The sound names are declared in both modules. I suppose I could have written "sfx_start_flags |= sfx2#SOUND__START_GAME", but I used "sfx1#..." everywhere even though some sounds are in engine 2.


    It turns out that the sound which plays when a human is saved (i.e. comes to rest safely on the ground) is the same as the "level done" sound, which is kind of annoying because that's one of the larger sounds I moved to engine 2 to save space for "in-game" sounds in engine 1.· Not sure what I'm going to do about that in the end.· For now I'm keeping it in engine 2 and I'm going to see if I can fit the remaining 2 in-game sounds into engine 1 (SWARMER and EXTRA_LIFE).
  • epmoyerepmoyer Posts: 314
    edited 2007-12-02 08:10
    By the way, when I went from my old "bad" pseudo random number generator to the new LFSR version it worked great for thrust and explosions, but the laser fire lost the pitchy twaing it used to have on the front end. Once I enter the tweaking phase I'm going to bring the laser twang back; it's just too hissy right now (especially in the heat of a game with all kinds of things going on).
  • epmoyerepmoyer Posts: 314
    edited 2007-12-02 22:04
    Hadn't realized that the pod has its own sound in addition to the swarmers. Finished the POD sound and am currently using every single word of my cog for in-game sounds. Not sure how I'm going to get the swarmer in yet. May be able to economize on the individual sound starting code overhead somehow.
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-05 07:57
    Hi Eric,

    Tested the sounds on the Hybrid. They sound just the same as the Hydra now!

    The two engine approach works perfectly. I think I got all the sounds you've released so far in.

    It does seem the way of the Propeller that whenever you do something really interesting you hit your head on the 496 long cog limit.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • epmoyerepmoyer Posts: 314
    edited 2007-12-05 08:20
    Glad to hear the Hybrid code worked! I tested it on the Hydra and I got lower pitched sounds, so I figured it was probably right.

    More sounds coming tomorrow evening. I have the Pod and the Swarmer both in now but I still need to clean up engine 2 to match the changes I've made to engine 1.

    I did a big overhaul on the way sounds are started, moving from a bitmask system to a command system. The new interface has two command words in the control block; one to command the thrust and one to command the sound effects. The new system reduced a lot of overhead and gave me the room to fit the swarmer sound in with some space left over. The next overhaul will be to collapse all the sound parameter words into a block of 6 or seven general purpose registers instead of the current 10 or 12 blocks of 3 to 6 registers each, which will free up space for more sounds in engine 1. That's about the last thing left to crunch, but it might get me the space for EXTRA_LIFE and HUMAN_RETURNED in engine 1.

    I've also implemented the high and low level thrust sounds, and have created an infrastructure which lets me tag any sound effect as "uninterruptible". If a sound is uninterruptible then it will play until completion even if new sound commands are issued (the new commands will be ignored). The reason PLANET_EXPLODE was disappearing before is that it was getting overwritten by other sounds. Now PLANET_EXPLODE, LANDER_DIE, YOU_DIE and HUMAN_ABDUCTED are all uninterruptible. Here is the new scheme:

      IS_UNINTERRUPTIBLE     = %1_0000_0000
      IS_EXPLOSION           = %0_1000_0000
    
      'Thrust Commands
      CMD__THRUST_OFF        = 0
      CMD__THRUST_HIGH       = 1
      CMD__THRUST_LOW        = 2
    
      'Sound Effect Commands (Engine 1)
      CMD__IDLE              = 3                                         
      CMD__HUMAN_DIE         = 4  | IS_EXPLOSION
      CMD__FIRE              = 5  | IS_EXPLOSION 
      CMD__WARP              = 6  | IS_EXPLOSION
      CMD__YOU_DIE           = 7  | IS_EXPLOSION | IS_UNINTERRUPTIBLE 
      CMD__PLANET_EXPLODE    = 8  | IS_EXPLOSION | IS_UNINTERRUPTIBLE
      CMD__MUTANT            = 9  
      CMD__LANDER_FIRE       = 10 
      CMD__LANDER_DIE        = 11 | IS_UNINTERRUPTIBLE
      CMD__HUMAN_ABDUCTED    = 12 | IS_UNINTERRUPTIBLE   
      CMD__HUMAN_FALLING     = 13 
      CMD__HUMAN_CAUGHT      = 14 
      CMD__POD               = 15 
      CMD__SWARMER           = 16
      CMD__HUMAN_RETURNED    = 17  
      CMD__EXTRA_LIFE        = 18 
    
      'Sound Effect Commands (Engine 2)   
      CMD__LEVEL_DONE        = 19 | IS_EXPLOSION
      CMD__START_GAME        = 20 | IS_EXPLOSION
      CMD__HIGHSCORE         = 21 | IS_EXPLOSION
    
      CMD__QUIET             = $7f
    
    



    At any time issuing CMD__QUIET will stop all sound (including uninterruptible sounds). The engine detects state changes in the command register, so on any game loop pass where you have not generated a new sound request you set the command register to CMD__IDLE, and any currently playing sound will continue until completion.

    HUMAN_RETURNED, EXTRA_LIFE, and HIGHSCORE are the only unimplemented sounds remaining, although I did notice the other day that when I shot some enemy (a bomber I think) it seemed like it had a different death sound than any of the existing sounds, so perhaps there is one more out there. I will have to investigate.

    Post Edited (epmoyer) : 12/5/2007 8:25:39 AM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-05 08:43
    Blimey, you have been busy! The API sounds even more straightforward for me to call as well.

    Before you spend time on HIGHSCORE, let me give some thought to whether I'm going to support high scores. Because there are no tiles and a limited number of sprites, text is hard to do. So I need to think about whether I'm going to support hi scores, and if so how. I presume by HIGHSCORE you mean the deathly tones in the screen where you can enter your initials, right? Or is there an in-game sound when you pass the high score?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK
  • epmoyerepmoyer Posts: 314
    edited 2007-12-06 01:45
    Did the register collapse and got a bunch of space back. EXTRA_LIFE is half way done, and the first part of the sound is 100% authentic. I'm kind of amazed how well it turned out! Working on the second half now; should have a new post tonight.
  • epmoyerepmoyer Posts: 314
    edited 2007-12-06 06:45
    Pod People

    Release 013 of the demo app is attached.· The new version contains the following changes:

    -· Switched from a bitmap based invocation scheme to a cmd based scheme.·
    -· Consolidated sound parameter registers to crunch space
    -· Added POD, SWARMER, and EXTRA_LIFE sounds
    -· Added two flavors of thust; THRUST_HIGH and THRUST_LOW.· THRUST_LOW is the background sound the arcade version makes when your ship is idling.

    The new control block looks like:
      'Sound control block
      long sfx_command                 ' Sound effects command
      long thrust_command              ' Thrust command
      long sfx_hardware_type           ' Defines the hardware platform type (Hydra, Hydbrid)
    

    To set the thrust sound put one of the following into thrust_command:

      'Thrust Commands
      CMD__THRUST_OFF        = 0
      CMD__THRUST_HIGH       = 1
      CMD__THRUST_LOW        = 2
    


    To play a sound put one of the following into sfx_comand:
      'Sound Effect Commands (Engine 1)
      CMD__IDLE              = 3                                         
      CMD__HUMAN_DIE         = 4  | IS_EXPLOSION
      CMD__FIRE              = 5  | IS_EXPLOSION 
      CMD__WARP              = 6  | IS_EXPLOSION
      CMD__YOU_DIE           = 7  | IS_EXPLOSION | IS_UNINTERRUPTIBLE 
      CMD__PLANET_EXPLODE    = 8  | IS_EXPLOSION | IS_UNINTERRUPTIBLE
      CMD__MUTANT            = 9  
      CMD__LANDER_FIRE       = 10 
      CMD__LANDER_DIE        = 11 | IS_UNINTERRUPTIBLE
      CMD__HUMAN_ABDUCTED    = 12 | IS_UNINTERRUPTIBLE   
      CMD__HUMAN_FALLING     = 13 
      CMD__HUMAN_CAUGHT      = 14 
      CMD__POD               = 15 
      CMD__SWARMER           = 16
      CMD__HUMAN_RETURNED    = 17  
      CMD__EXTRA_LIFE        = 18
      CMD__EXTRA_LIFE2       = 19   'NOTE: This is the 2nd part of the 'Extra Life' sound, and should not
                                    '      be called by the game engine.  EXTRA_LIFE will be followed by
                                    '      EXTRA_LIFE2 automatically.
      'Sound Effect Commands (Engine 2)   
      CMD__LEVEL_DONE        = 20
      CMD__START_GAME        = 21
      CMD__HIGHSCORE         = 22
      CMD__QUIET             = $7f
    

    ·The intended implmentation is that you create a temporary variable called next_snd_command, set it to CMD__IDLE at the top of your code loop, set it to the appropriate sound command in any event code which generates a sound, and set the control block variable sfx_command to next_snd_command at the bottom of your code loop.

    CMD_HIGHSCORE is defined, but the sound is not implemented.

    My next·task is to playtest the sounds in the next Defender release, balance the volume levels, and polish them for a good mix.· I'll also fix the FIRE sound to get back the original twang on the front end and make it a little less hissy.·

    Engine 1 has only 3 longs to spare, so·it's full now.· The only sounds missing (that I know of) are:
    ··· Bomber Die
    ··· High Score
    ··· Human Returned (which is the same as LEVEL DONE in Engine 2, but since it's in Engine 2 it can't be played in-game)

    I just noticed a bug in START_GAME where it will cycle forever the 2nd time you play it.· I'll try to track it down and update this post shortly.· No doubt induced by the change of control schemes (which affected the sound start initialization code a bit).

    UPDATE:· Ah, found it.· Just as·I suspected; botched the start initialization in the conversion.· Rev 014 is attached and fixes the problem.

    Post Edited (epmoyer) : 12/6/2007 6:59:28 AM GMT
  • CardboardGuruCardboardGuru Posts: 443
    edited 2007-12-06 10:53
    I've just played through all the sounds individually and they do all sound great. I'll try to get all the new sounds + PLAYER_DIE in a release today so you have the latest to do your play test.
    epmoyer said...
    The intended implmentation is that you create a temporary variable called next_snd_command, set it to CMD__IDLE at the top of your code loop, set it to the appropriate sound command in any event code which generates a sound, and set the control block variable sfx_command to next_snd_command at the bottom of your code loop.

    What if there is more than one sound event in a playloop? I guess the answer is that thrust is separate and apart from that, only one sound can play anyway, so it doesn't matter. However other sound commands should take precedence in my code to CMD_QUIET. (If indeed I ever need to call CMD_QUIET during game play I can't think off hand if I do. Anyway, I'll just give it a try and see what happens.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Help to build the Propeller wiki - propeller.wikispaces.com
    Play Defender - Propeller version of the classic game
    Prop Room Robotics - my web store for Roomba spare parts in the UK
Sign In or Register to comment.