text:
/*
    fmod_studio_common.h
    Copyright (c), Firelight Technologies Pty, Ltd. 2017.

    This header defines common enumerations, structs and callbacks that are shared between the C and C++ interfaces.
*/

#ifndef FMOD_STUDIO_COMMON_H
#define FMOD_STUDIO_COMMON_H

#include "fmod.h"

/*
    FMOD Studio types.
*/

typedef struct FMOD_STUDIO_SYSTEM FMOD_STUDIO_SYSTEM;
typedef struct FMOD_STUDIO_EVENTDESCRIPTION FMOD_STUDIO_EVENTDESCRIPTION;
typedef struct FMOD_STUDIO_EVENTINSTANCE FMOD_STUDIO_EVENTINSTANCE;
typedef struct FMOD_STUDIO_PARAMETERINSTANCE FMOD_STUDIO_PARAMETERINSTANCE;
typedef struct FMOD_STUDIO_BUS FMOD_STUDIO_BUS;
typedef struct FMOD_STUDIO_VCA FMOD_STUDIO_VCA;
typedef struct FMOD_STUDIO_BANK FMOD_STUDIO_BANK;
typedef struct FMOD_STUDIO_COMMANDREPLAY FMOD_STUDIO_COMMANDREPLAY;

/*
[DEFINE]
[
    [NAME]
    FMOD_STUDIO_INITFLAGS

    [DESCRIPTION]
    Studio System initialization flags.
    Use them with Studio::System::initialize in the *studioflags* parameter to change various behavior.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::initialize
]
*/
#define FMOD_STUDIO_INIT_NORMAL                     0x00000000  /* Initialize normally. */
#define FMOD_STUDIO_INIT_LIVEUPDATE                 0x00000001  /* Enable live update. */
#define FMOD_STUDIO_INIT_ALLOW_MISSING_PLUGINS      0x00000002  /* Load banks even if they reference plugins that have not been loaded. */
#define FMOD_STUDIO_INIT_SYNCHRONOUS_UPDATE         0x00000004  /* Disable asynchronous processing and perform all processing on the calling thread instead. */
#define FMOD_STUDIO_INIT_DEFERRED_CALLBACKS         0x00000008  /* Defer timeline callbacks until the main update. See Studio::EventInstance::setCallback for more information. */
#define FMOD_STUDIO_INIT_LOAD_FROM_UPDATE           0x00000010  /* No additional threads are created for bank and resource loading.  Loading is driven from Studio::System::update.  Mainly used in non-realtime situations. */
/* [DEFINE_END] */

typedef unsigned int FMOD_STUDIO_INITFLAGS;

/*
[ENUM]
[
    [DESCRIPTION]
    These values describe the loading status of various objects.

    [REMARKS]
    Calling Studio::System::loadBankFile, Studio::System::loadBankMemory or Studio::System::loadBankCustom
    will trigger loading of metadata from the bank.

    Calling Studio::EventDescription::loadSampleData, Studio::EventDescription::createInstance
    or Studio::Bank::loadSampleData may trigger asynchronous loading of sample data.

    [SEE_ALSO]
    Studio::EventDescription::getSampleLoadingState
    Studio::Bank::getLoadingState
    Studio::Bank::getSampleLoadingState
]
*/
typedef enum FMOD_STUDIO_LOADING_STATE
{
    FMOD_STUDIO_LOADING_STATE_UNLOADING,        /* Currently unloading. */
    FMOD_STUDIO_LOADING_STATE_UNLOADED,         /* Not loaded. */
    FMOD_STUDIO_LOADING_STATE_LOADING,          /* Loading in progress. */
    FMOD_STUDIO_LOADING_STATE_LOADED,           /* Loaded and ready to play. */
    FMOD_STUDIO_LOADING_STATE_ERROR,            /* Failed to load and is now in error state. */

    FMOD_STUDIO_LOADING_STATE_FORCEINT = 65536  /* Makes sure this enum is signed 32bit. */
} FMOD_STUDIO_LOADING_STATE;

/*
[ENUM]
[
    [DESCRIPTION]
    Specifies how to use the memory buffer passed to Studio::System::loadBankMemory.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::loadBankMemory
    Studio::Bank::unload
]
*/
typedef enum FMOD_STUDIO_LOAD_MEMORY_MODE
{
    FMOD_STUDIO_LOAD_MEMORY,                    /* Duplicates the memory into its own buffers, memory can be freed after Studio::System::loadBankMemory returns. */
    FMOD_STUDIO_LOAD_MEMORY_POINT,              /* Copies the memory pointer without duplicating the memory into its own buffers, memory can be freed after receiving a FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD callback. */

    FMOD_STUDIO_LOAD_MEMORY_FORCEINT = 65536    /* Makes sure this enum is signed 32bit. */
} FMOD_STUDIO_LOAD_MEMORY_MODE;

/*
[DEFINE]
[
    [NAME]
    FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT

    [DESCRIPTION]
    The required alignment of the buffer for Studio::System::loadBankMemory when using FMOD_STUDIO_LOAD_MEMORY_POINT.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::loadBankMemory
    FMOD_STUDIO_LOAD_MEMORY_MODE
]
*/
#define FMOD_STUDIO_LOAD_MEMORY_ALIGNMENT 32
/* [DEFINE_END] */

/*
[ENUM]
[
    [DESCRIPTION]
    Describes the type of a parameter.

    [REMARKS]
    There are two primary types of parameters: game controlled and automatic.
    Game controlled parameters receive their value from the API using
    Studio::EventInstance::setParameterValue. Automatic parameters are updated inside
    FMOD based on the positional information of the event and listener.

    **Horizontal angle** means the angle between vectors projected onto the
    listener's XZ plane (for the EVENT_ORIENTATION and DIRECTION parameters)
    or the global XZ plane (for the LISTENER_ORIENTATION parameter).

    [SEE_ALSO]
    FMOD_STUDIO_PARAMETER_DESCRIPTION
    Studio::EventInstance::setParameterValue
    Studio::EventInstance::set3DAttributes
    Studio::System::setListenerAttributes
]
*/
typedef enum FMOD_STUDIO_PARAMETER_TYPE
{
    FMOD_STUDIO_PARAMETER_GAME_CONTROLLED,                  /* Controlled via the API using Studio::EventInstance::setParameterValue. */
    FMOD_STUDIO_PARAMETER_AUTOMATIC_DISTANCE,               /* Distance between the event and the listener. */
    FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_CONE_ANGLE,       /* Angle between the event's forward vector and the vector pointing from the event to the listener (0 to 180 degrees). */
    FMOD_STUDIO_PARAMETER_AUTOMATIC_EVENT_ORIENTATION,      /* Horizontal angle between the event's forward vector and listener's forward vector (-180 to 180 degrees). */
    FMOD_STUDIO_PARAMETER_AUTOMATIC_DIRECTION,              /* Horizontal angle between the listener's forward vector and the vector pointing from the listener to the event (-180 to 180 degrees). */
    FMOD_STUDIO_PARAMETER_AUTOMATIC_ELEVATION,              /* Angle between the listener's XZ plane and the vector pointing from the listener to the event (-90 to 90 degrees). */
    FMOD_STUDIO_PARAMETER_AUTOMATIC_LISTENER_ORIENTATION,   /* Horizontal angle between the listener's forward vector and the global positive Z axis (-180 to 180 degrees). */

    FMOD_STUDIO_PARAMETER_MAX,                              /* Maximum number of parameter types supported. */
    FMOD_STUDIO_PARAMETER_FORCEINT = 65536                  /* Makes sure this enum is signed 32bit. */
} FMOD_STUDIO_PARAMETER_TYPE;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Information for loading a bank with Studio::System::loadBankCustom.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::loadBankCustom
]
*/
typedef struct FMOD_STUDIO_BANK_INFO
{
    int                      size;                  /* The size of this struct (for binary compatibility) */
    void                    *userdata;              /* User data to be passed to the file callbacks */
    int                      userdatalength;        /* If this is non-zero, userdata will be copied internally */
    FMOD_FILE_OPEN_CALLBACK  opencallback;          /* Callback for opening this file. */
    FMOD_FILE_CLOSE_CALLBACK closecallback;         /* Callback for closing this file. */
    FMOD_FILE_READ_CALLBACK  readcallback;          /* Callback for reading from this file. */
    FMOD_FILE_SEEK_CALLBACK  seekcallback;          /* Callback for seeking within this file. */
} FMOD_STUDIO_BANK_INFO;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure describing an event parameter.

    [REMARKS]

    [SEE_ALSO]
    Studio::EventDescription::getParameter
    FMOD_STUDIO_PARAMETER_TYPE
]
*/
typedef struct FMOD_STUDIO_PARAMETER_DESCRIPTION
{
    const char                 *name;               /* Name of the parameter. */
    int                         index;              /* Index of parameter */
    float                       minimum;            /* Minimum parameter value. */
    float                       maximum;            /* Maximum parameter value. */
    float                       defaultvalue;       /* Default value */
    FMOD_STUDIO_PARAMETER_TYPE  type;               /* Type of the parameter */
} FMOD_STUDIO_PARAMETER_DESCRIPTION;

/*
[ENUM]
[
    [DESCRIPTION]
    These definitions describe a user property's type.

    [REMARKS]

    [SEE_ALSO]
    FMOD_STUDIO_USER_PROPERTY
]
*/
typedef enum FMOD_STUDIO_USER_PROPERTY_TYPE
{
    FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER,         /* Integer property */
    FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN,         /* Boolean property */
    FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT,           /* Float property */
    FMOD_STUDIO_USER_PROPERTY_TYPE_STRING,          /* String property */

    FMOD_STUDIO_USER_PROPERTY_TYPE_FORCEINT = 65536 /* Makes sure this enum is signed 32bit. */
} FMOD_STUDIO_USER_PROPERTY_TYPE;

/*
[ENUM]
[
    [DESCRIPTION]
    These definitions describe built-in event properties.

    [REMARKS]
    For FMOD_STUDIO_EVENT_PROPERTY_CHANNELPRIORITY, a value of -1 uses the priority
    set in FMOD Studio, while other values override it. This property uses the same
    system as Channel::setPriority; this means lower values are higher priority
    (i.e. 0 is the highest priority while 256 is the lowest).

    [SEE_ALSO]
    Studio::EventInstance::getProperty
    Studio::EventInstance::setProperty
]
*/
typedef enum FMOD_STUDIO_EVENT_PROPERTY
{
    FMOD_STUDIO_EVENT_PROPERTY_CHANNELPRIORITY,     /* Priority to set on low-level channels created by this event instance (-1 to 256). */
    FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_DELAY,      /* Schedule delay to synchronized playback for multiple tracks in DSP clocks, or -1 for default. */
    FMOD_STUDIO_EVENT_PROPERTY_SCHEDULE_LOOKAHEAD,  /* Schedule look-ahead on the timeline in DSP clocks, or -1 for default. */
    FMOD_STUDIO_EVENT_PROPERTY_MINIMUM_DISTANCE,    /* Override the event's 3D minimum distance, or -1 for default. */
    FMOD_STUDIO_EVENT_PROPERTY_MAXIMUM_DISTANCE,    /* Override the event's 3D maximum distance, or -1 for default. */
    FMOD_STUDIO_EVENT_PROPERTY_MAX,                 /* Maximum number of event properties supported. */

    FMOD_STUDIO_EVENT_PROPERTY_FORCEINT = 65536     /* Makes sure this enum is signed 32bit. */
} FMOD_STUDIO_EVENT_PROPERTY;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure describing a user property.

    [REMARKS]

    [SEE_ALSO]
    Studio::EventDescription::getUserProperty
]
*/
typedef struct FMOD_STUDIO_USER_PROPERTY
{
    const char                     *name;           /* Name of the user property. */
    FMOD_STUDIO_USER_PROPERTY_TYPE  type;           /* Type of the user property. Use this to select one of the following values. */

    union
    {
        int                         intvalue;       /* Value of the user property. Only valid when type is FMOD_STUDIO_USER_PROPERTY_TYPE_INTEGER. */
        FMOD_BOOL                   boolvalue;      /* Value of the user property. Only valid when type is FMOD_STUDIO_USER_PROPERTY_TYPE_BOOLEAN. */
        float                       floatvalue;     /* Value of the user property. Only valid when type is FMOD_STUDIO_USER_PROPERTY_TYPE_FLOAT. */
        const char                 *stringvalue;    /* Value of the user property. Only valid when type is FMOD_STUDIO_USER_PROPERTY_TYPE_STRING. */
    };
} FMOD_STUDIO_USER_PROPERTY;

