# 5. White Papers | Transitioning from FMOD Ex

## Transitioning between FMOD Ex and FMOD Studio

This section describes the differences between FMOD Ex and FMOD Studio.

### FMOD Studio API Versus FMOD Designer API

The FMOD Studio API is conceptually similar to the old FMOD Designer API, but most classes have been renamed, and some have been removed or split up.

#### EventSystem and EventSystem_Create

The Studio::System class is analogous to the old EventSystem class. The static Studio::System::create function is analogous to the old EventSystem_Create function.

#### EventProject

The Studio::Bank class is analogous to the old EventProject class.

#### FEV and FSB Files

Each FMOD Designer project produced a single .fev file and multiple .fsb files. In contrast, an FMOD Studio project produces multiple .bank files, which contain event metadata as well as sample data. See the Studio::System::loadBankFile, Studio::Bank::loadSampleData, and Studio::EventDescription::loadSampleData functions. The core API still supports loading .fsb files directly.

#### EventGroup

FMOD Studio doesn't have the concept of EventGroups. Events can be placed in folders, but this has no significance at runtime. To achieve the loading control formerly provided by EventGroups, events can be placed in different banks.

#### Event

The old Event class has been split into two classes: Studio::EventDescription and Studio::EventInstance. Studio::EventDescription holds the static data that describes an event, while Studio::EventInstance is a playable instance of an event. These two classes correspond to old Event objects retrieved by calling getEvent with or without the FMOD_EVENT_INFOONLY flag.

The FMOD Designer API used to create a fixed number of event instances when you first called getEvent without FMOD_EVENT_INFOONLY, whereas the FMOD Studio API creates a single instance each time you call Studio::EventDescription::createInstance. This gives you more control over the memory usage for each event.

#### Retrieving Events

Events can be retrieved by ID (using Studio::System::getEventByID) or by path (using Studio::System::getEvent).

Event IDs are GUIDs (globally unique identifiers), and stay the same even if the event is renamed or moved around in the project. IDs can be parsed from a string using Studio::parseID, or looked up from a path using Studio::System::lookupID if the "Master Bank.strings.bank" file is loaded.

Event paths consist of the string "event:/", followed by the the path to the event within the project's folder structure. To retrieve events by path, the "Master Bank.strings.bank" file must be loaded.

#### EventParameter

There is no class analogous to the old EventParameter class. Instead use the parameter getting and setting functions in Studio::EventInstance: Studio::EventInstance::getParameterByID, Studio::EventInstance::getParameterByName, Studio::EventInstance::setParameterByID, Studio::EventInstance::setParameterByName, Studio::EventInstance::setParametersByIDs.

#### Sustain Points and Key Off

The old EventParameter class had a keyOff function to move past the next sustain point. In FMOD Studio this behavior is implemented via a built-in KeyOff that can be triggered via Studio::EventInstance::keyOff.

#### EventCategory

Event categories have been replaced in FMOD Studio by buses and VCAs, which provide much more functionality to the sound designer. At runtime, buses and VCAs are accessed via the Studio::Bus and Studio::VCA classes.

#### EventReverb

The EventReverb class has been removed. Similar functionality can be implemented using events with automatic distance parameters controlling reverb snapshots.

#### EventQueue and EventQueueEntry

FMOD Studio doesn't have the concept of event queues.

#### MusicSystem and MusicPrompt

Interactive music in FMOD Studio is implemented inside the event editor, so the MusicSystem and MusicPrompt classes have been removed.

#### NetEventSystem

Whereas the old network tweaking API was implemented as a separate fmod_event_net library, the FMOD Studio live update system is built into the main API library, and can be enabled by passing FMOD_STUDIO_INIT_LIVEUPDATE to Studio::System::initialize.

### FMOD Studio Core API Versus FMOD Ex Core API

### New features

#### No more 'recommended startup sequence'

