getParameterInfo returns garbage in Unity

Running the following code on a playing event instance:

FMOD.ChannelGroup chGroup;
string name;
int _ignore;
uint _uignore;
int paramCount = 0;

Audio.CheckError(evtInstance.getChannelGroup(out chGroup), this);
Audio.CheckError(chGroup.getDSP(0, out dsp), this);

dsp.getInfo(out name, out _uignore, out _ignore, out _ignore, out _ignore);
s += string.Format("\n - {0}", name);

Audio.CheckError(dsp.getNumParameters(out paramCount), this);
for (int j = 0; j < paramCount; ++j)
Audio.CheckError(dsp.getParameterInfo(j, out paramDesc), this);
string paramName = new string(;
s += string.Format("\n   - param {0} : type: {1} name: '{2}' label: '{3}'",
    new string(,
    new string(paramDesc.label)

I get garbage data back from getParameterInfo, for instance:

- ChanGroup Fader
 - param 0 : type: -404006640 name: '' label: ''
 - param 1 : type: -404006640 name: '' label: ''

Same goes for paramDesc.desc, all useless data.

I’m using Unity 2017.2.5f1 and
fmodstudio11014_v2.unitypackage / FMOD Studio 1.10.14 64-bit Build #102821

Thanks very much for the info.

We are aware of this issue and have a task to investigate it further but do not have an ETA at this point.

Both the P/Invoke and structure are setup wrong.

Firstly the struct needs to marshal bytes, as this is fixed size. char in c# is 2-bytes wide, so 16 of those would be 32 bytes, which would not match the DLL.

public struct DSP_PARAMETER_DESC
    public DSP_PARAMETER_TYPE   type;            /* [w] Type of this parameter. */
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public byte[]               name;            /* [w] Name of the parameter to be displayed (ie "Cutoff frequency"). */
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public byte[]               label;           /* [w] Short string to be put next to value to denote the unit type (ie "hz"). */
    public string               description;     /* [w] Description of the parameter to be displayed as a help item / tooltip for this parameter. */


Then the P/Invoke needs to change, as the DLL’s GetParameterInfo allocates the result, and returns its pointer through a pointer to pointer.

private static extern RESULT FMOD5_DSP_GetParameterInfo          (IntPtr dsp, int index, out IntPtr pDesc);

Now as we only have the pointer, we need to marshal the actual struct before giving it to the managed layer.

public RESULT getParameterInfo(int index, out DSP_PARAMETER_DESC desc)
    IntPtr pDesc;
    RESULT rc = FMOD5_DSP_GetParameterInfo(this.handle, index, out pDesc);

    int szDesc = Marshal.SizeOf(typeof(DSP_PARAMETER_DESC));
    desc = Marshal.PtrToStructure<DSP_PARAMETER_DESC>(pDesc);

    return rc;

Finally, in case you want name / label as a managed string, you’ll need to use the ASCII encoding to convert from the bytes in your code.

        string name = Encoding.ASCII.GetString('\0');
        string label = Encoding.ASCII.GetString(desc.label).TrimEnd('\0');

Then it all works just fine.

Hope that helps - Andy


Thank you, Andy! This patch works for me.
I’m on the old C#, so I had to make a small change:

// desc = Marshal.PtrToStructure<DSP_PARAMETER_DESC>(pDesc);
desc = (DSP_PARAMETER_DESC) Marshal.PtrToStructure(pDesc,
1 Like