/*
[DEFINE]
[
    [NAME]
    FMOD_STUDIO_SYSTEM_CALLBACK_TYPE

    [DESCRIPTION]
    These callback types are used with Studio::System::setCallback.

    [REMARKS]

    [SEE_ALSO]
    FMOD_STUDIO_SYSTEM_CALLBACK
    Studio::System::setCallback
]
*/
#define FMOD_STUDIO_SYSTEM_CALLBACK_PREUPDATE       0x00000001  /* Called at the start of the main Studio update.  For async mode this will be on its own thread. */
#define FMOD_STUDIO_SYSTEM_CALLBACK_POSTUPDATE      0x00000002  /* Called at the end of the main Studio update.  For async mode this will be on its own thread. */
#define FMOD_STUDIO_SYSTEM_CALLBACK_BANK_UNLOAD     0x00000004  /* Called when bank has just been unloaded, after all resources are freed. CommandData will be the bank handle.*/
#define FMOD_STUDIO_SYSTEM_CALLBACK_ALL             0xFFFFFFFF  /* Pass this mask to Studio::System::setCallback to receive all callback types. */
/* [DEFINE_END] */

typedef unsigned int FMOD_STUDIO_SYSTEM_CALLBACK_TYPE;

/*
[DEFINE]
[
    [NAME]
    FMOD_STUDIO_EVENT_CALLBACK_TYPE

    [DESCRIPTION]
    These callback types are used with FMOD_STUDIO_EVENT_CALLBACK.

    [REMARKS]
    The data passed to the event callback function in the *parameters* argument varies based on the callback type.

    FMOD_STUDIO_EVENT_CALLBACK_STARTING is called when:

     * Studio::EventInstance::start has been called on an event which was not already playing.  The event will
       remain in this state until its sample data has been loaded.  If the event could not be started due to
       polyphony, then FMOD_STUDIO_EVENT_CALLBACK_START_FAILED will be called instead.

    FMOD_STUDIO_EVENT_CALLBACK_STARTED is called when:

     * The event has commenced playing.  Normally this callback will be issued immediately
       after FMOD_STUDIO_EVENT_CALLBACK_STARTING, but may be delayed until sample data has loaded.

    FMOD_STUDIO_EVENT_CALLBACK_RESTARTED is called when:

     * Studio::EventInstance::start has been called on an event which was already playing.

    FMOD_STUDIO_EVENT_CALLBACK_STOPPED is called when:

     * The event has stopped due to Studio::EventInstance::stop being called with FMOD_STUDIO_STOP_IMMEDIATE.
     * The event has finished fading out after Studio::EventInstance::stop was called with FMOD_STUDIO_STOP_ALLOWFADEOUT.
     * The event has stopped naturally by reaching the end of the timeline, and no further sounds can be triggered due to
       parameter changes.

    FMOD_STUDIO_EVENT_CALLBACK_START_FAILED is called when:

     * Studio::EventInstance::start has been called but the polyphony settings did not allow the event to start.  In
       this case none of FMOD_STUDIO_EVENT_CALLBACK_STARTING, FMOD_STUDIO_EVENT_CALLBACK_STARTED and FMOD_STUDIO_EVENT_CALLBACK_STOPPED
       will not be called.

    FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND is called when:

    * A programmer sound is about to play. FMOD expects the callback to provide an FMOD::Sound object for it to use.

    FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND is called when:

    * A programmer sound has stopped playing. At this point it is safe to release the FMOD::Sound object that was used.

    [SEE_ALSO]
    Studio::EventDescription::setCallback
    Studio::EventInstance::setCallback
    FMOD_STUDIO_EVENT_CALLBACK
]
*/
#define FMOD_STUDIO_EVENT_CALLBACK_CREATED                  0x00000001  /* Called when an instance is fully created. Parameters = unused. */
#define FMOD_STUDIO_EVENT_CALLBACK_DESTROYED                0x00000002  /* Called when an instance is just about to be destroyed. Parameters = unused. */
#define FMOD_STUDIO_EVENT_CALLBACK_STARTING                 0x00000004  /* Called when an instance is preparing to start. Parameters = unused. */
#define FMOD_STUDIO_EVENT_CALLBACK_STARTED                  0x00000008  /* Called when an instance starts playing. Parameters = unused. */
#define FMOD_STUDIO_EVENT_CALLBACK_RESTARTED                0x00000010  /* Called when an instance is restarted. Parameters = unused. */
#define FMOD_STUDIO_EVENT_CALLBACK_STOPPED                  0x00000020  /* Called when an instance stops. Parameters = unused. */
#define FMOD_STUDIO_EVENT_CALLBACK_START_FAILED             0x00000040  /* Called when an instance did not start, e.g. due to polyphony. Parameters = unused. */
#define FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND  0x00000080  /* Called when a programmer sound needs to be created in order to play a programmer instrument. Parameters = FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES. */
#define FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND 0x00000100  /* Called when a programmer sound needs to be destroyed. Parameters = FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES. */
#define FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED           0x00000200  /* Called when a DSP plugin instance has just been created. Parameters = FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES. */
#define FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED         0x00000400  /* Called when a DSP plugin instance is about to be destroyed. Parameters = FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES. */
#define FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER          0x00000800  /* Called when the timeline passes a named marker.  Parameters = FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES. */
#define FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT            0x00001000  /* Called when the timeline hits a beat in a tempo section.  Parameters = FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES. */
#define FMOD_STUDIO_EVENT_CALLBACK_SOUND_PLAYED             0x00002000  /* Called when the event plays a sound.  Parameters = FMOD::Sound. */
#define FMOD_STUDIO_EVENT_CALLBACK_SOUND_STOPPED            0x00004000  /* Called when the event finishes playing a sound.  Parameters = FMOD::Sound. */
#define FMOD_STUDIO_EVENT_CALLBACK_ALL                      0xFFFFFFFF  /* Pass this mask to Studio::EventDescription::setCallback or Studio::EventInstance::setCallback to receive all callback types. */
/* [DEFINE_END] */

typedef unsigned int FMOD_STUDIO_EVENT_CALLBACK_TYPE;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    This structure holds information about a programmer sound.

    [REMARKS]
    This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_CREATE_PROGRAMMER_SOUND
    or FMOD_STUDIO_EVENT_CALLBACK_DESTROY_PROGRAMMER_SOUND.

    The provided sound should be created with the FMOD_LOOP_NORMAL mode bit set. FMOD will set this bit internally if
    it is not set, possibly incurring a slight performance penalty.

    To support non-blocking loading of FSB subsounds, you can specify the subsound you want to use by setting the
    subsoundIndex field. This will cause FMOD to wait until the provided sound is ready and then get the specified
    subsound from it.

    [SEE_ALSO]
    FMOD_STUDIO_EVENT_CALLBACK
    FMOD_STUDIO_SOUND_INFO
    Studio::EventDescription::setCallback
    Studio::EventInstance::setCallback
    Studio::System::getSoundInfo
]
*/
typedef struct FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES
{
    const char  *name;                              /* The name of the programmer instrument (set in FMOD Studio). */
    FMOD_SOUND  *sound;                             /* The programmer-created sound. This should be filled in by the create callback, and cleaned up by the destroy callback. The provided sound should be created with the FMOD_LOOP_NORMAL mode bit set. This can be cast to/from FMOD::Sound* type. */
    int          subsoundIndex;                     /* The index of the subsound to use. This should be filled in by the create callback, or set to -1 if the provided sound should be used directly. Defaults to -1. */
} FMOD_STUDIO_PROGRAMMER_SOUND_PROPERTIES;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    This structure holds information about a DSP plugin instance.

    [REMARKS]
    This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_CREATED
    or FMOD_STUDIO_EVENT_CALLBACK_PLUGIN_DESTROYED.

    [SEE_ALSO]
    FMOD_STUDIO_EVENT_CALLBACK
    Studio::EventDescription::setCallback
    Studio::EventInstance::setCallback
]
*/
typedef struct FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES
{
    const char *name;                           /* The name of the plugin effect or sound (set in FMOD Studio). */
    FMOD_DSP   *dsp;                            /* The DSP plugin instance. This can be cast to FMOD::DSP* type. */
} FMOD_STUDIO_PLUGIN_INSTANCE_PROPERTIES;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    This structure holds information about a marker on the timeline.

    [REMARKS]
    This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER.

    [SEE_ALSO]
    FMOD_STUDIO_EVENT_CALLBACK
    Studio::EventDescription::setCallback
    Studio::EventInstance::setCallback
]
*/
typedef struct FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES
{
    const char *name;                           /* The marker name */
    int         position;                       /* The position of the marker on the timeline in milliseconds. */
} FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    This structure holds information about a beat on the timeline.

    [REMARKS]
    This data is passed to the event callback function when type is FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT.

    [SEE_ALSO]
    FMOD_STUDIO_EVENT_CALLBACK
    Studio::EventDescription::setCallback
    Studio::EventInstance::setCallback
]
*/
typedef struct FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES
{
    int     bar;                                /* The bar number (starting from 1). */
    int     beat;                               /* The beat number within the bar (starting from 1). */
    int     position;                           /* The position of the beat on the timeline in milliseconds. */
    float   tempo;                              /* The current tempo in beats per minute. */
    int     timesignatureupper;                 /* The current time signature upper number (beats per bar). */
    int     timesignaturelower;                 /* The current time signature lower number (beat unit). */
} FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES;

/*
[ENUM]
[
    [DESCRIPTION]
    These values describe the playback state of an event instance.

    [REMARKS]

    [SEE_ALSO]
    Studio::EventInstance::getPlaybackState
    Studio::EventInstance::start
    Studio::EventInstance::stop
    FMOD_STUDIO_EVENT_CALLBACK_TYPE
]
*/
typedef enum FMOD_STUDIO_PLAYBACK_STATE
{
    FMOD_STUDIO_PLAYBACK_PLAYING,               /* Currently playing. */
    FMOD_STUDIO_PLAYBACK_SUSTAINING,            /* The timeline cursor is paused on a sustain point. */
    FMOD_STUDIO_PLAYBACK_STOPPED,               /* Not playing. */
    FMOD_STUDIO_PLAYBACK_STARTING,              /* Start has been called but the instance is not fully started yet. */
    FMOD_STUDIO_PLAYBACK_STOPPING,              /* Stop has been called but the instance is not fully stopped yet. */

    FMOD_STUDIO_PLAYBACK_FORCEINT = 65536       /* Makes sure this enum is signed 32bit. */
} FMOD_STUDIO_PLAYBACK_STATE;

/*
[ENUM]
[
    [DESCRIPTION]
    Controls how to stop playback of an event instance.

    [REMARKS]

    [SEE_ALSO]
    Studio::EventInstance::stop
    Studio::Bus::stopAllEvents
]
*/
typedef enum FMOD_STUDIO_STOP_MODE
{
    FMOD_STUDIO_STOP_ALLOWFADEOUT,              /* Allows AHDSR modulators to complete their release, and DSP effect tails to play out. */
    FMOD_STUDIO_STOP_IMMEDIATE,                 /* Stops the event instance immediately. */

    FMOD_STUDIO_STOP_FORCEINT = 65536           /* Makes sure this enum is signed 32bit. */
} FMOD_STUDIO_STOP_MODE;