FMOD Studio now handles the speaker mode automatically. To start FMOD Studio is as simple as calling System::init, rather than querying caps or speaker modes to make FMODs software mixer match that of the operating system. If you want the software mixer to be forced into a certain speaker mode, disregarding the operating system, use System::setSoftwareFormat. FMOD will automatically downmix or upmix this mode if the user's system is not the same speaker mode as the one selected for the software engine. Where possible, Dolby or internal downmixing will be used to achieve better surround effect.

#### Added new DSP effects

The following new DSP effects are added. (From fmod_dsp_effects.h)

    FMOD_DSP_TYPE_SEND,               /* This unit sends a copy of the signal to a return DSP anywhere in the DSP tree. */
    FMOD_DSP_TYPE_RETURN,             /* This unit receives signals from a number of send DSPs. */
    FMOD_DSP_TYPE_HIGHPASS_SIMPLE,    /* This unit filters sound using a simple highpass with no resonance, but has flexible cutoff and is fast. Deprecated and will be removed in a future release (see FMOD_DSP_HIGHPASS_SIMPLE remarks for alternatives). */
    FMOD_DSP_TYPE_PAN,                /* This unit pans the signal, possibly upmixing or downmixing as well. */
    FMOD_DSP_TYPE_THREE_EQ,           /* This unit is a three-band equalizer. */
    FMOD_DSP_TYPE_FFT,                /* This unit simply analyzes the signal and provides spectrum information back through getParameter. */
    FMOD_DSP_TYPE_LOUDNESS_METER,     /* This unit analyzes the loudness and true peak of the signal. */
    FMOD_DSP_TYPE_ENVELOPEFOLLOWER,   /* This unit tracks the envelope of the input/sidechain signal. Format to be publicly disclosed soon. */
    FMOD_DSP_TYPE_CONVOLUTIONREVERB,  /* This unit implements convolution reverb. */
    FMOD_DSP_TYPE_CHANNELMIX,         /* This unit provides per signal channel gain, and output channel mapping to allow 1 multi-channel signal made up of many groups of signals to map to a single output signal. */
    FMOD_DSP_TYPE_TRANSCEIVER,        /* This unit 'sends' and 'receives' from a selection of up to 32 different slots.  It is like a send/return but it uses global slots rather than returns as the destination.  It also has other features.  Multiple transceivers can receive from a single channel, or multiple transceivers can send to a single channel, or a combination of both. */
    FMOD_DSP_TYPE_OBJECTPAN,          /* This unit sends the signal to a 3d object encoder like Dolby Atmos.   Supports a subset of the FMOD_DSP_TYPE_PAN parameters. */
    FMOD_DSP_TYPE_MULTIBAND_EQ,       /* This unit is a flexible five band parametric equalizer. */

Note FMOD's convolution reverb also has the option to be GPU accelerated for big performance wins.

#### New file format support

FMOD_SOUND_TYPE_FADPCM is a new highly optimized, branchless ADPCM variant which has higher quality than IMA ADPCM, and better performance. Great for mobiles.

#### Dolby Atmos support

Through the FMOD object panner, sounds can be positioned spherically in 3d space to support Dolby Atmos. This includes height speakers.

#### New DSP mixing engine

FMOD Studio's software mixing engine is now more flexible, with support for changing channel formats and speaker modes as the signal flows through the mix. FMOD Studio's new software mixing engine also has better custom DSP support, with branch idling, silence detection, sends and returns, side-chaining, circular connections and more.

#### Added plugin info helper function

System::getDSPInfoByPlugin has been added to plug the gap between loading a plugin, and getting its FMOD_DSP_DESCRIPTION structure so that it can be passed to System::createDSP.

#### Added background suspension support

For mobile devices, System::mixerSuspend and System::mixerResume allows you to halt FMODs cpu mixer and thread before sleeping or answering a call or any other interruption event.

#### ChannelGroups volume and panning are now DSP based, rather than reaching down to the Channels of the child ChannelGroups.

