FMOD Engine User Manual 2.03
This section describes the differences between FMOD Ex and FMOD Studio.
The 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.
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.
The Studio::Bank class is analogous to the old EventProject class.
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.
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.
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 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.
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.
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.
The old EventParameter class had a keyOff function to move past the next sustain point. In FMOD Studio and the Studio API, this behavior is implemented via a built-in KeyOff that can be triggered via Studio::EventInstance::keyOff.
Event categories have been replaced in FMOD Studio by buses and VCAs, which provide much more functionality to the sound designer. In the Studio API, buses and VCAs are accessed via the Studio::Bus and Studio::VCA classes.
The EventReverb class has been removed. Similar functionality can be implemented using events with automatic distance parameters controlling reverb snapshots.
FMOD Studio doesn't have the concept of event queues.
Interactive music in FMOD Studio is implemented inside the event editor, so the MusicSystem and MusicPrompt classes have been removed.
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.
The FMOD Engine now handles the speaker mode automatically. Starting the Core API is as simple as calling System::init, and does not require querying caps or speaker modes to make the FMOD Engine's 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. The FMOD Engine 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.
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_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.
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.
Through the FMOD object panner, sounds can be positioned spherically in 3d space to support Dolby Atmos. This includes height speakers.
The FMOD Engine's software mixing engine is more flexible than that of FMOD Ex, with support for changing channel formats and speaker modes as the signal flows through the mix. THe FMOD Engine's software mixing engine also has better custom DSP support, with branch idling, silence detection, sends and returns, side-chaining, circular connections and more.
System::getDSPInfoByPlugin has been added to plug the gap between loading a plug-in, and getting its FMOD_DSP_DESCRIPTION structure so that it can be passed to System::createDSP.
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 in FMOD Ex were a way to scale and modify the pan and volume of the Channels in the ChannelGroups below. The FMOD Engine now modifies pan and volume on a DSP basis using the fader DSP unit. A fader unit can be repositioned in its own effect list, allowing effects to be either post- or pre-fader effects.
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 the ability for a child sound (subsound) to query for its parent via Sound::getSubSoundParent.
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.
Functions such as System::getDriverInfoW have been removed in favour of UTF8 support.
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.
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.
In FMOD Ex, only float parameters were supported. Now Int, Bool and Data parameters are supported.
Use:
The FMOD Engine's software mixing is sufficiently advanced that it can do things that would be impossible with the limited features of hardware voices. Today, when multicore processors are common even on mobile platforms, hardware voice support provides no real advantage; not when the FMOD Engine can be faster, better quality, and more flexible. As such, all sounds and voices handled by the FMOD Engine are software mixed.
API changes:
Channels and ChannelGroups had some similar functionality in FMOD Ex (ie setVolume, setPaused), but the FMOD Engine takes it even further. The FMOD Engine is designed so that ChannelGroups can have a lot more control, including allowing pausing and muting at the DSP node level, adding effects, and positioning in 3D.
The FMOD Engine handles reverb parameters differently to FMOD Ex. Use this table to convert from FMOD Ex parameters to FMOD Engine parameters.
FMOD Engine property | Range | FMOD Ex property / conversion formula to create FMOD Engine 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::setSpeakerPosition is a minor name change to denote that 3d and 2d positioning is affected by speaker location.
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.
Legacy support for CDROM redbook audio playback has been removed due to lack of interest and issues with maintaining said code.
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.
Functions such as System::getDriverInfoW have been removed in favour of UTF8 support.
The 'background' ambient reverb for a 3d reverb system is now just the standard reverb set with System::setReverbProperties.
Use the DSP clock of the master ChannelGroup instead with System::getMasterChannelGroup and ChannelControl::getDSPClock.
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.
Due to this being a 'helper' function that can easily be achieved in user code, this was deemed not necessary and 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.
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.
A cleaner replacement has been made for these functions,
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.
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.
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. THe FMOD Engine corrects this with ChannelControl::set3DLevel.
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.
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.
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.