/*
[DEFINE]
[
    [NAME]
    FMOD_STUDIO_LOAD_BANK_FLAGS

    [DESCRIPTION]
    Flags passed into Studio loadBank commands to control bank load behaviour.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::loadBankFile
    Studio::System::loadBankMemory
    Studio::System::loadBankCustom
]
*/
#define FMOD_STUDIO_LOAD_BANK_NORMAL                0x00000000         /* Standard behaviour. */
#define FMOD_STUDIO_LOAD_BANK_NONBLOCKING           0x00000001         /* Bank loading occurs asynchronously rather than occurring immediately. */
#define FMOD_STUDIO_LOAD_BANK_DECOMPRESS_SAMPLES    0x00000002         /* Force samples to decompress into memory when they are loaded, rather than staying compressed. */
/* [DEFINE_END] */

typedef unsigned int FMOD_STUDIO_LOAD_BANK_FLAGS;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Settings for advanced features like configuring memory and cpu usage.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.<br>
    Members marked with [w] mean the variable can be written to.  The user can set the value.<br>
    Members marked with [r/w] are either read or write depending on if you are using System::setAdvancedSettings (w) or System::getAdvancedSettings (r).

    [SEE_ALSO]
    Studio::System::setAdvancedSettings
    Studio::System::getAdvancedSettings
    FMOD_MODE
]
*/
typedef struct FMOD_STUDIO_ADVANCEDSETTINGS
{
    int             cbsize;                     /* [w]   Size of this structure.  Use sizeof(FMOD_STUDIO_ADVANCEDSETTINGS)  NOTE: This must be set before calling Studio::System::getAdvancedSettings or Studio::System::setAdvancedSettings! */
    unsigned int    commandqueuesize;           /* [r/w] Optional. Specify 0 to ignore. Specify the command queue size for studio async processing.  Default 32kB. */
    unsigned int    handleinitialsize;          /* [r/w] Optional. Specify 0 to ignore. Specify the initial size to allocate for handles.  Memory for handles will grow as needed in pages. Default 8192 * sizeof(void*) */
    int             studioupdateperiod;         /* [r/w] Optional. Specify 0 to ignore. Specify the update period of Studio when in async mode, in milliseconds.  Will be quantised to the nearest multiple of mixer duration.  Default is 20ms. */
    int             idlesampledatapoolsize;     /* [r/w] Optional. Specify 0 to ignore. Specify the amount of sample data to keep in memory when no longer used, to avoid repeated disk IO.  Use -1 to disable.  Default is 256kB. */
} FMOD_STUDIO_ADVANCEDSETTINGS;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Performance information for FMOD Studio and low level systems.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::getCPUUsage
]
*/
typedef struct FMOD_STUDIO_CPU_USAGE
{
    float           dspusage;                   /* Returns the % CPU time taken by DSP processing on the low level mixer thread. */
    float           streamusage;                /* Returns the % CPU time taken by stream processing on the low level stream thread. */
    float           geometryusage;              /* Returns the % CPU time taken by geometry processing on the low level geometry thread. */
    float           updateusage;                /* Returns the % CPU time taken by low level update, called as part of the studio update. */
    float           studiousage;                /* Returns the % CPU time taken by studio update, called from the studio thread. Does not include low level update time. */
} FMOD_STUDIO_CPU_USAGE;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Information for a single buffer in FMOD Studio.

    [REMARKS]

    [SEE_ALSO]
    FMOD_STUDIO_BUFFER_USAGE
]
*/
typedef struct FMOD_STUDIO_BUFFER_INFO
{
    int             currentusage;               /* Current buffer usage in bytes. */
    int             peakusage;                  /* Peak buffer usage in bytes. */
    int             capacity;                   /* Buffer capacity in bytes. */
    int             stallcount;                 /* Cumulative number of stalls due to buffer overflow. */
    float           stalltime;                  /* Cumulative amount of time stalled due to buffer overflow, in seconds. */
} FMOD_STUDIO_BUFFER_INFO;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Information for FMOD Studio buffer usage.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::getBufferUsage
    Studio::System::resetBufferUsage
    FMOD_STUDIO_BUFFER_INFO
]
*/
typedef struct FMOD_STUDIO_BUFFER_USAGE
{
    FMOD_STUDIO_BUFFER_INFO studiocommandqueue; /* Information for the Studio Async Command buffer, controlled by FMOD_STUDIO_ADVANCEDSETTINGS commandQueueSize. */
    FMOD_STUDIO_BUFFER_INFO studiohandle;       /* Information for the Studio handle table, controlled by FMOD_STUDIO_ADVANCEDSETTINGS handleInitialSize. */
} FMOD_STUDIO_BUFFER_USAGE;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Information for loading a sound from a sound table.

    [REMARKS]
    The name_or_data member points into FMOD internal memory, which will become
    invalid if the sound table bank is unloaded.

    If mode flags such as FMOD_CREATESTREAM, FMOD_CREATECOMPRESSEDSAMPLE or FMOD_NONBLOCKING are required,
    it is up to the user to OR them together when calling System::createSound.

    [SEE_ALSO]
    Studio::System::getSoundInfo
    System::createSound
]
*/
typedef struct FMOD_STUDIO_SOUND_INFO
{
    const char             *name_or_data;       /* The filename or memory buffer that contains the sound. */
    FMOD_MODE               mode;               /* Mode flags required for loading the sound. */
    FMOD_CREATESOUNDEXINFO  exinfo;             /* Extra information required for loading the sound. */
    int                     subsoundindex;      /* Subsound index for loading the sound. */
} FMOD_STUDIO_SOUND_INFO;

/*
[DEFINE]
[
    [NAME]
    FMOD_STUDIO_COMMANDCAPTURE_FLAGS

    [DESCRIPTION]
    Flags passed into Studio::System::startCommandCapture.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::startCommandCapture
]
*/
#define FMOD_STUDIO_COMMANDCAPTURE_NORMAL                      0x00000000       /* Standard behaviour. */
#define FMOD_STUDIO_COMMANDCAPTURE_FILEFLUSH                   0x00000001       /* Call file flush on every command. */
#define FMOD_STUDIO_COMMANDCAPTURE_SKIP_INITIAL_STATE          0x00000002       /* Normally the initial state of banks and instances is captured, unless this flag is set. */
/* [DEFINE_END] */

typedef unsigned int FMOD_STUDIO_COMMANDCAPTURE_FLAGS;

/*
[DEFINE]
[
    [NAME]
    FMOD_STUDIO_COMMANDREPLAY_FLAGS

    [DESCRIPTION]
    Flags passed into Studio::System::loadCommandReplay.

    [REMARKS]

    [SEE_ALSO]
    Studio::System::loadCommandReplay
]
*/
#define FMOD_STUDIO_COMMANDREPLAY_NORMAL               0x00000000       /* Standard behaviour. */
#define FMOD_STUDIO_COMMANDREPLAY_SKIP_CLEANUP         0x00000001       /* Normally the playback will release any created resources when it stops, unless this flag is set. */
#define FMOD_STUDIO_COMMANDREPLAY_FAST_FORWARD         0x00000002       /* Play back at maximum speed, ignoring the timing of the original replay. */
/* [DEFINE_END] */

typedef unsigned int FMOD_STUDIO_COMMANDREPLAY_FLAGS;

/*
[ENUM]
[
    [DESCRIPTION]
    Used to distinguish the types used in command replays.

    [REMARKS]

    [SEE_ALSO]
]
*/
typedef enum FMOD_STUDIO_INSTANCETYPE
{
    FMOD_STUDIO_INSTANCETYPE_NONE,
    FMOD_STUDIO_INSTANCETYPE_SYSTEM,
    FMOD_STUDIO_INSTANCETYPE_EVENTDESCRIPTION,
    FMOD_STUDIO_INSTANCETYPE_EVENTINSTANCE,
    FMOD_STUDIO_INSTANCETYPE_PARAMETERINSTANCE,
    FMOD_STUDIO_INSTANCETYPE_BUS,
    FMOD_STUDIO_INSTANCETYPE_VCA,
    FMOD_STUDIO_INSTANCETYPE_BANK,
    FMOD_STUDIO_INSTANCETYPE_COMMANDREPLAY,

    FMOD_STUDIO_INSTANCETYPE_FORCEINT = 65536    /* Makes sure this enum is signed 32bit. */
} FMOD_STUDIO_INSTANCETYPE;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Information about a single command in a command replay file.

    [REMARKS]
    This information has metadata about the command at the given index.  Note that the handle fields are
    from the recorded session, and will no longer correspond to any actual object type in the current
    system.

    [SEE_ALSO]
    Studio::CommandReplay::getCommandInfo
]
*/
typedef struct FMOD_STUDIO_COMMAND_INFO
{
    const char                 *commandname;        /* The full name of the API function for this command. */
    int                         parentcommandindex; /* For commands that operate on an instance, this is the command that created the instance. */
    int                         framenumber;        /* The frame the command belongs to. */
    float                       frametime;          /* The playback time at which this command will be executed. */
    FMOD_STUDIO_INSTANCETYPE    instancetype;       /* The type of object that this command uses as an instance. */
    FMOD_STUDIO_INSTANCETYPE    outputtype;         /* The type of object that this command outputs, if any. */
    unsigned int                instancehandle;     /* The original handle value of the instance.  This will no longer correspond to any actual object in playback. */
    unsigned int                outputhandle;       /* The original handle value of the command output.  This will no longer correspond to any actual object in playback. */
} FMOD_STUDIO_COMMAND_INFO;

/*
    FMOD Studio callbacks.
*/
typedef FMOD_RESULT (F_CALLBACK *FMOD_STUDIO_SYSTEM_CALLBACK)                           (FMOD_STUDIO_SYSTEM *system, FMOD_STUDIO_SYSTEM_CALLBACK_TYPE type, void *commanddata, void *userdata);
typedef FMOD_RESULT (F_CALLBACK *FMOD_STUDIO_EVENT_CALLBACK)                            (FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE *event, void *parameters);
typedef FMOD_RESULT (F_CALLBACK *FMOD_STUDIO_COMMANDREPLAY_FRAME_CALLBACK)              (FMOD_STUDIO_COMMANDREPLAY *replay, int commandIndex, float currentTime, void *userdata);
typedef FMOD_RESULT (F_CALLBACK *FMOD_STUDIO_COMMANDREPLAY_LOAD_BANK_CALLBACK)          (FMOD_STUDIO_COMMANDREPLAY *replay, int commandIndex, const FMOD_GUID *bankGuid, const char *bankFilename, FMOD_STUDIO_LOAD_BANK_FLAGS flags, FMOD_STUDIO_BANK **bank, void *userdata);
typedef FMOD_RESULT (F_CALLBACK *FMOD_STUDIO_COMMANDREPLAY_CREATE_INSTANCE_CALLBACK)    (FMOD_STUDIO_COMMANDREPLAY *replay, int commandIndex, FMOD_STUDIO_EVENTDESCRIPTION *eventDescription, FMOD_STUDIO_EVENTINSTANCE **instance, void *userdata);

#endif // FMOD_STUDIO_COMMON_H


text:
/* ======================================================================================================== */
/* FMOD Studio - codec development header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2017.  */
/*                                                                                */
/* Use this header if you are wanting to develop your own file format plugin to use with                    */
/* FMOD's codec system.  With this header you can make your own fileformat plugin that FMOD                 */
/* can register and use.  See the documentation and examples on how to make a working plugin.               */
/*                                                                                */
/* ======================================================================================================== */

