Home > FMOD > Cutting Your Teeth on FMOD Part 3: Embedding Sounds In Your Application as Resources

Cutting Your Teeth on FMOD Part 3: Embedding Sounds In Your Application as Resources

January 15, 2013 Leave a comment Go to comments

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:

  1. In the Solution Explorer window, click the Resource View tab, or press Ctrl+Shift+E (default keyboard shortcut for C++ setup) to display it.
  2. Right-click the project to which you wish to embed resources, and choose Add -> Resource from the menu.
  3. 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.
  4. 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.
Embedded Audio Resources in Visual Studio

Figure 1. Embedded Audio Resources in Visual Studio

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 createSound to createStream and add a line of code to set the stream buffer size right before calling createStream:

system->setStreamBufferSize(65536, FMOD_TIMEUNIT_RAWBYTES);

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.

Coming Up…

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!

Advertisements
  1. January 15, 2013 at 15:47

    After being created in FMOD, is it necessary to keep the Lock and the handle?

    • January 15, 2013 at 18:57

      No, if you read the MSDN page on LockResource it is actually a misleading name, it doesn’t lock anything. FMOD_OPENMEMORY causes a resource to be copied into its own buffers so you don’t need to keep the handle either. To avoid the overhead, you can use FMOD_OPENMEMORY_POINT to use a pointer to the resource directly.

  2. Andrey
    June 1, 2013 at 04:47

    Now… what should one do if their Add -> Resource option is disabled? ._.

    • June 1, 2013 at 22:01

      That should never be the case, even in the free editions of Visual C++ Express/Desktop as far as I know. I’ve never seen the menu option grayed out altogether, sorry…

      • Andrey
        June 2, 2013 at 18:28

        Well, it is! 😦 I am using Express 2010.

        Uh… would you be able to recommend any other course of action? …From what I’ve heard, creating resource files is disabled in the free versions, but they can still be imported and go from there. So then… the problem becomes finding some other third party software that can convert mp3s into resource files. I haven’t managed to find any that work. …have you?

        • June 5, 2013 at 15:27

          You shouldn’t need to convert them; the IDE maintains an .rc file automatically which contains the filenames and resource types of each external resource. If Express doesn’t support importing resources in the IDE, my only suggestion would be to see if you can do it on the command-line with the supplied tools. Unfortunately I’m not an expert on that.

  3. Andrey
    July 18, 2013 at 04:21

    …Well, Miss Katy, I’ve had quite the adventure. After screwing around with multiple third party programs and command line tools, my resource-creating endeavors were hitting a brick wall.

    Eventually I went and found an Ultimate version of Visual Studio, which DID let me Add -> Resources! Yay! So then… I began following everything in this post, to the letter, and I kept getting different run and/or compile time errors for some reason or another. The most consistent one was FindResource returning error code 1813 (something about not being able to find the file).

    After many more weeks of googling and stackoverflow’ing, I stumbled upon this: http://stackoverflow.com/questions/12385163/findresource-doesnt-find-my-resource

    Desperately, I tried prepending that pound sign in front of the integer, and… miraculously… it worked. I didn’t believe it… every other example I’ve looked at used MAKEINTRESOURCE() (including yours!!). And somehow it’s worked for everyone but me. My resources.h file and my .rc file looked exactly as they were supposed to… So what the hell then! Was my FindResource function just being retarded? Converting the “INTRESOURCE” to something other than the correct value..?

    Whatever it is, that random octothorpe sure saved the day (and my sanity)! Instead of MAKEINTRESOURCE, I just ended up concatenating “#” with the number and passing it directly through FindResource’s second argument.

    I now have a superduper awesomesauce game that DOESN’T have a massive bin folder full of mp3s following it! And I have (mostly) you to thank for it. Sorry ’bout all the rambling. I just got really excited after finally solving this, so I felt like sharing my story. Thanks again, and… have fun eating those cookies!

    • July 22, 2013 at 13:01

      Thanks for sharing! When I was coding the loading of image files from resources in the Simple2D library elsewhere on the site I had similar problems with getting it to find the resource, I was tearing my hair out over it and the hash sign trick didn’t work either (I’m from England where we call “£” the pound sign and “#” the hash sign, you confused me momentarily :D), I don’t remember what the problem was on the end but I know I wasted a lot of hours on it and the whole MAKEINTRESOURCE() thing and resource numbers themselves seem very fickle. Glad you got the problem solved, I will await with bated breath the release of your superduper awesomesauce game 🙂

  1. January 25, 2013 at 07:44
  2. February 19, 2013 at 00:12
  3. March 15, 2013 at 15:16

Share your thoughts! Note: to post source code, enclose it in [code lang=...] [/code] tags. Valid values for 'lang' are cpp, csharp, xml, javascript, php etc. To post compiler errors or other text that is best read monospaced, use 'text' as the value for lang.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: