# 5. White Papers | Getting Started

## Getting Started

The FMOD Studio and Core API has been designed to be intuitive and flexible. In this section an introduction to using the engine as well as the key issues involved in using it effectively will be explained.

FMOD provides a C++ API and also a C API. They are functional identical, and in fact the C++ and C functions can be mixed interchangeably, with the C++ and C classes being able to be casted back and forth. The following examples only show the C++ version.

### Initialization

#### FMOD Studio API Initialization

When using the Studio API, you can create a FMOD Studio System and then call Studio::System::initialize. That function will also initialize the in-built core FMOD system as well. Here is a simple example:

    FMOD_RESULT result;
    FMOD::Studio::System* system = NULL;

    result = FMOD::Studio::System::create(&system); // Create the Studio System object.
    if (result != FMOD_OK)
    {
        printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
        exit(-1);
    }

    // Initialize FMOD Studio, which will also initialize FMOD Core
    result = system->initialize(512, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, 0);
    if (result != FMOD_OK)
    {
        printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
        exit(-1);
    }

### FMOD Core API Initialization (Do not use this if using FMOD Studio API Initialization)

The FMOD Core API can be used without needing to use the FMOD Studio API at all. Using the Core API gives access to the fundamental abilities of loading and playing sounds, creating DSP effects, setting up FMOD ChannelGroups, and setting sample-accurate fade points and start/stop times. However, when just using the Core API, it will not be possible to load Studio banks or load and play Studio events that sound artists have set up in the Studio tool. To initialize FMOD Core directly:

    FMOD_RESULT result;
    FMOD::System *system = NULL;

    result = FMOD::System_Create(&system);      // Create the main system object.
    if (result != FMOD_OK)
    {
        printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
        exit(-1);
    }

    result = system->init(512, FMOD_INIT_NORMAL, 0);    // Initialize FMOD.
    if (result != FMOD_OK)
    {
        printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
        exit(-1);
    }

#### Advanced Initialization Settings

FMOD can be customised with advanced settings by calling System::setAdvancedSettings or Studio::System::setAdvancedSettings before initialization. For a description of the typical settings for effective virtual voices, see the Virtual Voice System.

### Playing a sound (Core API only)

The simplest way to get started, and basic functionality of FMOD Core API - is to initialize the FMOD system, load a sound, and play it. All functions execute immediately, so the developer will either fire and forget during their main loop execution, or poll for the sound to finish. Playing a sound does not block the application.

To execute a simple playSound

1. Load a sound with System::createSound, using the system object handle as described above. This will return a Sound handle. This is your handle to your loaded sound.
2. Play the sound with System::playSound, using the Sound handle returned from Step 1. This will return a Channel handle.
3. Let it play in the background, or monitor its status with ChannelControl::isPlaying, using the Channel handle returned from Step 2. A channel handle will also go immediately invalid when a sound ends, when calling any relevant Channel based function, so that is another way to know a sound has ended. The error code returned will be FMOD_ERR_INVALID_HANDLE.

### Using decompressed samples vs compressed samples vs streams

#### Decompressed Samples

The default mode for createSound is FMOD_CREATESAMPLE, which decompresses the sound into memory. This may be useful for distributing sounds compressed, then decompressing them at runtime to avoid the overhead of decompressing the sounds while playing. This can be expensive on mobile devices depending on the format. Decompressing to PCM uses litte CPU during playback, but also uses many times more memory at runtime.

#### Streams

Loading a sound as a streaming, gives the ability to take a large file, and read/play it in realtime in small chunks at a time, avoiding the need to load the entire file into memory. This is typically reserved for Music / Voice over / dialogue or Long ambience tracks. The user can simply play a sound as a stream by adding the FMOD_CREATESTREAM flag to the System::createSound function, or using the System::createStream function. The 2 options equate to the same end behavior.

#### Compressed Samples

To play a sound as compressed, simply add the FMOD_CREATECOMPRESSEDSAMPLE flag to the System::createSound function

Because compressed samples are more complicated, they have larger contexts to deal with (for example vorbis decode information), so there is a constant per voice overhead (up to a fixed limit) for a playing sound.
This allocation is typically incurred at System::init time if the user calls System::setAdvancedSettings and sets a maxCodecs value, or it could happen the first time a sound is loaded with the FMOD_CREATECOMPRESSEDSAMPLE flag. This will not be configured by the user so uses the default of 32 codecs for the allocation.

As an example: the vorbis codec has an overhead of 16kb per voice, so the default of 32 vorbis codecs will consume 512kb of memory. This is adjustable by the user to reduce or increase the default of 32, using the System::setAdvancedSettings function as mentioned. The user would adjust the FMOD_ADVANCEDSETTINGS maxVorbisCodecs value for the vorbis case. Other supported codecs are adjustable as well.

The best cross platform codec to used as a compressed sample is Vorbis (from an FSB file) but if it uses too much CPU for your platform (ie mobile), the FADPCM codec is a good second option. It is less compressed, and uses far less CPU cycles to decode, while giving good quality and 4:1 compression. For PS4 or Xbox One, it is better to use the AT9 and XMA codec format respectively, as the decoding of these formats are handled by separate media chips, taking the load off the CPU.

### Update

FMOD should be ticked once per game update. When using FMOD Studio, call Studio::System::update, which internally will also update the Core system. If using Core directly, instead call System::update.

If FMOD Studio is running in asynchronous mode (the default, unless FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE has been specified), then the Studio::System::update will be extremely quick as it is merely swapping a buffer for the asynchronous execution of that frame's commands.

### Shut Down

To shut down FMOD Studio call Studio::System::release. If using the Core directly, instead call System::release.

### Error Checking

In the FMOD examples, the error codes are checked with a macro that calls into an handling function if an unexpected error occurs. That is the recommended way of calling FMOD Studio API functions. There is also a callback that can be received whenever a public FMOD function has an error. See FMOD_SYSTEM_CALLBACK for more information.

### Configuration

The output hardware, FMOD's resource usage, and other types of configuration options can be set if you desire behavior differing from the default. These are generally called before System::init. For examples of these, see Studio::System::getCoreSystem, System::setAdvancedSettings, Studio::System::setAdvancedSettings.

### Avoiding stalls while loading or releasing a sound

One of the slowest operations is loading a sound. To place a sound load into the background so that it doesn't affect processing in the main application thread, the user can use the FMOD_NONBLOCKING flag in System::createSound or System::createStream.

Immediately a sound handle is returned to the user. The status of the sound being loaded can then be checked with Sound::getOpenState. If a function is called on a sound that is still loading (besides getOpenState), it will typically return FMOD_ERR_NOTREADY. Wait until the sound is ready to play it. The state would be FMOD_OPENSTATE_READY.

To avoid a stall on a streaming sound when trying to free/release it, check that the state is FMOD_OPENSTATE_READY before calling Sound::release.