#ifndef _FMOD_CODEC_H
#define _FMOD_CODEC_H

typedef struct FMOD_CODEC_STATE FMOD_CODEC_STATE;
typedef struct FMOD_CODEC_WAVEFORMAT FMOD_CODEC_WAVEFORMAT;

/*
    Codec callbacks
*/
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_OPEN_CALLBACK)         (FMOD_CODEC_STATE *codec_state, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_CLOSE_CALLBACK)        (FMOD_CODEC_STATE *codec_state);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_READ_CALLBACK)         (FMOD_CODEC_STATE *codec_state, void *buffer, unsigned int samples_in, unsigned int *samples_out);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETLENGTH_CALLBACK)    (FMOD_CODEC_STATE *codec_state, unsigned int *length, FMOD_TIMEUNIT lengthtype);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_SETPOSITION_CALLBACK)  (FMOD_CODEC_STATE *codec_state, int subsound, unsigned int position, FMOD_TIMEUNIT postype);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETPOSITION_CALLBACK)  (FMOD_CODEC_STATE *codec_state, unsigned int *position, FMOD_TIMEUNIT postype);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_SOUNDCREATE_CALLBACK)  (FMOD_CODEC_STATE *codec_state, int subsound, FMOD_SOUND *sound);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_METADATA_CALLBACK)     (FMOD_CODEC_STATE *codec_state, FMOD_TAGTYPE tagtype, char *name, void *data, unsigned int datalen, FMOD_TAGDATATYPE datatype, int unique);
typedef FMOD_RESULT (F_CALLBACK *FMOD_CODEC_GETWAVEFORMAT_CALLBACK)(FMOD_CODEC_STATE *codec_state, int index, FMOD_CODEC_WAVEFORMAT *waveformat);

/*
[STRUCTURE]
[
    [DESCRIPTION]
    When creating a codec, declare one of these and provide the relevant callbacks and name for FMOD to use when it opens and reads a file.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_CODEC_STATE
    FMOD_CODEC_WAVEFORMAT
]
*/
typedef struct FMOD_CODEC_DESCRIPTION
{
    const char                       *name;            /* [w] Name of the codec. */
    unsigned int                      version;         /* [w] Plugin writer's version number. */
    int                               defaultasstream; /* [w] Tells FMOD to open the file as a stream when calling System::createSound, and not a static sample.  Should normally be 0 (FALSE), because generally the user wants to decode the file into memory when using System::createSound.   Mainly used for formats that decode for a very long time, or could use large amounts of memory when decoded.  Usually sequenced formats such as mod/s3m/xm/it/midi fall into this category.   It is mainly to stop users that don't know what they're doing from getting FMOD_ERR_MEMORY returned from createSound when they should have in fact called System::createStream or used FMOD_CREATESTREAM in System::createSound. */
    FMOD_TIMEUNIT                     timeunits;       /* [w] When setposition codec is called, only these time formats will be passed to the codec. Use bitwise OR to accumulate different types. */
    FMOD_CODEC_OPEN_CALLBACK          open;            /* [w] Open callback for the codec for when FMOD tries to open a sound using this codec. */
    FMOD_CODEC_CLOSE_CALLBACK         close;           /* [w] Close callback for the codec for when FMOD tries to close a sound using this codec.  */
    FMOD_CODEC_READ_CALLBACK          read;            /* [w] Read callback for the codec for when FMOD tries to read some data from the file to the destination format (specified in the open callback). */
    FMOD_CODEC_GETLENGTH_CALLBACK     getlength;       /* [w] Callback to return the length of the song in whatever format required when Sound::getLength is called. */
    FMOD_CODEC_SETPOSITION_CALLBACK   setposition;     /* [w] Seek callback for the codec for when FMOD tries to seek within the file with Channel::setPosition. */
    FMOD_CODEC_GETPOSITION_CALLBACK   getposition;     /* [w] Tell callback for the codec for when FMOD tries to get the current position within the with Channel::getPosition. */
    FMOD_CODEC_SOUNDCREATE_CALLBACK   soundcreate;     /* [w] Sound creation callback for the codec when FMOD finishes creating the sound.  (So the codec can set more parameters for the related created sound, ie loop points/mode or 3D attributes etc). */
    FMOD_CODEC_GETWAVEFORMAT_CALLBACK getwaveformat;   /* [w] Callback to tell FMOD about the waveformat of a particular subsound.  This is to save memory, rather than saving 1000 FMOD_CODEC_WAVEFORMAT structures in the codec, the codec might have a more optimal way of storing this information. */
} FMOD_CODEC_DESCRIPTION;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Set these values marked to tell fmod what sort of sound to create when the codec open callback is called.

    The format, channels, frequency and lengthpcm tell FMOD what sort of sound buffer to create when you initialize your code.

    If you wrote an MP3 codec that decoded to stereo 16bit integer PCM for a 44khz sound, you would specify FMOD_SOUND_FORMAT_PCM16, and channels would be equal to 2, and frequency would be 44100.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    1.07 Note.  'blockalign' member which was in bytes has been removed.   'pcmblocksize' is now the replacement, and is measured in PCM samples only, not bytes.  This is purely to support buffering
    internal to FMOD for codecs that are not sample accurate.

    Note: When registering a codec, format, channels, frequency and lengthpcm must be supplied, otherwise there will be an error.

    This structure is optional if FMOD_CODEC_GETWAVEFORMAT_CALLBACK is specified.

    An array of these structures may be needed if FMOD_CODEC_STATE::numsubsounds is larger than 1.

    [SEE_ALSO]
    FMOD_CODEC_STATE
    FMOD_SOUND_FORMAT
    FMOD_MODE
    FMOD_CHANNELMASK
    FMOD_CHANNELORDER
    FMOD_CODEC_WAVEFORMAT_VERSION
]
*/
struct FMOD_CODEC_WAVEFORMAT
{
    const char*        name;          /* [w] Name of sound.  Optional. If used, the codec must own the lifetime of the string memory until the codec is destroyed. */
    FMOD_SOUND_FORMAT  format;        /* [w] Format for (decompressed) codec output, ie FMOD_SOUND_FORMAT_PCM8, FMOD_SOUND_FORMAT_PCM16.  Mandantory - Must be supplied. */
    int                channels;      /* [w] Number of channels used by codec, ie mono = 1, stereo = 2.  Mandantory - Must be supplied.  */
    int                frequency;     /* [w] Default frequency in hz of the codec, ie 44100.  Mandantory - Must be supplied.  */
    unsigned int       lengthbytes;   /* [w] Length in bytes of the source data.  Used for FMOD_TIMEUNIT_RAWBYTES.  Optional. Default = 0. */
    unsigned int       lengthpcm;     /* [w] Length in decompressed, PCM samples of the file, ie length in seconds * frequency.  Used for Sound::getLength and for memory allocation of static decompressed sample data.  Mandantory - Must be supplied. */
    unsigned int       pcmblocksize;  /* [w] Minimum, optimal number of decompressed PCM samples codec can handle.  0 or 1 = no buffering.  Anything higher means FMOD will allocate a PCM buffer of this size to read in chunks.  The codec read callback will be called in multiples of this value.  Optional.  */
    int                loopstart;     /* [w] Loopstart in decompressed, PCM samples of file. Optional. Default = 0. */
    int                loopend;       /* [w] Loopend in decompressed, PCM samples of file. Optional. Default = 0. */
    FMOD_MODE          mode;          /* [w] Mode to determine whether the sound should by default load as looping, non looping, 2d or 3d.  Optional. Default = FMOD_DEFAULT. */
    FMOD_CHANNELMASK   channelmask;   /* [w] Defined channel bitmask to describe which speakers the channels in the codec map to, in order of channel count.  See fmod_common.h.  Optional. Leave at 0 to map to the speaker layout defined in FMOD_SPEAKER. */
    FMOD_CHANNELORDER  channelorder;  /* [w] Defined channel order type, to describe where each sound channel should pan for the number of channels specified.  See fmod_common.h.  Optional.  Leave at 0 to play in default speaker order. */
    float              peakvolume;    /* [w] Peak volume of sound. Optional. Default = 0 if not used. */
};

/*
[DEFINE]
[
    [NAME]
    FMOD_CODEC_WAVEFORMAT_VERSION

    [DESCRIPTION]
    Version number of FMOD_CODEC_WAVEFORMAT structure.  Should be set into FMOD_CODEC_STATE in the FMOD_CODEC_OPEN_CALLBACK.

    [REMARKS]
    Use this for binary compatibility and for future expansion.

    [SEE_ALSO]
    FMOD_CODEC_STATE
    FMOD_CODEC_DESCRIPTION
    FMOD_CODEC_OPEN_CALLBACK
]
*/
#define FMOD_CODEC_WAVEFORMAT_VERSION 3
/* [DEFINE_END] */

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Codec plugin structure that is passed into each callback.

    Optionally set the numsubsounds and waveformat members when called in FMOD_CODEC_OPEN_CALLBACK to tell fmod what sort of sound to create.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    'numsubsounds' should be 0 if the file is a normal single sound stream or sound.  Examples of this would be .WAV, .WMA, .MP3, .AIFF.

    'numsubsounds' should be 1+ if the file is a container format, and does not contain wav data itself.  Examples of these types would be FSB (contains multiple sounds), DLS (contain instruments).

    The waveformat value should point to an arrays of information based on how many subsounds are in the format.  If the number of subsounds is 0 then it should point to 1 waveformat, the same as if the number of subsounds was 1.  If subsounds was 100 for example, there should be a pointer to an array of 100 waveformat structures.

    The waveformat pointer is optional and could be 0, if using FMOD_CODEC_GETWAVEFORMAT_CALLBACK is preferred.

    When a sound has 1 or more subsounds, the caller must play the individual sounds specified by first obtaining the subsound with Sound::getSubSound.

    [SEE_ALSO]
    FMOD_CODEC_WAVEFORMAT
    FMOD_FILE_READ_CALLBACK
    FMOD_FILE_SEEK_CALLBACK
    FMOD_CODEC_METADATA_CALLBACK
    Sound::getSubSound
    Sound::getNumSubSounds
    FMOD_CODEC_WAVEFORMAT_VERSION
]
*/
struct FMOD_CODEC_STATE
{
    int                          numsubsounds;      /* [w] Number of 'subsounds' in this sound.  Anything other than 0 makes it a 'container' format (ie DLS/FSB etc which contain 1 or more subsounds).  For most normal, single sound codec such as WAV/AIFF/MP3, this should be 0 as they are not a container for subsounds, they are the sound by itself. */
    FMOD_CODEC_WAVEFORMAT       *waveformat;        /* [w] Pointer to an array of format structures containing information about each sample.  Can be 0 or NULL if FMOD_CODEC_GETWAVEFORMAT_CALLBACK callback is preferred.  The number of entries here must equal the number of subsounds defined in the subsound parameter. If numsubsounds = 0 then there should be 1 instance of this structure. */
    void                        *plugindata;        /* [w] Plugin writer created data the codec author wants to attach to this object. */

    void                        *filehandle;        /* [r] This will return an internal FMOD file handle to use with the callbacks provided.  */
    unsigned int                 filesize;          /* [r] This will contain the size of the file in bytes. */
    FMOD_FILE_READ_CALLBACK      fileread;          /* [r] This will return a callable FMOD file function to use from codec. */
    FMOD_FILE_SEEK_CALLBACK      fileseek;          /* [r] This will return a callable FMOD file function to use from codec.  */
    FMOD_CODEC_METADATA_CALLBACK metadata;          /* [r] This will return a callable FMOD metadata function to use from codec.  */

    int                          waveformatversion; /* [w] Must be set to FMOD_CODEC_WAVEFORMAT_VERSION in the FMOD_CODEC_OPEN_CALLBACK. */
};

#endif

repo_name: JoshParnell/libphx