ChannelGroups in FMOD Ex were a way to scale and modify the pan and volume of the Channels in the ChannelGroups below. FMOD Studio now modifies pan and volume on a DSP basis using the FMOD DSP 'Fader' unit, and the fader can be repositioned in amongst its own effect list, so you can get the concept of post or pre fader effects.

#### Added additional output streams

System::attachChannelGroupToPort and System::detachChannelGroupFromPort allows signals to be sent to alternate sound outputs like headsets, controllers with speakers, and console based multi speaker arrays that are not the standard surround sound speaker output.

#### Added Sound helper function

Added the ability for a child sound (subsound) to query for its parent via Sound::getSubSoundParent.

#### Added sample volume control

ChannelControl::addFadePoint, ChannelControl::removeFadePoints and ChannelControl::getFadePoints give the ability to set up a volume fade or ramp between any 2 clock points is possible. Link up multiple fade points to create envelopes. All fading is clock accurate and compensated for when pitch is changed. ChannelControl::setVolumeRamp / ChannelControl::getVolumeRamp can be used when queuing sounds up and for other reasons, it can be desirable to turn off ramping of volume changes, so the ability has been added to turn volume ramping (declicking) off or on per Channel/ChannelGroup.

#### Added UTF8 support

Functions such as System::getDriverInfoW have been removed in favour of UTF8 support.

#### Added concept of a 'fader' DSP per Channel and ChannelGroup

Each Channel and ChannelGroup has a built in 'fader' (FMOD_DSP_TYPE_FADER). This also acts as the DSP 'head' of the Channel or ChannelGroup by default.
This can of course be changed later. If you add an effect, you can position it to be the head, and the fader will be before that in the signal chain.
A fader DSP simply adjusts volume of the signal for a mix, and also supports sample accurate volume fade points, for envelopes and fade ins / fade outs.
A panner is a separate entity which can pan a sound in mono, stereo and surround using a variety of parameters including position/direction/extent/rotation/axis control and 3d position control.
The order of processing of a fader and panner can be controlled using ChannelControl::setDSPIndex, and it can be positioned into an effect chain so that panning comes before an effect or after, with fading coming at a different position in the effect chain.

#### New DSPConnection types supported

DSP::addInput now has a new optional parameter to describe the connection's behavior between 2 DSP units. FMOD_DSPCONNECTION_TYPE has been added to tell an input DSP that it should mix to a 'sidechain' buffer, which is a special buffer for DSP units that want to process a sidechain (for example a compressor) through a DSP unit's FMOD_DSP_STATE structure. This signal is not audible but is used to affect behavior within the DSP. FMOD_DSPCONNECTION_TYPE_SIDECHAIN would be used here.
It should only consume existing data, not execute the input to generate that data. FMOD_DSPCONNECTION_TYPE_SEND would be used here. This can be useful for graph dependency reasons, so that an input is not executed before it should be.

#### New DSP parameter types

In FMOD Ex, only float parameters were supported. Now Int, Bool and Data parameters are supported.
Use:

- DSP::setParameterFloat, DSP::getParameterFloat
- DSP::setParameterInt, DSP::getParameterInt
- DSP::setParameterBool, DSP::getParameterBool
- DSP::setParameterData, DSP::getParameterData

### Changes

#### FMOD_HARDWARE support

FMOD Studio is such an advanced mixing engine, that the limited features of hardware voices could not possibly hope to achieve parity with the features of FMOD's software engine. It has been decided that in this day and age of multicore processors, even at the mobile level, that hardware voice support gained nothing for the user. FMOD's software engine can actually be faster, and better quality, and more flexible than hardware, so all sounds and voices are software mixed now. API changes:

System::setHardwareChannels is removed
System::getDriverCaps is removed. systemrate, speakermode, speakermodechannels parameters have been added to System::getDriverInfo to provide the information which may be important to the developer. Similarly, System::getRecordDriverCaps has been removed, in favour of System::getRecordDriverInfo.
System::setSpeakerMode and System::getSpeakerMode are removed, and instead are now moved into System::setSoftwareFormat because 'speakermode' now only affects the internal mixer, and the operating system speaker mode is matched at runtime through matrix upmixing or downmixing (automatically).

#### FMOD Ex had Channels and ChannelGroups, now it seems they are merged into 'ChannelControl'?

Channels and ChannelGroups had some similar functionality in FMOD Ex (ie setVolume, setPaused), but FMOD Studio takes it even further. FMOD Studio has been designed so that ChannelGroups can have a lot more control, like pausing and muting at the DSP node level, adding effects, and positioning in 3d.

#### Converting FMOD Reverb parameters

Reverb parameters have changed in FMOD Studio. Use this table to convert from FMOD Ex parameters to FMOD Studio parameters.

Studio property | Range | FMOD Ex property / conversion formula to create FMOD Studio value
--- | --- | ---
DecayTime (ms) | 100 to 20000 | DecayTime * 1000
EarlyDelay (ms) | 0 to 300 | ReflectionsDelay * 1000
LateDelay (ms) | 0 to 100 | ReverbDelay * 1000
HFReference (Hz) | 20 to 20000 | HFReference
HFDecayRatio (%) | 0 to 100 | DecayHFRatio * 100
Diffusion (%) | 0 to 100 | Diffusion
Density (%) | 0 to 100 | Density
LowShelfFrequency (Hz) | 20 to 1000 | LFReference
LowShelfGain (dB) | -48 to 12 | RoomLF / 100
HighCut (Hz) | 20 to 20000 | IF RoomHF < 0 THEN HFReference / sqrt((1-HFGain) / HFGain) ELSE 20000
EarlyLateMix (%) | 0 to 100 | IF Reflections > -10000 THEN LateEarlyRatio/(LateEarlyRatio + 1) * 100 ELSE 100
WetLevel (dB) | -80 to 20 | 10 * log10(EarlyAndLatePower) + Room / 100

Note: Clamp all values to maximum (after conversion) as some conversions may exceed the new parameter range.

Intermediate variables used in conversion | Formulas
--- | ---
LateEarlyRatio | pow(10, (Reverb - Reflections) / 2000)
EarlyAndLatePower | pow(10, Reflections / 1000) + pow(10, Reverb / 1000)
HFGain | pow(10, RoomHF / 2000)

#### System::set3DSpeakerPosition renamed

System::setSpeakerPosition is a minor name change to denote that 3d and 2d positioning is affected by speaker location.

#### FMOD_CHANNEL_FREE / FMOD_CHANNEL_REUSE removed. Default ChannelGroup now passed to playSound if needed

System::playSound and System::playDSP now do not take a 'channel' parameter. All channels behave the same way as FMOD_CHANNEL_FREE would have in FMOD Ex.
Seeing as a parameter was removed from playSound/playDSP, a new one was added to remove the overhead of disconnecting and reconnecting DSP graph nodes after playSound was called, so that they could be hooked up to a new ChannelGroup other than the master ChannelGroup. Consider this addition a performance optimization, and a simplification in API calls.

#### CDROM / CDDA support removed

Legacy support for CDROM redbook audio playback has been removed due to lack of interest and issues with maintaining said code.

#### System::getSpectrum and System::getWaveData removed

Add a custom DSP unit to capture DSP wavedata from the output stage. Use the master ChannelGroup's DSP head with System::getMasterChannelGroup and ChannelControl::getDSP.
Add a built in FFT DSP unit type to capture spectrum data from the output stage. Create a built in FFT unit with System::createDSPByType and FMOD_DSP_TYPE_FFT, then add the effect to the master ChannelGroup with ChannelControl::addDSP. Use DSP::getParameterData to get the raw spectrum data or use DSP::getParameterFloat to get the dominant frequency from the signal.

#### 'W' function wide char support removed

