Audaspace is a standalone Python module, much like the mathutils library. While it's not a game engine specific library, it works with the BGE just fine, and is very versatile and useful. Some nice features are dynamic filtering, synth waveform playing (e.g. dynamically playing a square or sine wave), and fading sounds in and out.
The idea behind Audaspace is pretty simple. We have a device that we use to play sounds, which is like our sound card, and we have sounds. We first load up the sounds from the hard disk to create Factories, and then play those Factories using the default device.
Note that there's no packing sounds into the blend file if you use Audaspace, which is similar to the inability to pack textures in if you use the bge.texture module for loading textures.
So, let's take a look at the source code.
from bge import logic import aud cont = logic.getCurrentController() obj = cont.owner if not 'init' in obj: obj['init'] = 1 logic.device = aud.device() soundpath = logic.expandPath('//theme.ogg') obj['sound'] = aud.Factory.file(soundpath) logic.device.play(obj['sound'])
So in the first line, we simply import the logic module. No surprise there. In the third, we import the Audaspace module. It's name is 'aud'. So, then, we see that a few lines down, we run some code only once. We store in a module variable (game-wide variable) a reference to the current audio Device that we'll be using to play sounds and songs.
logic.device = aud.device()
Note, you could also make a new device using the aud.Device class to customize parameters, like which library you use to play sounds (SDL or OpenAL), and other features as well, but you can easily get the current and preconfigured device using the aud.device() function, like we did here. You usually want OpenAL because it allows you to use advanced features like dynamically adjusting the pitch of sounds. Simply using the aud.device() function defaults to Blender's User Preferences setting, which is set to OpenAL by default.
soundpath = logic.expandPath('//theme.ogg')
Next, we expand a path out to our song that we want to play using a string. The string indicates the filename of the sound or song that we want to play. When using logic.expandPath, utilizing two forward slashes inthe string makes the string relative to the blend file. You would use this, for example, to navigate to the 'DungeonBGM.ogg' file in the Resources folder relative to your blend file or game executable like so:
testpath = logic.expandPath('//Resources/DungeonBGM.ogg')
Which would read back as "Game Directory (where the blend file or BlenderPlayer is)/Resources/DungeonBGM.ogg". To be more efficient, you could even store out the path to the music or resources directory, and then simply specify the filename when you want to load it:
resourcedir = logic.expandPath('//Resources/') bgmpath = resourcedir + 'DungeonBGM.ogg'
Okay, so after we specify the sound directory, we create a Factory to play a sound.
obj['sound'] = aud.Factory.file(soundpath)
A Factory is just that - a Factory, or generator, for sounds to be played from. You could think of it like a cookie cutter - each Factory plays a specific sound, but you can use it several times to play a single sound several times, even in different ways.
Note that here, I'm loading sounds using the aud.Factory.file() method, which loads a Factory from a file. You can also just use aud.Factory() and have the same result of loading a Factory from a file - I'm not sure as to the reason that both methods seem to work and exist together, but only the aud.Factory.file() method is documented, so make of that what you will. :p
Finally, we play the sound via the Device. Be sure that you only play the sound on the frame that you need to play it, and no other times. In this example, the script only runs once, so the sound plays just once. So, don't hook up a sound to play whenever the player's got a key pressed, unless you want it to play many times in a second.
There's one last thing to consider, and that's Handles. Handles are like controls for sounds after they've begun playing. You can use Handles to change the volume, pitch, loop count, and other factors about how the sound plays. Each time you play a sound using an audio Device, it returns a Handle. Handles have their own properties, which is how you control how the sound is played back. Here's an example of making a sound loop indefinitely:
handle = logic.device.play(logic.sounds['Explosion']) handle.loop_count = -1
As you can see, we assign a variable to the play() function of the sound device. This is the handle variable, and we access its loop_count variable to designate how many times the sound should loop. A value of -1 is indefinitely, a value of 0 is for no looping whatsoever, and a value greater than 0 will make the sound loop that many times.
From here, there are different ways you can expand this process. You can, for example, store a dictionary of sounds globally, along with your sound device, and play them when you need to:
Anyway, from this point, it's up to you. Have fun!