In Part 1 we handled rendering, and in Part 2 we went over the rest of the components needed for the engine. Now that we can draw things on the screen and we’ve got a plan, the next thing we’ll want to do is play music and sound effects.
There’s a lot. But thankfully, we don’t really need to care about almost all of them. For our little hobby engines, we don’t need to handle all the different codecs. It might be interesting to try loading them, I still load .WAV files myself because the format is so simple. I haven’t tried loading ogg files yet, but that’s one of the things I want to do.
For our little engines, we only need to worry about two formats. WAV files and Ogg. Depending on your game and it’s needs, you might even get away with just WAV files.
Use these files for small sound effects that you can load into memory and play. There is no compression in WAV files, so they are only suitable for short sounds.
Use these for music tracks or other long sounds, like speech. Ogg files are compressed so they save disk space.
You will likely want the RAM usage of your little game to be low. You should do this as a matter of pride in my opinion, I like my code to be efficient. To do this, you only load the sounds into memory that are repeatedly and constantly used in your game.
In Pong, you would load the ball bounce sound into memory. It’s probably going to be a WAV file because it’s short. You can load it completely into a buffer for OpenAL Soft. The music file you would have as a compressed Ogg file format, and you would stream it from disk. You can see here how it’s done.
Getting Sounds to Play
There’s a whole bunch of ways to get sounds to play. I use OpenAL Soft, which is an open-source software implementation of the OpenAL Specification. I use it because it was originally designed to be the Audio equivalent to OpenGL. It works, and it does everything I could want it to do.
Of course, there’s alternatives. Fmod is widely regarded as the defacto industry standard. However, it’s only free 1 time per year, and to be honest, you won’t need most of the features. Tinysound is another that’s basically what you would make if you did it yourself. If you’re using an existing engine, all of this would already be handled for you.
Much like I did with the rendering, I just put everything into a bunch of functions in a namespace. I don’t need the protection that classes give me because I’m the only developer here. The sorts of things you’ll need are:
- Play sound once
- Play sound every n milliseconds
- Play sound every random n between min and max milliseconds
- Stop sound immediately
- Play stream once
- Play stream repeated
- Stop stream
- Apply effect
These are objects that you can pass to the above functions that contain parameters to be applied to the audio. These objects are updated every frame by the caller so that they can be time-based. For example, fading in or out simply modified the gain of the source over time.
This is pretty much all you need for a little hobby game. You can get into 3D spatial sounds as well if you want, they add a fun extra little bit to your engine.
In the next part we’ll talk about the utilities, or just “random” functions that you’ll likely need.