repo_language: C

mime_type: text/x-c++


text:
/* ========================================================================================== */
/* FMOD Studio - DSP header file. Copyright (c), Firelight Technologies Pty, Ltd. 2004-2017.  */
/*                                                                                */
/* Use this header if you are interested in delving deeper into the FMOD software mixing /    */
/* DSP engine.                                                                                */
/* Also use this header if you are wanting to develop your own DSP plugin to use with FMOD's  */
/* dsp system.  With this header you can make your own DSP plugin that FMOD can               */
/* register and use.  See the documentation and examples on how to make a working plugin.     */
/*                                                                                */
/* ========================================================================================== */

#ifndef _FMOD_DSP_H
#define _FMOD_DSP_H

#include "fmod_dsp_effects.h"

typedef struct FMOD_DSP_STATE FMOD_DSP_STATE;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure for FMOD_DSP_PROCESS_CALLBACK input and output buffers.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_DSP_DESCRIPTION
]
*/
typedef struct FMOD_DSP_BUFFER_ARRAY
{
    int                numbuffers;              /* [r/w] number of buffers */
    int               *buffernumchannels;       /* [r/w] array of number of channels for each buffer */
    FMOD_CHANNELMASK  *bufferchannelmask;       /* [r/w] array of channel masks for each buffer */
    float            **buffers;                 /* [r/w] array of buffers */
    FMOD_SPEAKERMODE   speakermode;             /* [r/w] speaker mode for all buffers in the array */
} FMOD_DSP_BUFFER_ARRAY;

/*
[ENUM]
[
    [DESCRIPTION]
    Operation type for FMOD_DSP_PROCESS_CALLBACK.

    [REMARKS]
    A process callback will be called twice per mix for a DSP unit.  Once with the FMOD_DSP_PROCESS_QUERY command, then conditionally, FMOD_DSP_PROCESS_PERFORM.

    FMOD_DSP_PROCESS_QUERY is to be handled only by filling out the outputarray information, and returning a relevant return code.

    It should not really do any logic besides checking and returning one of the following codes:

    - FMOD_OK - Meaning yes, it should execute the dsp process function with FMOD_DSP_PROCESS_PERFORM

    - FMOD_ERR_DSP_DONTPROCESS - Meaning no, it should skip the process function and not call it with FMOD_DSP_PROCESS_PERFORM.

    - FMOD_ERR_DSP_SILENCE - Meaning no, it should skip the process function and not call it with FMOD_DSP_PROCESS_PERFORM, AND, tell the signal chain to follow that it is now idle, so that no more processing happens down the chain.

    If audio is to be processed, 'outbufferarray' must be filled with the expected output format, channel count and mask.  Mask can be 0.

    FMOD_DSP_PROCESS_PROCESS  is to be handled by reading the data from the input, processing it, and writing it to the output.  Always write to the output buffer and fill it fully to avoid unpredictable audio output.

    Always return FMOD_OK, the return value is ignored from the process stage.

    [SEE_ALSO]
    FMOD_DSP_DESCRIPTION
]
*/
typedef enum
{
    FMOD_DSP_PROCESS_PERFORM,                   /* Process the incoming audio in 'inbufferarray' and output to 'outbufferarray'. */
    FMOD_DSP_PROCESS_QUERY                      /* The DSP is being queried for the expected output format and whether it needs to process audio or should be bypassed.  The function should return FMOD_OK, or FMOD_ERR_DSP_DONTPROCESS or FMOD_ERR_DSP_SILENCE if audio can pass through unprocessed. See remarks for more.  If audio is to be processed, 'outbufferarray' must be filled with the expected output format, channel count and mask. */
} FMOD_DSP_PROCESS_OPERATION;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Complex number structure used for holding FFT frequency domain-data for FMOD_FFTREAL and FMOD_IFFTREAL DSP functions.

    [REMARKS]

    [SEE_ALSO]
    FMOD_DSP_STATE_FUNCTIONS
    FMOD_DSP_STATE_DFT_FUNCTIONS
]
*/
typedef struct FMOD_COMPLEX
{
    float real; /* Real component */
    float imag; /* Imaginary component */
} FMOD_COMPLEX;

/*
[ENUM]
[
    [DESCRIPTION]
    Flags for the FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC function.

    [REMARKS]
    This functionality is experimental, please contact support@fmod.org for more information.

    [SEE_ALSO]
    FMOD_DSP_STATE_PAN_FUNCTIONS
]
*/
typedef enum FMOD_DSP_PAN_SURROUND_FLAGS
{
    FMOD_DSP_PAN_SURROUND_DEFAULT = 0,
    FMOD_DSP_PAN_SURROUND_ROTATION_NOT_BIASED = 1,

    FMOD_DSP_PAN_SURROUND_FLAGS_FORCEINT = 65536     /* Makes sure this enum is signed 32bit. */
} FMOD_DSP_PAN_SURROUND_FLAGS;

/*
    FMOD_DSP_DESCRIPTION callbacks
*/
typedef FMOD_RESULT (F_CALL *FMOD_DSP_CREATE_CALLBACK)                    (FMOD_DSP_STATE *dsp_state);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_RELEASE_CALLBACK)                   (FMOD_DSP_STATE *dsp_state);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_RESET_CALLBACK)                     (FMOD_DSP_STATE *dsp_state);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_READ_CALLBACK)                      (FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_PROCESS_CALLBACK)                   (FMOD_DSP_STATE *dsp_state, unsigned int length, const FMOD_DSP_BUFFER_ARRAY *inbufferarray, FMOD_DSP_BUFFER_ARRAY *outbufferarray, FMOD_BOOL inputsidle, FMOD_DSP_PROCESS_OPERATION op);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPOSITION_CALLBACK)               (FMOD_DSP_STATE *dsp_state, unsigned int pos);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_SHOULDIPROCESS_CALLBACK)            (FMOD_DSP_STATE *dsp_state, FMOD_BOOL inputsidle, unsigned int length, FMOD_CHANNELMASK inmask, int inchannels, FMOD_SPEAKERMODE speakermode);

typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_FLOAT_CALLBACK)            (FMOD_DSP_STATE *dsp_state, int index, float value);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_INT_CALLBACK)              (FMOD_DSP_STATE *dsp_state, int index, int value);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_BOOL_CALLBACK)             (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL value);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_SETPARAM_DATA_CALLBACK)             (FMOD_DSP_STATE *dsp_state, int index, void *data, unsigned int length);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_FLOAT_CALLBACK)            (FMOD_DSP_STATE *dsp_state, int index, float *value, char *valuestr);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_INT_CALLBACK)              (FMOD_DSP_STATE *dsp_state, int index, int *value, char *valuestr);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_BOOL_CALLBACK)             (FMOD_DSP_STATE *dsp_state, int index, FMOD_BOOL *value, char *valuestr);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETPARAM_DATA_CALLBACK)             (FMOD_DSP_STATE *dsp_state, int index, void **data, unsigned int *length, char *valuestr);

typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_REGISTER_CALLBACK)           (FMOD_DSP_STATE *dsp_state);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK)         (FMOD_DSP_STATE *dsp_state);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_SYSTEM_MIX_CALLBACK)                (FMOD_DSP_STATE *dsp_state, int stage);

/*
    FMOD_DSP_STATE functions
*/
typedef void *      (F_CALL *FMOD_DSP_ALLOC_FUNC)                         (unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr);
typedef void *      (F_CALL *FMOD_DSP_REALLOC_FUNC)                       (void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr);
typedef void        (F_CALL *FMOD_DSP_FREE_FUNC)                          (void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr);
typedef void        (F_CALL *FMOD_DSP_LOG_FUNC)                           (FMOD_DEBUG_FLAGS level, const char *file, int line, const char *function, const char *string, ...);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETSAMPLERATE_FUNC)                 (FMOD_DSP_STATE *dsp_state, int *rate);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETBLOCKSIZE_FUNC)                  (FMOD_DSP_STATE *dsp_state, unsigned int *blocksize);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETSPEAKERMODE_FUNC)                (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE *speakermode_mixer, FMOD_SPEAKERMODE *speakermode_output);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETCLOCK_FUNC)                      (FMOD_DSP_STATE *dsp_state, unsigned long long *clock, unsigned int *offset, unsigned int *length);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETLISTENERATTRIBUTES_FUNC)         (FMOD_DSP_STATE *dsp_state, int *numlisteners, FMOD_3D_ATTRIBUTES *attributes);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_GETUSERDATA_FUNC)                   (FMOD_DSP_STATE *dsp_state, void **userdata);

typedef FMOD_RESULT (F_CALL *FMOD_DSP_DFT_FFTREAL_FUNC)                   (FMOD_DSP_STATE *dsp_state, int size, const float *signal, FMOD_COMPLEX* dft, const float *window, int signalhop);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_DFT_IFFTREAL_FUNC)                  (FMOD_DSP_STATE *dsp_state, int size, const FMOD_COMPLEX *dft, float* signal, const float *window, int signalhop);

typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMMONOMATRIX_FUNC)             (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, float lowFrequencyGain, float overallGain, float *matrix);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC)           (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, float pan, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC)         (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE sourceSpeakerMode, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix, FMOD_DSP_PAN_SURROUND_FLAGS flags);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC)   (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC) (FMOD_DSP_STATE *dsp_state, FMOD_SPEAKERMODE targetSpeakerMode, float direction, float extent, float rotation, float lowFrequencyGain, float overallGain, int matrixHop, float *matrix);
typedef FMOD_RESULT (F_CALL *FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC)            (FMOD_DSP_STATE *dsp_state, FMOD_DSP_PAN_3D_ROLLOFF_TYPE rolloff, float distance, float mindistance, float maxdistance, float *gain);

/*
[DEFINE]
[
    [NAME]
    FMOD_DSP_GETPARAM_VALUESTR_LENGTH

    [DESCRIPTION]
    Length in bytes of the buffer pointed to by the valuestr argument of FMOD_DSP_GETPARAM_XXXX_CALLBACK functions.

    [REMARKS]
    DSP plugins should not copy more than this number of bytes into the buffer or memory corruption will occur.

    [SEE_ALSO]
    FMOD_DSP_GETPARAM_FLOAT_CALLBACK
    FMOD_DSP_GETPARAM_INT_CALLBACK
    FMOD_DSP_GETPARAM_BOOL_CALLBACK
    FMOD_DSP_GETPARAM_DATA_CALLBACK
]
*/
#define FMOD_DSP_GETPARAM_VALUESTR_LENGTH 32
/* [DEFINE_END] */

/*
[ENUM]
[
    [DESCRIPTION]
    DSP parameter types.

    [REMARKS]

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_DESC
]
*/
typedef enum
{
    FMOD_DSP_PARAMETER_TYPE_FLOAT,              /* FMOD_DSP_PARAMETER_DESC will use the FMOD_DSP_PARAMETER_DESC_FLOAT. */
    FMOD_DSP_PARAMETER_TYPE_INT,                /* FMOD_DSP_PARAMETER_DESC will use the FMOD_DSP_PARAMETER_DESC_INT. */
    FMOD_DSP_PARAMETER_TYPE_BOOL,               /* FMOD_DSP_PARAMETER_DESC will use the FMOD_DSP_PARAMETER_DESC_BOOL. */
    FMOD_DSP_PARAMETER_TYPE_DATA,               /* FMOD_DSP_PARAMETER_DESC will use the FMOD_DSP_PARAMETER_DESC_DATA. */

    FMOD_DSP_PARAMETER_TYPE_MAX,                /* Maximum number of DSP parameter types. */
    FMOD_DSP_PARAMETER_TYPE_FORCEINT = 65536    /* Makes sure this enum is signed 32bit. */
} FMOD_DSP_PARAMETER_TYPE;

/*
[ENUM]
[
    [DESCRIPTION]
    DSP float parameter mappings. These determine how values are mapped across dials and automation curves.

    [REMARKS]
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO generates a mapping based on range and units. For example, if the units are in Hertz and the range is with-in the audio spectrum, a Bark scale will be chosen. Logarithmic scales may also be generated for ranges above zero spanning several orders of magnitude.

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_FLOAT_MAPPING
]
*/
typedef enum
{
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_LINEAR,               /* Values mapped linearly across range. */
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO,                 /* A mapping is automatically chosen based on range and units.  See remarks. */
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR,     /* Values mapped in a piecewise linear fashion defined by FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR. */

    FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_FORCEINT = 65536      /* Makes sure this enum is signed 32bit. */
} FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure to define a piecewise linear mapping.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE
    FMOD_DSP_PARAMETER_FLOAT_MAPPING
]
*/
typedef struct FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR
{
    int numpoints;                              /* [w] The number of <position, value> pairs in the piecewise mapping (at least 2). */
    float *pointparamvalues;                    /* [w] The values in the parameter's units for each point */
    float *pointpositions;                      /* [w] The positions along the control's scale (e.g. dial angle) corresponding to each parameter value.  The range of this scale is arbitrary and all positions will be relative to the minimum and maximum values (e.g. [0,1,3] is equivalent to [1,2,4] and [2,4,8]).  If this array is zero, pointparamvalues will be distributed with equal spacing. */
} FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure to define a mapping for a DSP unit's float parameter.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR
    FMOD_DSP_PARAMETER_DESC_FLOAT
]
*/
typedef struct FMOD_DSP_PARAMETER_FLOAT_MAPPING
{
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE type;
    FMOD_DSP_PARAMETER_FLOAT_MAPPING_PIECEWISE_LINEAR piecewiselinearmapping; /* [w] Only required for FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR type mapping. */
} FMOD_DSP_PARAMETER_FLOAT_MAPPING;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure to define a float parameter for a DSP unit.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    System::createDSP
    DSP::setParameterFloat
    DSP::getParameterFloat
    FMOD_DSP_PARAMETER_DESC
    FMOD_DSP_PARAMETER_FLOAT_MAPPING
]
*/
typedef struct FMOD_DSP_PARAMETER_DESC_FLOAT
{
    float                     min;                      /* [w] Minimum parameter value. */
    float                     max;                      /* [w] Maximum parameter value. */
    float                     defaultval;               /* [w] Default parameter value. */
    FMOD_DSP_PARAMETER_FLOAT_MAPPING mapping;           /* [w] How the values are distributed across dials and automation curves (e.g. linearly, exponentially etc). */
} FMOD_DSP_PARAMETER_DESC_FLOAT;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure to define a int parameter for a DSP unit.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    System::createDSP
    DSP::setParameterInt
    DSP::getParameterInt
    FMOD_DSP_PARAMETER_DESC
]
*/
typedef struct FMOD_DSP_PARAMETER_DESC_INT
{
    int                       min;                      /* [w] Minimum parameter value. */
    int                       max;                      /* [w] Maximum parameter value. */
    int                       defaultval;               /* [w] Default parameter value. */
    FMOD_BOOL                 goestoinf;                /* [w] Whether the last value represents infiniy. */
    const char* const*        valuenames;               /* [w] Names for each value.  There should be as many strings as there are possible values (max - min + 1).  Optional. */
} FMOD_DSP_PARAMETER_DESC_INT;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure to define a boolean parameter for a DSP unit.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    System::createDSP
    DSP::setParameterBool
    DSP::getParameterBool
    FMOD_DSP_PARAMETER_DESC
]
*/
typedef struct FMOD_DSP_PARAMETER_DESC_BOOL
{
    FMOD_BOOL                 defaultval;               /* [w] Default parameter value. */
    const char* const*        valuenames;               /* [w] Names for false and true, respectively.  There should be two strings.  Optional. */
} FMOD_DSP_PARAMETER_DESC_BOOL;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure to define a data parameter for a DSP unit.  Use 0 or above for custom types.  This parameter will be treated specially by the system if set to one of the FMOD_DSP_PARAMETER_DATA_TYPE values.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    System::createDSP
    DSP::setParameterData
    DSP::getParameterData
    FMOD_DSP_PARAMETER_DATA_TYPE
    FMOD_DSP_PARAMETER_DESC
]
*/
typedef struct FMOD_DSP_PARAMETER_DESC_DATA
{
    int                       datatype;                 /* [w] The type of data for this parameter.  Use 0 or above for custom types or set to one of the FMOD_DSP_PARAMETER_DATA_TYPE values. */
} FMOD_DSP_PARAMETER_DESC_DATA;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Base Structure for DSP parameter descriptions.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    System::createDSP
    DSP::setParameterFloat
    DSP::getParameterFloat
    DSP::setParameterInt
    DSP::getParameterInt
    DSP::setParameterBool
    DSP::getParameterBool
    DSP::setParameterData
    DSP::getParameterData
    FMOD_DSP_PARAMETER_DESC_FLOAT
    FMOD_DSP_PARAMETER_DESC_INT
    FMOD_DSP_PARAMETER_DESC_BOOL
    FMOD_DSP_PARAMETER_DESC_DATA
    FMOD_DSP_PARAMETER_DATA_TYPE
]
*/
typedef struct FMOD_DSP_PARAMETER_DESC
{
    FMOD_DSP_PARAMETER_TYPE   type;                 /* [w] Type of this parameter. */
    char                      name[16];             /* [w] Name of the parameter to be displayed (ie "Cutoff frequency"). */
    char                      label[16];            /* [w] Short string to be put next to value to denote the unit type (ie "hz"). */
    const char               *description;          /* [w] Description of the parameter to be displayed as a help item / tooltip for this parameter. */

    union
    {
        FMOD_DSP_PARAMETER_DESC_FLOAT   floatdesc;  /* [w] Struct containing information about the parameter in floating point format.  Use when type is FMOD_DSP_PARAMETER_TYPE_FLOAT. */
        FMOD_DSP_PARAMETER_DESC_INT     intdesc;    /* [w] Struct containing information about the parameter in integer format.  Use when type is FMOD_DSP_PARAMETER_TYPE_INT. */
        FMOD_DSP_PARAMETER_DESC_BOOL    booldesc;   /* [w] Struct containing information about the parameter in boolean format.  Use when type is FMOD_DSP_PARAMETER_TYPE_BOOL. */
        FMOD_DSP_PARAMETER_DESC_DATA    datadesc;   /* [w] Struct containing information about the parameter in data format.  Use when type is FMOD_DSP_PARAMETER_TYPE_DATA. */
    };
} FMOD_DSP_PARAMETER_DESC;

/*
[ENUM]
[
    [DESCRIPTION]
    Built-in types for the 'datatype' member of FMOD_DSP_PARAMETER_DESC_DATA.  Data parameters of type other than FMOD_DSP_PARAMETER_DATA_TYPE_USER will be treated specially by the system.

    [REMARKS]

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_DESC_DATA
    FMOD_DSP_PARAMETER_OVERALLGAIN
    FMOD_DSP_PARAMETER_3DATTRIBUTES
    FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI
    FMOD_DSP_PARAMETER_SIDECHAIN
    DSP::getParameterData
    DSP::setParameterData
]
*/
typedef enum
{
    FMOD_DSP_PARAMETER_DATA_TYPE_USER = 0,                  /* The default data type.  All user data types should be 0 or above. */
    FMOD_DSP_PARAMETER_DATA_TYPE_OVERALLGAIN = -1,          /* The data type for FMOD_DSP_PARAMETER_OVERALLGAIN parameters.  There should a maximum of one per DSP. */
    FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES = -2,         /* The data type for FMOD_DSP_PARAMETER_3DATTRIBUTES parameters.  There should a maximum of one per DSP. */
    FMOD_DSP_PARAMETER_DATA_TYPE_SIDECHAIN = -3,            /* The data type for FMOD_DSP_PARAMETER_SIDECHAIN parameters.  There should a maximum of one per DSP. */
    FMOD_DSP_PARAMETER_DATA_TYPE_FFT = -4,                  /* The data type for FMOD_DSP_PARAMETER_FFT parameters.  There should a maximum of one per DSP. */
    FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI = -5,   /* The data type for FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI parameters.  There should a maximum of one per DSP. */
} FMOD_DSP_PARAMETER_DATA_TYPE;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure for data parameters of type FMOD_DSP_PARAMETER_DATA_TYPE_OVERALLGAIN.
    A parameter of this type is used in effects that affect the overgain of the signal in a predictable way.
    This parameter is read by the system to determine the effect's gain for voice virtualization.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_DATA_TYPE
    FMOD_DSP_PARAMETER_DESC
]
*/
typedef struct FMOD_DSP_PARAMETER_OVERALLGAIN
{
    float linear_gain;                                  /* [r] The overall linear gain of the effect on the direct signal path */
    float linear_gain_additive;                         /* [r] Additive gain, for parallel signal paths */
} FMOD_DSP_PARAMETER_OVERALLGAIN;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure for data parameters of type FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES.

    A parameter of this type is used in effects that respond to a 3D position.

    [REMARKS]
    The FMOD::Studio::System will set this parameter automatically if an FMOD::Studio::EventInstance position
    changes, however if using the low level FMOD::System you must set this DSP parameter explicitly.

    Attributes must use a coordinate system with the positive Y axis being up and the positive X axis being
    right. FMOD will convert passed in coordinates to left-handed for the plugin if the System was initialized
    with the FMOD_INIT_3D_RIGHTHANDED flag.

    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_DATA_TYPE
    FMOD_DSP_PARAMETER_DESC
]
*/
typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES
{
    FMOD_3D_ATTRIBUTES relative;                        /* [w] The position of the sound relative to the listener. */
    FMOD_3D_ATTRIBUTES absolute;                        /* [w] The position of the sound in world coordinates. */
} FMOD_DSP_PARAMETER_3DATTRIBUTES;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure for data parameters of type FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES_MULTI.

    A parameter of this type is used in effects that respond to a 3D position and support multiple listeners.

    [REMARKS]
    The FMOD::Studio::System will set this parameter automatically if an FMOD::Studio::EventInstance position
    changes, however if using the low level FMOD::System you must set this DSP parameter explicitly.

    Attributes must use a coordinate system with the positive Y axis being up and the positive X axis being
    right. FMOD will convert passed in coordinates to left-handed for the plugin if the System was initialized
    with the FMOD_INIT_3D_RIGHTHANDED flag.

    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_DATA_TYPE
    FMOD_DSP_PARAMETER_DESC
]
*/
typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI
{
    int                numlisteners;                    /* [w] The number of listeners. */
    FMOD_3D_ATTRIBUTES relative[FMOD_MAX_LISTENERS];    /* [w] The position of the sound relative to the listeners. */
    float              weight[FMOD_MAX_LISTENERS];      /* [w] The weighting of the listeners where 0 means listener has no contribution and 1 means full contribution. */
    FMOD_3D_ATTRIBUTES absolute;                        /* [w] The position of the sound in world coordinates. */
} FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure for data parameters of type FMOD_DSP_PARAMETER_DATA_TYPE_SIDECHAIN.
    A parameter of this type is declared for effects which support sidechaining.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_DATA_TYPE
    FMOD_DSP_PARAMETER_DESC
]
*/
typedef struct FMOD_DSP_PARAMETER_SIDECHAIN
{
    FMOD_BOOL sidechainenable;                               /* [r/w] Whether sidechains are enabled. */
} FMOD_DSP_PARAMETER_SIDECHAIN;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Structure for data parameters of type FMOD_DSP_PARAMETER_DATA_TYPE_FFT.
    A parameter of this type is declared for the FMOD_DSP_TYPE_FFT effect.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    Notes on the spectrum data member.  Values inside the float buffer are typically between 0 and 1.0.

    Each top level array represents one PCM channel of data.

    Address data as spectrum[channel][bin].  A bin is 1 fft window entry.

    Only read/display half of the buffer typically for analysis as the 2nd half is usually the same data reversed due to the nature of the way FFT works.

    [SEE_ALSO]
    FMOD_DSP_PARAMETER_DATA_TYPE
    FMOD_DSP_PARAMETER_DESC
    FMOD_DSP_PARAMETER_DATA_TYPE_FFT
    FMOD_DSP_TYPE
    FMOD_DSP_FFT
]
*/
typedef struct FMOD_DSP_PARAMETER_FFT
{
    int     length;                                    /* [r] Number of entries in this spectrum window.   Divide this by the output rate to get the hz per entry. */
    int     numchannels;                               /* [r] Number of channels in spectrum. */
    float  *spectrum[32];                              /* [r] Per channel spectrum arrays.  See remarks for more. */
} FMOD_DSP_PARAMETER_FFT;

