Cutting Your Teeth on FMOD Part 3: Embedding Sounds In Your Application as Resources
Having all of your sounds and music as separate files in your application is messy, and makes abuse by mischievous souls slightly easier. To tidy things up, we can embed audio files directly into the compiled EXE file. FMOD provides the ability to load audio directly from memory, so the problem has two main steps: 1. embed the audio resources in your application, 2. modify the application code to load resources from memory (your application process) instead of from files.
Note: The SimpleFMOD library contains all of the source code and pre-compiled executables for the examples in this series.
Embedding Audio Resources using Visual Studio
If you are using uncompressed audio (WAV or FLAC files) I first recommend that you use a tool to compress them into Vorbis files or another format supported by FMOD. Note that although MP3s are supported (and we use them in this tutorial), FMOD does not grant you a license to use MP3s in commercial applications – this must be paid for separately.
Once you have your audio ready, open your solution in Visual Studio and for each file, perform the following steps:
- In the Solution Explorer window, click the Resource View tab, or press Ctrl+Shift+E (default keyboard shortcut for C++ setup) to display it.
- Right-click the project to which you wish to embed resources, and choose Add -> Resource from the menu.
- In the window that appears, click Import… and choose the audio file to embed. You will need to change the file filter to All Files, as only graphic formats are shown by default.
- You will be asked to enter a name for the resource type. Enter any short descriptive name you wish, like Audio or MP3, and re-use the same name for each subsequent import.
Once you are finished you should have something like Figure 1 in Solution Explorer, with an automatically generated file called
resource.h in your project. Do not edit this file, Visual Studio will handle updates automatically as you edit your resources. Note that it includes several
#defines which give each of your embedded resources a unique ID. This is used in your code to locate them later.
Loading embedded resources into FMOD
You would be surprised how complicated this is, so to save you the trouble, I have provided the code below. First, we’ll set a couple of variables to the resource we want to locate:
int resourceId = IDMP3_Song1; LPCTSTR resourceType = "MP3";
The above lines correspond to one of the resources shown in Figure 1. You will need to change these to match your own project settings.
To actually find and load the resource into FMOD:
HRSRC rsrc = FindResource(NULL, MAKEINTRESOURCE(resourceId), resourceType); HGLOBAL handle = LoadResource(NULL, rsrc); DWORD audioSize = SizeofResource(NULL, rsrc); LPVOID audioData = LockResource(handle); FMOD_CREATESOUNDEXINFO audioInfo; memset(&audioInfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); audioInfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); audioInfo.length = static_cast<unsigned int>(audioSize); // system is a pointer to FMOD::System set in your application's initialization phase FMOD::Sound *sound; FMODErrorCheck(system->createSound(static_cast<const char *>(audioData), FMOD_OPENMEMORY, &audioInfo, &sound));
At this point, the audio resource will be loaded into
sound just as if it had been loaded from file. Note that this code opens the sound directly. If you want to open it as a stream, simply change
createStream and add a line of code to set the stream buffer size right before calling
for a buffer size of 64K. You may wish to experiment with this value to get the best performance if your application suffers from stuttering or broken up audio when streaming.
In Part 4 of our series on FMOD we will look at how to do a real-time frequency analysis of a playing stream, such that we can add visual effects or events to our game that trigger in time with the playing audio. Have fun!