Functions such as System::getDriverInfoW have been removed in favour of UTF8 support.

#### System::setReverbAmbientProperties removed

The 'background' ambient reverb for a 3d reverb system is now just the standard reverb set with System::setReverbProperties.

#### System::getDSPClock removed

Use the DSP clock of the master ChannelGroup instead with System::getMasterChannelGroup and ChannelControl::getDSPClock.

#### getMemoryInfo functions have been removed from all classes

Due to the unreliability of the function in FMOD Ex due to caching, threads, and shared memory throwing results out, the function has been removed. Alternate memory tracking methods will be added later. FMOD::Memory_GetStats and logging is the best way to track memory at the moment.

#### Sound::setVariations and Sound::getVariations have been removed

Due to this being a 'helper' function that can easily be achieved in user code, this was deemed not necessary and removed.

#### Sound::setSubSoundSentence has been removed

This function has been removed in favour of the extremely precise and more reliable ChannelControl::setDelay functionality. 2 or more sounds can be queued up to play end to end using this function, with the added benefit of cross fades and overlaps.

#### setDelay and clock functions now use 64bit 'long long' type rather than than 32bit hi and 32bit low part parameters.

Due to the complexity of working in fixed point, and seeing as there is a consistent 64bit type for all compilers in long long that FMOD supports, we have switched to this type.
1 32bit value would wrap around in 24 hours at 48khz, so 64bit values will last for 12 million years which should be enough to avoid in game clock wrap around.

#### Channel::setSpeakerMix, Channel::setSpeakerLevels, Channel::setInputChannelMix, Channel::getPan, Channel::getSpeakerMix and Channel::getSpeakerLevels removed

A cleaner replacement has been made for these functions,

- ChannelControl::setMixLevelsOutput (float frontleft, float frontright, float center, float lfe, float surroundleft, float surroundright, float backleft, float backright);
- ChannelControl::setMixLevelsInput (float *levels, int numlevels);
- ChannelControl::setMixMatrix (float *matrix, int outchannels, int inchannels, int inchannel_hop = 0);
- ChannelControl::getMixMatrix (float matrix, int outchannels, int *inchannels, int inchannel_hop = 0);

Note that because setPan, setMixLevelsOutput and setMixLevelsInput all affect a final pan matrix, only getMixMatrix is available as the 'getter'. There is no more exclusive mode for the panning technique like there was in FMOD Ex. All 3 functions can now affect the final matrix. The setMixMatrix function now allows instant setting of a full matrix for performance reasons, rather than calling setSpeakerLevels each time for each speaker.

#### DSPConnection::setLevels/getLevels have been removed.

As above, new functionality is available to produce the same result. Rather than setting output levels row by row, a full 2 dimensional matrix is supplied with DSPConnection::setMixMatrix.

#### Channel::set3DPanLevel misnomer renamed

The FMOD Ex function did not actually only affect pan, it also affected doppler and distance attenuation so to call it 'pan' level was not really correct. FMOD Studio corrects this with ChannelControl::set3DLevel.

#### 'override' functions removed from ChannelGroup class

Because volume/pitch/muting/reverb properties and pausing has been added as a ChannelGroup concept at the DSP level, ChannelGroups no longer rely on their 'channels' to do pausing and muting type logic. The ChannelGroup's DSP itself will directly mute/pause etc, thanks to the removal of FMOD_HARDWARE support.

#### System::addDSP removed from the System API

Rather than using the 'system' to add a DSP to, the user must use System::getMasterChannelGroup which gets the top level ChannelGroup, then use ChannelControl::addDSP to add the DSP to it, which effectively puts at the end of the signal chain.

#### DSP::remove removed from the DSP API

Effects that are added with ChannelControl::addDSP are owned by the ChannelControl that added it, and therefore must be removed with ChannelControl::removeDSP, instead of having the DSP removing itself. This helps the ChannelGroup or Channel manage resources.