/*
    Helpers for declaring parameters in custom DSPSs
*/
#define FMOD_DSP_INIT_PARAMDESC_FLOAT(_paramstruct, _name, _label, _description, _min, _max, _defaultval) \
    memset(&(_paramstruct), 0, sizeof(_paramstruct)); \
    (_paramstruct).type         = FMOD_DSP_PARAMETER_TYPE_FLOAT; \
    strncpy((_paramstruct).name,  _name,  15); \
    strncpy((_paramstruct).label, _label, 15); \
    (_paramstruct).description  = _description; \
    (_paramstruct).floatdesc.min          = _min; \
    (_paramstruct).floatdesc.max          = _max; \
    (_paramstruct).floatdesc.defaultval   = _defaultval; \
    (_paramstruct).floatdesc.mapping.type = FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_AUTO;

#define FMOD_DSP_INIT_PARAMDESC_FLOAT_WITH_MAPPING(_paramstruct, _name, _label, _description, _defaultval, _values, _positions); \
    memset(&(_paramstruct), 0, sizeof(_paramstruct)); \
    (_paramstruct).type         = FMOD_DSP_PARAMETER_TYPE_FLOAT; \
    strncpy((_paramstruct).name,  _name , 15); \
    strncpy((_paramstruct).label, _label, 15); \
    (_paramstruct).description  = _description; \
    (_paramstruct).floatdesc.min          = _values[0]; \
    (_paramstruct).floatdesc.max          = _values[sizeof(_values) / sizeof(float) - 1]; \
    (_paramstruct).floatdesc.defaultval   = _defaultval; \
    (_paramstruct).floatdesc.mapping.type = FMOD_DSP_PARAMETER_FLOAT_MAPPING_TYPE_PIECEWISE_LINEAR; \
    (_paramstruct).floatdesc.mapping.piecewiselinearmapping.numpoints = sizeof(_values) / sizeof(float); \
    (_paramstruct).floatdesc.mapping.piecewiselinearmapping.pointparamvalues = _values; \
    (_paramstruct).floatdesc.mapping.piecewiselinearmapping.pointpositions = _positions;

#define FMOD_DSP_INIT_PARAMDESC_INT(_paramstruct, _name, _label, _description, _min, _max, _defaultval, _goestoinf, _valuenames) \
    memset(&(_paramstruct), 0, sizeof(_paramstruct)); \
    (_paramstruct).type         = FMOD_DSP_PARAMETER_TYPE_INT; \
    strncpy((_paramstruct).name,  _name , 15); \
    strncpy((_paramstruct).label, _label, 15); \
    (_paramstruct).description  = _description; \
    (_paramstruct).intdesc.min          = _min; \
    (_paramstruct).intdesc.max          = _max; \
    (_paramstruct).intdesc.defaultval   = _defaultval; \
    (_paramstruct).intdesc.goestoinf    = _goestoinf; \
    (_paramstruct).intdesc.valuenames   = _valuenames;

#define FMOD_DSP_INIT_PARAMDESC_INT_ENUMERATED(_paramstruct, _name, _label, _description, _defaultval, _valuenames) \
    memset(&(_paramstruct), 0, sizeof(_paramstruct)); \
    (_paramstruct).type         = FMOD_DSP_PARAMETER_TYPE_INT; \
    strncpy((_paramstruct).name,  _name , 15); \
    strncpy((_paramstruct).label, _label, 15); \
    (_paramstruct).description  = _description; \
    (_paramstruct).intdesc.min          = 0; \
    (_paramstruct).intdesc.max          = sizeof(_valuenames) / sizeof(char*) - 1; \
    (_paramstruct).intdesc.defaultval   = _defaultval; \
    (_paramstruct).intdesc.goestoinf    = false; \
    (_paramstruct).intdesc.valuenames   = _valuenames;

#define FMOD_DSP_INIT_PARAMDESC_BOOL(_paramstruct, _name, _label, _description, _defaultval, _valuenames) \
    memset(&(_paramstruct), 0, sizeof(_paramstruct)); \
    (_paramstruct).type         = FMOD_DSP_PARAMETER_TYPE_BOOL; \
    strncpy((_paramstruct).name,  _name , 15); \
    strncpy((_paramstruct).label, _label, 15); \
    (_paramstruct).description  = _description; \
    (_paramstruct).booldesc.defaultval   = _defaultval; \
    (_paramstruct).booldesc.valuenames   = _valuenames;

#define FMOD_DSP_INIT_PARAMDESC_DATA(_paramstruct, _name, _label, _description, _datatype) \
    memset(&(_paramstruct), 0, sizeof(_paramstruct)); \
    (_paramstruct).type         = FMOD_DSP_PARAMETER_TYPE_DATA; \
    strncpy((_paramstruct).name,  _name , 15); \
    strncpy((_paramstruct).label, _label, 15); \
    (_paramstruct).description  = _description; \
    (_paramstruct).datadesc.datatype     = _datatype;

#define FMOD_PLUGIN_SDK_VERSION 110

/*
[STRUCTURE]
[
    [DESCRIPTION]
    When creating a DSP unit, declare one of these and provide the relevant callbacks and name for FMOD to use when it creates and uses a DSP unit of this type.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    There are 2 different ways to change a parameter in this architecture.

    One is to use DSP::setParameterFloat / DSP::setParameterInt / DSP::setParameterBool / DSP::setParameterData.  This is platform independant and is dynamic, so new unknown plugins can have their parameters enumerated and used.

    The other is to use DSP::showConfigDialog.  This is platform specific and requires a GUI, and will display a dialog box to configure the plugin.

    [SEE_ALSO]
    System::createDSP
    DSP::setParameterFloat
    DSP::setParameterInt
    DSP::setParameterBool
    DSP::setParameterData
    FMOD_DSP_STATE
    FMOD_DSP_CREATE_CALLBACK
    FMOD_DSP_RELEASE_CALLBACK
    FMOD_DSP_RESET_CALLBACK
    FMOD_DSP_READ_CALLBACK
    FMOD_DSP_PROCESS_CALLBACK
    FMOD_DSP_SETPOSITION_CALLBACK
    FMOD_DSP_PARAMETER_DESC
    FMOD_DSP_SETPARAM_FLOAT_CALLBACK
    FMOD_DSP_SETPARAM_INT_CALLBACK
    FMOD_DSP_SETPARAM_BOOL_CALLBACK
    FMOD_DSP_SETPARAM_DATA_CALLBACK
    FMOD_DSP_GETPARAM_FLOAT_CALLBACK
    FMOD_DSP_GETPARAM_INT_CALLBACK
    FMOD_DSP_GETPARAM_BOOL_CALLBACK
    FMOD_DSP_GETPARAM_DATA_CALLBACK
    FMOD_DSP_SHOULDIPROCESS_CALLBACK
    FMOD_DSP_SYSTEM_REGISTER_CALLBACK
    FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK
    FMOD_DSP_SYSTEM_MIX_CALLBACK
]
*/
typedef struct FMOD_DSP_DESCRIPTION
{
    unsigned int                        pluginsdkversion;   /* [w] The plugin SDK version this plugin is built for.  Set to this to FMOD_PLUGIN_SDK_VERSION defined above. */
    char                                name[32];           /* [w] The identifier of the DSP. This will also be used as the name of DSP and shouldn't change between versions. */
    unsigned int                        version;            /* [w] Plugin writer's version number. */
    int                                 numinputbuffers;    /* [w] Number of input buffers to process.  Use 0 for DSPs that only generate sound and 1 for effects that process incoming sound. */
    int                                 numoutputbuffers;   /* [w] Number of audio output buffers.  Only one output buffer is currently supported. */
    FMOD_DSP_CREATE_CALLBACK            create;             /* [w] Create callback.  This is called when DSP unit is created.  Can be null. */
    FMOD_DSP_RELEASE_CALLBACK           release;            /* [w] Release callback.  This is called just before the unit is freed so the user can do any cleanup needed for the unit.  Can be null. */
    FMOD_DSP_RESET_CALLBACK             reset;              /* [w] Reset callback.  This is called by the user to reset any history buffers that may need resetting for a filter, when it is to be used or re-used for the first time to its initial clean state.  Use to avoid clicks or artifacts. */
    FMOD_DSP_READ_CALLBACK              read;               /* [w] Read callback.  Processing is done here.  Can be null. */
    FMOD_DSP_PROCESS_CALLBACK           process;            /* [w] Process callback.  Can be specified instead of the read callback if any channel format changes occur between input and output.  This also replaces shouldiprocess and should return an error if the effect is to be bypassed.  Can be null. */
    FMOD_DSP_SETPOSITION_CALLBACK       setposition;        /* [w] Set position callback.  This is called if the unit wants to update its position info but not process data, or reset a cursor position internally if it is reading data from a certain source.  Can be null. */

    int                                 numparameters;      /* [w] Number of parameters used in this filter.  The user finds this with DSP::getNumParameters */
    FMOD_DSP_PARAMETER_DESC           **paramdesc;          /* [w] Variable number of parameter structures. */
    FMOD_DSP_SETPARAM_FLOAT_CALLBACK    setparameterfloat;  /* [w] This is called when the user calls DSP::setParameterFloat. Can be null. */
    FMOD_DSP_SETPARAM_INT_CALLBACK      setparameterint;    /* [w] This is called when the user calls DSP::setParameterInt.   Can be null. */
    FMOD_DSP_SETPARAM_BOOL_CALLBACK     setparameterbool;   /* [w] This is called when the user calls DSP::setParameterBool.  Can be null. */
    FMOD_DSP_SETPARAM_DATA_CALLBACK     setparameterdata;   /* [w] This is called when the user calls DSP::setParameterData.  Can be null. */
    FMOD_DSP_GETPARAM_FLOAT_CALLBACK    getparameterfloat;  /* [w] This is called when the user calls DSP::getParameterFloat. Can be null. */
    FMOD_DSP_GETPARAM_INT_CALLBACK      getparameterint;    /* [w] This is called when the user calls DSP::getParameterInt.   Can be null. */
    FMOD_DSP_GETPARAM_BOOL_CALLBACK     getparameterbool;   /* [w] This is called when the user calls DSP::getParameterBool.  Can be null. */
    FMOD_DSP_GETPARAM_DATA_CALLBACK     getparameterdata;   /* [w] This is called when the user calls DSP::getParameterData.  Can be null. */
    FMOD_DSP_SHOULDIPROCESS_CALLBACK    shouldiprocess;     /* [w] This is called before processing.  You can detect if inputs are idle and return FMOD_OK to process, or any other error code to avoid processing the effect.  Use a count down timer to allow effect tails to process before idling! */
    void                               *userdata;           /* [w] Optional. Specify 0 to ignore. This is user data to be attached to the DSP unit during creation.  Access via FMOD_DSP_STATE_FUNCTIONS::getuserdata. */

    FMOD_DSP_SYSTEM_REGISTER_CALLBACK   sys_register;       /* [w] Register callback.  This is called when DSP unit is loaded/registered.  Useful for 'global'/per system object init for plugin.  Can be null. */
    FMOD_DSP_SYSTEM_DEREGISTER_CALLBACK sys_deregister;     /* [w] Deregister callback.  This is called when DSP unit is unloaded/deregistered.  Useful as 'global'/per system object shutdown for plugin.  Can be null. */
    FMOD_DSP_SYSTEM_MIX_CALLBACK        sys_mix;            /* [w] System mix stage callback.  This is called when the mixer starts to execute or is just finishing executing.  Useful for 'global'/per system object once a mix update calls for a plugin.  Can be null. */

} FMOD_DSP_DESCRIPTION;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Struct containing DFT functions to enable a plugin to perform optimized time-frequency domain conversion.

    [REMARKS]
    Members marked with [r] mean read only for the developer, read/write for the FMOD system.

    Members marked with [w] mean read/write for the developer, read only for the FMOD system.

    [SEE_ALSO]
    FMOD_DSP_STATE_FUNCTIONS
]
*/
typedef struct FMOD_DSP_STATE_DFT_FUNCTIONS
{
    FMOD_DSP_DFT_FFTREAL_FUNC  fftreal;        /* [r] Function for performing an FFT on a real signal. */
    FMOD_DSP_DFT_IFFTREAL_FUNC inversefftreal; /* [r] Function for performing an inverse FFT to get a real signal. */
} FMOD_DSP_STATE_DFT_FUNCTIONS;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Struct containing panning helper functions for spatialization plugins.

    [REMARKS]
    These are experimental, please contact support@fmod.org for more information.

    Members marked with [r] mean read only for the developer, read/write for the FMOD system.

    Members marked with [w] mean read/write for the developer, read only for the FMOD system.

    [SEE_ALSO]
    FMOD_DSP_STATE_FUNCTIONS
    FMOD_DSP_PAN_SURROUND_FLAGS
]
*/
typedef struct FMOD_DSP_STATE_PAN_FUNCTIONS
{
    FMOD_DSP_PAN_SUMMONOMATRIX_FUNC             summonomatrix;             /* [r] TBD. */
    FMOD_DSP_PAN_SUMSTEREOMATRIX_FUNC           sumstereomatrix;           /* [r] TBD. */
    FMOD_DSP_PAN_SUMSURROUNDMATRIX_FUNC         sumsurroundmatrix;         /* [r] TBD. */
    FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX_FUNC   summonotosurroundmatrix;   /* [r] TBD. */
    FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX_FUNC sumstereotosurroundmatrix; /* [r] TBD. */
    FMOD_DSP_PAN_GETROLLOFFGAIN_FUNC            getrolloffgain;            /* [r] TBD. */
} FMOD_DSP_STATE_PAN_FUNCTIONS;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    Struct containing functions to give plugin developers the ability to query system state, access system level functionality and helpers.

    [REMARKS]
    Members marked with [r] mean read only for the developer, read/write for the FMOD system.

    Members marked with [w] mean read/write for the developer, read only for the FMOD system.

    [SEE_ALSO]
    FMOD_DSP_STATE
    FMOD_DSP_STATE_DFT_FUNCTIONS
    FMOD_DSP_STATE_PAN_FUNCTIONS
]
*/
typedef struct FMOD_DSP_STATE_FUNCTIONS
{
    FMOD_DSP_ALLOC_FUNC                 alloc;                  /* [r] Function to allocate memory using the FMOD memory system. */
    FMOD_DSP_REALLOC_FUNC               realloc;                /* [r] Function to reallocate memory using the FMOD memory system. */
    FMOD_DSP_FREE_FUNC                  free;                   /* [r] Function to free memory allocated with FMOD_DSP_ALLOC_FUNC. */
    FMOD_DSP_GETSAMPLERATE_FUNC         getsamplerate;          /* [r] Function to query the system sample rate. */
    FMOD_DSP_GETBLOCKSIZE_FUNC          getblocksize;           /* [r] Function to query the system block size, DSPs will be requested to process blocks of varying length up to this size. */
    FMOD_DSP_STATE_DFT_FUNCTIONS       *dft;                    /* [r] Struct containing DFT functions to enable a plugin to perform optimized time-frequency domain conversion. */
    FMOD_DSP_STATE_PAN_FUNCTIONS       *pan;                    /* [r] Struct containing panning helper functions for spatialization plugins. */
    FMOD_DSP_GETSPEAKERMODE_FUNC        getspeakermode;         /* [r] Function to query the system speaker modes.  One is the mixer's default speaker mode, the other is the output mode the system is downmixing or upmixing to.*/
    FMOD_DSP_GETCLOCK_FUNC              getclock;               /* [r] Function to get the clock of the current DSP, as well as the subset of the input buffer that contains the signal. */
    FMOD_DSP_GETLISTENERATTRIBUTES_FUNC getlistenerattributes;  /* [r] Callback for getting the absolute listener attributes set via the API (returned as left-handed coordinates). */
    FMOD_DSP_LOG_FUNC                   log;                    /* [r] Function to write to the FMOD logging system. */
    FMOD_DSP_GETUSERDATA_FUNC           getuserdata;            /* [r] Function to get the user data attached to this DSP. See FMOD_DSP_DESCRIPTION::userdata. */
} FMOD_DSP_STATE_FUNCTIONS;

