diff --git a/metadata.json b/metadata.json index 84752d5..738fbd4 100644 --- a/metadata.json +++ b/metadata.json @@ -1 +1 @@ -{"gitHubUrl":"https://github.com/YoYoGames/GMEXT-FMOD","projectFile":"source/fmod_gml/FMOD.yyp","projectVersion":"LTS22","releaseTemplate":"templates/release_body.md","extensionMetaData":[{"extensionFile":"source/fmod_gml/extensions/FMOD/FMOD.yy","packageId":"com.yoyogames.fmodext","packageName":"FMOD Ext","packageVersion":"0.0.2","packageFormat":"LTS22","includeFolders":null,"includeResources":null,"excludeFolders":null,"excludeResources":null}]} \ No newline at end of file +{"gitHubUrl":"https://github.com/YoYoGames/GMEXT-FMOD","projectFile":"source/fmod_gml/FMOD.yyp","projectVersion":"LTS22","releaseTemplate":"templates/release_body.md","extensionMetaData":[{"extensionFile":"source/fmod_gml/extensions/FMOD/FMOD.yy","packageId":"com.yoyogames.fmodext","packageName":"FMOD Ext","packageVersion":"0.0.3","packageFormat":"LTS22","includeFolders":null,"includeResources":null,"excludeFolders":null,"excludeResources":null}]} \ No newline at end of file diff --git a/source/fmod_gml/extensions/FMOD/FMOD.yy b/source/fmod_gml/extensions/FMOD/FMOD.yy index 36aded8..50533f9 100644 --- a/source/fmod_gml/extensions/FMOD/FMOD.yy +++ b/source/fmod_gml/extensions/FMOD/FMOD.yy @@ -16,7 +16,7 @@ "copyToTargets": 3035426170322551022, "description": "", "exportToGame": true, - "extensionVersion": "0.0.2", + "extensionVersion": "0.0.3", "files": [ {"$GMExtensionFile":"","%Name":"YYFMOD.dll","constants":[],"copyToTargets":3035426170322550990,"filename":"YYFMOD.dll","final":"","functions":[ {"$GMExtensionFunction":"","%Name":"fmod_channel_set_frequency","argCount":0,"args":[2,2,],"documentation":"/// @desc\n\r/// @param {real} channel_ref \n\r/// @param {real} frequency \n\r/// @returns {real}\n\r","externalName":"fmod_channel_set_frequency","help":"fmod_channel_set_frequency(channel_ref, frequency)","hidden":false,"kind":1,"name":"fmod_channel_set_frequency","resourceType":"GMExtensionFunction","resourceVersion":"2.0","returnType":2,}, diff --git a/source/fmod_gml/extensions/FMOD/docs/DSP.html b/source/fmod_gml/extensions/FMOD/docs/DSP.html index ff3d6d1..0283d4e 100644 --- a/source/fmod_gml/extensions/FMOD/docs/DSP.html +++ b/source/fmod_gml/extensions/FMOD/docs/DSP.html @@ -228,8 +228,7 @@

fmod_dsp_add_input


Syntax:

-
fmod_dsp_add_input(dsp_ref, dsp_input_ref, dsp_connection_type)
-
+
fmod_dsp_add_input(dsp_ref, dsp_input_ref, dsp_connection_type)
@@ -281,8 +280,7 @@

fmod_dsp_get_input


Syntax:

-
fmod_dsp_get_input(dsp_ref, dsp_chain_index)
-
+
fmod_dsp_get_input(dsp_ref, dsp_chain_index)
@@ -329,8 +327,7 @@

fmod_dsp_get_output


Syntax:

-
fmod_dsp_get_output(dsp_ref, dsp_chain_index)
-
+
fmod_dsp_get_output(dsp_ref, dsp_chain_index)
@@ -376,8 +373,7 @@

fmod_dsp_get_num_inputs


Syntax:

-
fmod_dsp_get_num_inputs(dsp_ref)
-
+
fmod_dsp_get_num_inputs(dsp_ref)
@@ -418,8 +414,7 @@

fmod_dsp_get_num_outputs


Syntax:

-
fmod_dsp_get_num_outputs(dsp_ref)
-
+
fmod_dsp_get_num_outputs(dsp_ref)
@@ -457,8 +452,7 @@

fmod_dsp_disconnect_all


Syntax:

-
fmod_dsp_disconnect_all(dsp_ref, inputs, outputs)
-
+
fmod_dsp_disconnect_all(dsp_ref, inputs, outputs)
@@ -507,8 +501,7 @@

fmod_dsp_disconnect_from


Syntax:

-
fmod_dsp_disconnect_from(dsp_ref, dsp_other_ref, dsp_connection_ref)
-
+
fmod_dsp_disconnect_from(dsp_ref, dsp_other_ref, dsp_connection_ref)
@@ -557,8 +550,7 @@

fmod_dsp_get_data_parameter_index


Syntax:

-
fmod_dsp_get_data_parameter_index(dsp_ref, data_type)
-
+
fmod_dsp_get_data_parameter_index(dsp_ref, data_type)
@@ -601,8 +593,7 @@

fmod_dsp_get_num_parameters


Syntax:

-
fmod_dsp_get_num_parameters(dsp_ref)
-
+
fmod_dsp_get_num_parameters(dsp_ref)
@@ -639,8 +630,7 @@

fmod_dsp_set_parameter_bool


Syntax:

-
fmod_dsp_set_parameter_bool(dsp_ref, parameter_index, value)
-
+
fmod_dsp_set_parameter_bool(dsp_ref, parameter_index, value)
@@ -687,8 +677,7 @@

fmod_dsp_get_parameter_bool


Syntax:

-
fmod_dsp_get_parameter_bool(dsp_ref, parameter_index)
-
+
fmod_dsp_get_parameter_bool(dsp_ref, parameter_index)
@@ -735,8 +724,7 @@

fmod_dsp_set_parameter_data


Syntax:

-
fmod_dsp_set_parameter_data(dsp_ref, parameter_index, buffer, length)
-
+
fmod_dsp_set_parameter_data(dsp_ref, parameter_index, buffer, length)
@@ -785,6 +773,7 @@

fmod_dsp_get_parameter_data


This function retrieves a binary data parameter by index.

+

It returns 0 if the function succeeds or a value greater than 0 that's the buffer size needed to store the parameter data. In this case you should resize the buffer to the return value using buffer_resize.

The binary data is copied to the Buffer that you specify. A total number of length bytes are written.

Note

@@ -797,8 +786,7 @@

fmod_dsp_get_parameter_data


Syntax:

-
fmod_dsp_get_parameter_data(dsp_ref, parameter_index, buffer, length)
-
+
fmod_dsp_get_parameter_data(dsp_ref, parameter_index, buffer, length)
@@ -834,9 +822,20 @@

fmod_dsp_get_parameter_data


Returns:

-

N/A

+

Real


+

Example:

+

/// Step Event
+var _required_size = fmod_dsp_get_parameter_data(dsp_fft, FMOD_DSP_FFT.SPECTRUMDATA, fft_buffer);
+if (buffer_get_size(fft_buffer) < _required_size)
+{
+    buffer_resize(fft_buffer, _required_size);
+}
+The code example above attempts to get the spectrum data of an FFT DSP and store it in a buffer fft_buffer. +If the size of the buffer is less than the size returned, the buffer is resized. +Note that no new call to the function is made since this code executes in the Step event and will be executed again in the next step anyway.

+




Back To Top

@@ -850,8 +849,7 @@

fmod_dsp_set_parameter_float


Syntax:

-
fmod_dsp_set_parameter_float(dsp_ref, parameter_index, value)
-
+
fmod_dsp_set_parameter_float(dsp_ref, parameter_index, value)
@@ -898,8 +896,7 @@

fmod_dsp_get_parameter_float


Syntax:

-
fmod_dsp_get_parameter_float(dsp_ref, parameter_index)
-
+
fmod_dsp_get_parameter_float(dsp_ref, parameter_index)
@@ -941,8 +938,7 @@

fmod_dsp_set_parameter_int


Syntax:

-
fmod_dsp_set_parameter_int(dsp_ref, parameter_index, value)
-
+
fmod_dsp_set_parameter_int(dsp_ref, parameter_index, value)
@@ -989,8 +985,7 @@

fmod_dsp_get_parameter_int


Syntax:

-
fmod_dsp_get_parameter_int(dsp_ref, parameter_index)
-
+
fmod_dsp_get_parameter_int(dsp_ref, parameter_index)
@@ -1032,8 +1027,7 @@

fmod_dsp_get_parameter_info


Syntax:

-
fmod_dsp_get_parameter_info(dsp_ref)
-
+
fmod_dsp_get_parameter_info(dsp_ref)
@@ -1074,8 +1068,7 @@

fmod_dsp_set_channel_format


Syntax:

-
fmod_dsp_set_channel_format(dsp_ref, channel_mask, num_channels, speaker_mode)
-
+
fmod_dsp_set_channel_format(dsp_ref, channel_mask, num_channels, speaker_mode)
@@ -1127,8 +1120,7 @@

fmod_dsp_get_channel_format


Syntax:

-
fmod_dsp_get_channel_format(dsp_ref)
-
+
fmod_dsp_get_channel_format(dsp_ref)
@@ -1165,8 +1157,7 @@

fmod_dsp_get_output_channel_format

Syntax:

-
fmod_dsp_get_output_channel_format(dsp_ref, channel_mask_in, num_channels_in, speaker_mode_in)
-
+
fmod_dsp_get_output_channel_format(dsp_ref, channel_mask_in, num_channels_in, speaker_mode_in)

@@ -1226,8 +1217,7 @@

fmod_dsp_get_metering_info


Syntax:

-
fmod_dsp_get_metering_info(dsp_ref)
-
+
fmod_dsp_get_metering_info(dsp_ref)
@@ -1270,8 +1260,7 @@

fmod_dsp_set_metering_enabled


Syntax:

-
fmod_dsp_set_metering_enabled(dsp_ref, enabled_in, enabled_out)
-
+
fmod_dsp_set_metering_enabled(dsp_ref, enabled_in, enabled_out)
@@ -1318,8 +1307,7 @@

fmod_dsp_get_metering_enabled


Syntax:

-
fmod_dsp_get_metering_enabled(dsp_ref)
-
+
fmod_dsp_get_metering_enabled(dsp_ref)
@@ -1361,8 +1349,7 @@

fmod_dsp_set_active


Syntax:

-
fmod_dsp_set_active(dsp_ref, active)
-
+
fmod_dsp_set_active(dsp_ref, active)
@@ -1409,8 +1396,7 @@

fmod_dsp_get_active


Syntax:

-
fmod_dsp_get_active(dsp_ref)
-
+
fmod_dsp_get_active(dsp_ref)
@@ -1448,8 +1434,7 @@

fmod_dsp_set_bypass


Syntax:

-
fmod_dsp_set_bypass(dsp_ref, bypass)
-
+
fmod_dsp_set_bypass(dsp_ref, bypass)
@@ -1492,8 +1477,7 @@

fmod_dsp_get_bypass


Syntax:

-
fmod_dsp_get_bypass(dsp_ref)
-
+
fmod_dsp_get_bypass(dsp_ref)
@@ -1530,8 +1514,7 @@

fmod_dsp_set_wet_dry_mix


Syntax:

-
fmod_dsp_set_wet_dry_mix(dsp_ref, prewet, postwet, dry)
-
+
fmod_dsp_set_wet_dry_mix(dsp_ref, prewet, postwet, dry)
@@ -1583,8 +1566,7 @@

fmod_dsp_get_wet_dry_mix


Syntax:

-
fmod_dsp_get_wet_dry_mix(dsp_ref)
-
+
fmod_dsp_get_wet_dry_mix(dsp_ref)
@@ -1623,8 +1605,7 @@

fmod_dsp_get_idle


Syntax:

-
fmod_dsp_get_idle(dsp_ref)
-
+
fmod_dsp_get_idle(dsp_ref)
@@ -1662,8 +1643,7 @@

fmod_dsp_reset


Syntax:

-
fmod_dsp_reset(dsp_ref)
-
+
fmod_dsp_reset(dsp_ref)
@@ -1701,8 +1681,7 @@

fmod_dsp_release


Syntax:

-
fmod_dsp_release(dsp_ref)
-
+
fmod_dsp_release(dsp_ref)
@@ -1740,8 +1719,7 @@

fmod_dsp_get_type


Syntax:

-
fmod_dsp_get_type(dsp_ref)
-
+
fmod_dsp_get_type(dsp_ref)
@@ -1778,8 +1756,7 @@

fmod_dsp_get_info


Syntax:

-
fmod_dsp_get_info(dsp_ref)
-
+
fmod_dsp_get_info(dsp_ref)
@@ -1820,8 +1797,7 @@

fmod_dsp_get_cpu_usage


Syntax:

-
fmod_dsp_get_cpu_usage(dsp_ref)
-
+
fmod_dsp_get_cpu_usage(dsp_ref)
@@ -1862,8 +1838,7 @@

fmod_dsp_set_user_data


Syntax:

-
fmod_dsp_set_user_data(dsp_ref, data)
-
+
fmod_dsp_set_user_data(dsp_ref, data)
@@ -1909,8 +1884,7 @@

fmod_dsp_get_user_data


Syntax:

-
fmod_dsp_get_user_data(dsp_ref)
-
+
fmod_dsp_get_user_data(dsp_ref)
@@ -1949,8 +1923,7 @@

fmod_dsp_set_callback


Syntax:

-
fmod_dsp_set_callback(dsp_ref)
-
+
fmod_dsp_set_callback(dsp_ref)
@@ -2023,8 +1996,7 @@

fmod_dsp_get_system_object


Syntax:

-
fmod_dsp_get_system_object(dsp_ref)
-
+
fmod_dsp_get_system_object(dsp_ref)
diff --git a/source/fmod_gml/extensions/FMOD/docs/GeneralInformation.html b/source/fmod_gml/extensions/FMOD/docs/GeneralInformation.html index e822e5f..61a452e 100644 --- a/source/fmod_gml/extensions/FMOD/docs/GeneralInformation.html +++ b/source/fmod_gml/extensions/FMOD/docs/GeneralInformation.html @@ -166,10 +166,9 @@

Handles

  • The last 10 bits identify the extension.
  • To create an instance of an FMOD object and get its handle, you call an extension function that returns a handle. Many FMOD objects can be created using the fmod_system_create_* functions. For example:

    -
    system = fmod_system_create();
    -sound_group = fmod_system_create_sound_group("SoundGroup");
    -// Etc.
    -
    +
    system = fmod_system_create();
    +sound_group = fmod_system_create_sound_group("SoundGroup");
    +// Etc.

    Warning

    While these handles are internally represented in the same way as GameMaker's built-in handles, they are not true handles from GameMaker's perspective.

    @@ -177,16 +176,210 @@

    Handles

    Error Handling

    In FMOD, functions always return whether they executed successfully. If not, they return an error code explaining the error that occurred.

    Most functions of the FMOD extension don't return this FMOD result directly. Instead, when you call a function of the FMOD extension, the result of the last called function is stored internally with the extension. You can retrieve this value using the function fmod_last_result. For example:

    -
    system = fmod_system_create();
    +
    system = fmod_system_create();
     result = fmod_last_result();
    -show_debug_message("Result of fmod_system_create: {0}", result);
    -
    +show_debug_message("Result of fmod_system_create: {0}", result);

    Note

    fmod_last_result returns FMOD_RESULT.OK in case there were no errors.

    Bug Reports

    If you experience a crash when using the FMOD extension, please create a bug report. This allows the GameMaker team to look into the issue and improve the FMOD extension.

    +

    Working with DSP Parameters

    +

    The FMOD extension allows you to get and set DSP parameters. The different parameters that you can get and set can be found on the Effect Parameters page as well as in the extension's Fmod_Definitions script asset.

    +

    The FMOD extension has the following functions to get and set DSP parameters:

    + +

    You should make sure to always use the extension function that corresponds to the data type that you want to get or set.

    +

    Simple Parameters

    +

    These are the integer, float and boolean DSP parameters. You can get or set them with a single function call.

    +

    For example, to set the type and size of an FFT DSP's window:

    +
    fmod_dsp_set_parameter_int(dsp_fft, FMOD_DSP_FFT.WINDOWTYPE, FMOD_DSP_FFT_WINDOW.RECT);
    +fmod_dsp_set_parameter_int(dsp_fft, FMOD_DSP_FFT.WINDOWSIZE, 16384);
    +

    Since the FMOD_DSP_FFT_WINDOWTYPE and FMOD_DSP_FFT_WINDOWSIZE variables of the FMOD_DSP_FFT struct are both of type int, you should get them with fmod_dsp_get_parameter_int and set them with fmod_dsp_set_parameter_int.

    +

    Similarly, a FMOD_DSP_HIGHPASS DSP's parameters are of type float. So you should get the parameters with fmod_dsp_get_parameter_float and set them with fmod_dsp_get_parameter_float:

    +
    // Set
    +fmod_dsp_set_parameter_float(dsp_hpf, FMOD_DSP_HIGHPASS.CUTOFF, 10000);
    +fmod_dsp_set_parameter_float(dsp_hpf, FMOD_DSP_HIGHPASS.RESONANCE, 4);
    +
    +// Get
    +var _cutoff = fmod_dsp_get_parameter_float(dsp_hpf, FMOD_DSP_HIGHPASS.CUTOFF);
    +var _resonance = fmod_dsp_get_parameter_float(dsp_hpf, FMOD_DSP_HIGHPASS.RESONANCE);
    +

    Data Parameters

    +

    The more complex DSP parameters are of a type that's referred to in the FMOD documentation as data. The FMOD extension allows you to set and get this data by writing to and reading from a Buffer respectively.

    +
    +

    Note

    +

    the function fmod_dsp_get_parameter_data returns the size of the data (in bytes). You need to resize the buffer if it's not large enough to store the data.

    +
    +

    The mapping between FMOD's data structs and the same data in a Buffer may not be straightforward, however. This section explains how you can read from and write to a buffer in the format that FMOD uses.

    +

    We'll have a look at two particular cases:

    + +
    +

    Note

    +

    See Guide_To_Using_Buffers for more information on how to work with buffers.

    +
    +

    FMOD_DSP_FFT

    +

    The FMOD_DSP_FFT DSP is an example of a DSP type that has a data parameter with a pointer variable: FMOD_DSP_FFT_SPECTRUMDATA. This is shown in the FMOD documentation as:

    +

    Parameter of type data in docs

    +

    You get the data of this parameter as follows:

    +
    fmod_dsp_get_parameter_data(dsp_fft, FMOD_DSP_FFT.SPECTRUMDATA, fft_buffer);
    +

    The FMOD extension will write the data to the buffer fft_buffer that you pass it.

    +

    How this data looks can be found under FMOD_DSP_PARAMETER_FFT, which is defined like this:

    +
    typedef struct FMOD_DSP_PARAMETER_FFT {
    +  int     length;
    +  int     numchannels;
    +  float   *spectrum[32];
    +} FMOD_DSP_PARAMETER_FFT;
    +

    Here, length stores the length of the spectrum array of a single channel (i.e. the number of values included in the spectrum). numchannels stores the number of channels for which there is spectrum data.

    +

    If you read these variable definitions line by line, you have:

    +

    An int followed by an int, followed by at most 32 times length floats. spectrum is an array of pointers (the asterisk * refers to a pointer), which indicates that the memory for each array is not included in the FMOD_DSP_PARAMETER_FFT struct itself, but rather in the memory that the pointer to that array points to. You don't need to do any buffer copying yourself however, as the extension copies these blocks of data to the buffer one after the other.

    +

    Looking at the Data Type Mapping Table, you see that this corresponds to 2 times a buffer_s32, followed by numchannels blocks of spectrum data consisting of length buffer_f32 values. So the layout of the data in the buffer will be the following:

    +
    |Channel |                      |Channel 0                                                |Channel 1                                                | ... |
    +|FMOD    |int       |int        |float         |float         | ... |float                |float         |float         | ... |float                | ... |
    +|Buffer  |buffer_s32|buffer_s32 |buffer_f32    |buffer_f32    | ... |buffer_f32           |buffer_f32    |buffer_f32    | ... |buffer_f32           | ... |
    +|Variable|length    |numchannels|spectrum[0][0]|spectrum[0][1]| ... |spectrum[0][length-1]|spectrum[1][0]|spectrum[1][1]| ... |spectrum[1][length-1]| ... |
    +|Offset  |0         |4          |8             |12            | ... |8 + (length-1)*4     |...           |              |     |                     | ... |
    +

    To read this data from the buffer, you'd do:

    +
    buffer_seek(fft_buffer, buffer_seek_start, 0);
    +var _length = buffer_read(fft_buffer, buffer_s32);
    +var _numchannels = buffer_read(fft_buffer, buffer_s32);
    +var _spectrum = array_create(_numchannels), _channel_index = 0, _bin_index;
    +repeat(_numchannels)
    +{
    +    _spectrum[_channel_index] = array_create(_length);
    +    _bin_index = 0;
    +    repeat(_length)
    +    {
    +        _spectrum[_channel_index][_bin_index++] = buffer_read(fft_buffer, buffer_f32);
    +    }
    +    _channel_index++;
    +}
    +

    FMOD_DSP_OBJECTPAN

    +

    The FMOD_DSP_OBJECTPAN DSP is a second example of a DSP type that has a data parameter. It actually has a number of data parameters: FMOD_DSP_OBJECTPAN_3D_POSITION, FMOD_DSP_OBJECTPAN_OVERALL_GAIN, and FMOD_DSP_OBJECTPAN_ATTENUATION_RANGE.

    +

    In this example we'll look at the FMOD_DSP_OBJECTPAN_3D_POSITION parameter, since it has nested structs. This parameter is of type FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI:

    +

    You get the data of this parameter as follows:

    +
    fmod_dsp_get_parameter_data(dsp_pan, FMOD_DSP_OBJECTPAN._3D_POSITION, pan_buffer);
    +

    The FMOD extension will write the data to the buffer pan_buffer that you pass it.

    +

    The struct FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI is defined as follows:

    +
    typedef struct FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI {
    +  int                  numlisteners;
    +  FMOD_3D_ATTRIBUTES   relative[FMOD_MAX_LISTENERS];
    +  float                weight[FMOD_MAX_LISTENERS];
    +  FMOD_3D_ATTRIBUTES   absolute;
    +} FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI;
    +

    Here, relative and weight are arrays. relative is an array of structs of type FMOD_3D_ATTRIBUTES:

    +
    typedef struct FMOD_3D_ATTRIBUTES {
    +  FMOD_VECTOR position;
    +  FMOD_VECTOR velocity;
    +  FMOD_VECTOR forward;
    +  FMOD_VECTOR up;
    +} FMOD_3D_ATTRIBUTES;
    +

    All variables in this struct are also structs. Each variable is of type FMOD_VECTOR:

    +
    typedef struct FMOD_VECTOR {
    +  float   x;
    +  float   y;
    +  float   z;
    +} FMOD_VECTOR;
    +

    Bringing all that together, an FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI struct looks as follows:

    +

    An int, followed by FMOD_MAX_LISTENERS times the following: 4 times 3 floats in a row (x, y and z), followed by FMOD_MAX_LISTENERS times a float that stores a weight, followed by another 4 times 3 floats (each also x, y and z).

    +

    To get and read the data from the buffer, you'd do:

    +

    function read_vector(_buffer)
    +{
    +    var _x = buffer_read(_buffer, buffer_f32);
    +    var _y = buffer_read(_buffer, buffer_f32);
    +    var _z = buffer_read(_buffer, buffer_f32);
    +
    +    return {x: _x, y: _y, z: _z};
    +}
    +
    +function read_3d_attributes(_buffer)
    +{
    +    var _position = read_vector(_buffer);
    +    var _velocity = read_vector(_buffer);
    +    var _forward = read_vector(_buffer);
    +    var _up = read_vector(_buffer);
    +
    +    return {position: _position, velocity: _velocity, forward: _forward, up: _up};
    +}
    +
    +buffer_seek(pan_buffer, buffer_seek_start, 0);
    +
    +var _numlisteners, _relative, _weight, _absolute;
    +var _pan_per_listener = array_create(_numlisteners);
    +
    +_numlisteners = buffer_read(pan_buffer, buffer_s32);
    +for(var i = 0;i < FMOD_MAX_LISTENERS;i++)
    +{
    +    _relative = read_3d_attributes(pan_buffer);
    +    if (i < FMOD_MAX_LISTENERS)
    +    {
    +        // Valid listener index
    +        _pan_per_listener[i] = {relative: _relative};
    +    }
    +}
    +for(var i = 0;i < FMOD_MAX_LISTENERS;i++)
    +{
    +    _weight = buffer_read(pan_buffer, buffer_f32);
    +    if (i < FMOD_MAX_LISTENERS)
    +    {
    +        // Valid listener index
    +        _pan_per_listener[i].weight = _weight;
    +    }
    +}
    +_absolute = read_3d_attributes(pan_buffer);
    +The code example above shows how to read the FMOD_DSP_OBJECTPAN_3D_POSITION parameter, which is of type FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI. +First, two functions read_vector and read_3d_attributes are defined to read a FMOD_VECTOR and a FMOD_3D_ATTRIBUTES from the buffer and return them as a Struct. +Then, the number of listeners is read and two for loops are executed, each loop executes FMOD_MAX_LISTENERS times. The first loop assigns a struct to the variable _pan_per_listener at the current listener index. The second loop assigns that struct the weight as an additional attribute weight. +Note that you always have to execute the loop this number of times. If _numlisteners is less than FMOD_MAX_LISTENERS, the required calls to buffer_read to "skip" the remaining unused listener data won't happen and subsequent reads will give wrong results. +Also note that you cannot read relative and weight in the same for loop. This is because the buffer stores all relative data, followed by all weights. +Finally, the absolute pan properties are read with another call to read_3d_attributes.

    +

    Data Type Mapping Table

    +

    The following table provides the mapping of FMOD (C++) data types to GameMaker's buffer data types.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FMOD C++ data typeBuffer data type
    intbuffer_s32
    unsigned intbuffer_u32
    floatbuffer_f32
    doublebuffer_f64
    boolbuffer_bool
    structSee the FMOD docs
    type[num] (array)num times data of type