/*
[STRUCTURE]
[
    [DESCRIPTION]
    DSP plugin structure that is passed into each callback.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    'systemobject' is an integer that relates to the System object that created the DSP or registered the DSP plugin.  If only 1 System object is created then it should be 0.  A second object would be 1 and so on.
    FMOD_DSP_STATE_FUNCTIONS::getsamplerate/getblocksize/getspeakermode could return different results so it could be relevant to plugin developers to monitor which object is being used.

    [SEE_ALSO]
    FMOD_DSP_DESCRIPTION
    FMOD_DSP_STATE_FUNCTIONS
]
*/
struct FMOD_DSP_STATE
{
    void                     *instance;            /* [r] Internal instance pointer, should not be used or written to. */
    void                     *plugindata;          /* [w] Plugin writer created data the output author wants to attach to this object. */
    FMOD_CHANNELMASK          channelmask;         /* [r] Specifies which speakers the DSP effect is active on */
    FMOD_SPEAKERMODE          source_speakermode;  /* [r] Specifies which speaker mode the signal originated for information purposes, ie in case panning needs to be done differently. */
    float                    *sidechaindata;       /* [r] The mixed result of all incoming sidechains is stored at this pointer address. */
    int                       sidechainchannels;   /* [r] The number of channels of pcm data stored within the sidechain buffer. */
    FMOD_DSP_STATE_FUNCTIONS *functions;           /* [r] Struct containing functions to give plugin developers the ability to query system state, access system level functionality and helpers. */
    int                       systemobject;        /* [r] FMOD::System object index, relating to the System object that created this DSP. */
};

/*
    Macro helpers for accessing FMOD_DSP_STATE_FUNCTIONS
*/
#define FMOD_DSP_ALLOC(_state, _size) \
    (_state)->functions->alloc(_size, FMOD_MEMORY_NORMAL, __FILE__)
#define FMOD_DSP_REALLOC(_state, _ptr, _size) \
    (_state)->functions->realloc(_ptr, _size, FMOD_MEMORY_NORMAL, __FILE__)
#define FMOD_DSP_FREE(_state, _ptr) \
    (_state)->functions->free(_ptr, FMOD_MEMORY_NORMAL, __FILE__)
#define FMOD_DSP_LOG(_state, _level, _location, _format, ...) \
    (_state)->functions->log(_level, __FILE__, __LINE__, _location, _format, __VA_ARGS__)
#define FMOD_DSP_GETSAMPLERATE(_state, _rate) \
    (_state)->functions->getsamplerate(_state, _rate)
#define FMOD_DSP_GETBLOCKSIZE(_state, _blocksize) \
    (_state)->functions->getblocksize(_state, _blocksize)
#define FMOD_DSP_GETSPEAKERMODE(_state, _speakermodemix, _speakermodeout) \
    (_state)->functions->getspeakermode(_state, _speakermodemix, _speakermodeout)
#define FMOD_DSP_GETCLOCK(_state, _clock, _offset, _length) \
    (_state)->functions->getclock(_state, _clock, _offset, _length)
#define FMOD_DSP_GETLISTENERATTRIBUTES(_state, _numlisteners, _attributes) \
    (_state)->functions->getlistenerattributes(_state, _numlisteners, _attributes)
#define FMOD_DSP_GETUSERDATA(_state, _userdata) \
    (_state)->functions->getuserdata(_state, _userdata)
#define FMOD_DSP_DFT_FFTREAL(_state, _size, _signal, _dft, _window, _signalhop) \
    (_state)->functions->dft->fftreal(_state, _size, _signal, _dft, _window, _signalhop)
#define FMOD_DSP_DFT_IFFTREAL(_state, _size, _dft, _signal, _window, _signalhop) \
    (_state)->functions->dft->inversefftreal(_state, _size, _dft, _signal, _window, _signalhop)
#define FMOD_DSP_PAN_SUMMONOMATRIX(_state, _sourcespeakermode, _lowfrequencygain, _overallgain, _matrix) \
    (_state)->functions->pan->summonomatrix(_state, _sourcespeakermode, _lowfrequencygain, _overallgain, _matrix)
#define FMOD_DSP_PAN_SUMSTEREOMATRIX(_state, _sourcespeakermode, _pan, _lowfrequencygain, _overallgain, _matrixhop, _matrix) \
    (_state)->functions->pan->sumstereomatrix(_state, _sourcespeakermode, _pan, _lowfrequencygain, _overallgain, _matrixhop, _matrix)
#define FMOD_DSP_PAN_SUMSURROUNDMATRIX(_state, _sourcespeakermode, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, _matrixhop, _matrix, _flags) \
    (_state)->functions->pan->sumsurroundmatrix(_state, _sourcespeakermode, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, _matrixhop, _matrix, _flags)
#define FMOD_DSP_PAN_SUMMONOTOSURROUNDMATRIX(_state, _targetspeakermode, _direction, _extent, _lowfrequencygain, _overallgain, _matrixhop, _matrix) \
    (_state)->functions->pan->summonotosurroundmatrix(_state, _targetspeakermode, _direction, _extent, _lowfrequencygain, _overallgain, _matrixhop, _matrix)
#define FMOD_DSP_PAN_SUMSTEREOTOSURROUNDMATRIX(_state, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, matrixhop, _matrix) \
    (_state)->functions->pan->sumstereotosurroundmatrix(_state, _targetspeakermode, _direction, _extent, _rotation, _lowfrequencygain, _overallgain, matrixhop, _matrix)
#define FMOD_DSP_PAN_GETROLLOFFGAIN(_state, _rolloff, _distance, _mindistance, _maxdistance, _gain) \
    (_state)->functions->pan->getrolloffgain(_state, _rolloff, _distance, _mindistance, _maxdistance, _gain)

/*
[STRUCTURE]
[
    [DESCRIPTION]
    DSP metering info used for retrieving metering info with DSP::getMeteringInfo

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.

    Members marked with [w] mean the variable can be written to.  The user can set the value.

    [SEE_ALSO]
    FMOD_SPEAKER
    DSP::getMeteringInfo
]
*/
typedef struct FMOD_DSP_METERING_INFO
{
    int   numsamples;       /* [r] The number of samples considered for this metering info. */
    float peaklevel[32];    /* [r] The peak level per channel. */
    float rmslevel[32];     /* [r] The rms level per channel. */
    short numchannels;      /* [r] Number of channels. */
} FMOD_DSP_METERING_INFO;

#endif