Welcome to the Oculus Developer Forums!

Your participation on the forum is subject to the Oculus Code of Conduct.

In general, please be respectful and kind. If you violate the Oculus Code of Conduct, your access to the developer forums may be revoked at the discretion of Oculus staff.

FMOD low level API: spatializer doesn't work

Hi guys,

        I have spent last months with testing OSP in FMOD low-level API in c#. I can't use it from FMOD studio because I'm blind and it isn't usable for me. I traversed through many forums but I'm still struggling. Please help me.

Problem description
I can hear no spatialization and no reverb room effects and the sound sounds a bit muffled.

        My code

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

using FMOD;

namespace FmodOculusTest
{
    internal enum OspGlobalsParamIndex
    {
        ReflectionEngineEnabled, // bool
        ReverbEnabled,            // bool
        GlobalScale,              // float
        BypasAll,                // bypass
        RoomWidth,                // float
        RoomHeight,               // float
        RoomLength,               // float
        RefLeft,                  // float
        RefRight,                 // float
        RefUP,                    // float
        RefDown,                  // float
        RefNear,                  // float
        RefFar,                   // float
        ReverbRangeMin,          // float
        ReverbRangeMax,          // float

        OspGlobalsPINDEXNumParameters
    };

    internal enum OspParamIndex
    {
        SoundPosition,           // FMOD_DSP_PARAMETER_3DATTRIBUTES - both absolute and relative to camera
        ReflectionsEnabled,      // bool
        AttenuationEnabled,      // bool
        SourceVolumetricRadius, // float
        SourceRangeMin,         // float
        SourceRangeMax,         // float
        OspNumParameters
    };

    internal enum OspParamIndexAmbisonic
    {
        SoundPosition,         // FMOD_DSP_PARAMETER_3DATTRIBUTES - both absolute and relative to camera
        VirtualSpeakerMode,   // bool - OculusAmbi vs. Virtual Speakers

        OspAmbisonicNumParameters
    };

    internal class OvrTest
    {
        private uint _hrtfHandle;
        private Channel _channel;
        private ChannelGroup _masterGroup;
        private DSP _sharedReverb;
        private Sound _sound;
        private DSP _spatializerDSP;
        private ChannelGroup _spatializerGroup;
        private FMOD.System _system;

        public OvrTest()
        {
            // initialization
            ECheck(Factory.System_Create(out _system), "Creating context");
            ECheck(_system.init(1024, INITFLAGS.NORMAL, IntPtr.Zero), "FMOD initialization");

            // načtení pluginu Oculus Spatializer
            ECheck(_system.loadPlugin("OculusSpatializerFMOD.dll", out _hrtfHandle), "Loading plugin");

            // Creating DSP
            ECheck(_system.createDSPByPlugin(_hrtfHandle, out _spatializerDSP), "Creating DSP " + nameof(_spatializerDSP));
            ECheck(_system.createDSPByPlugin(_hrtfHandle + 2, out _sharedReverb), "Creating DSP " + nameof(_sharedReverb));

            // Optaining master channel group and creating group for spatialization
            ECheck(_system.getMasterChannelGroup(out _masterGroup), "Optaining master channel group");
            ECheck(_system.createChannelGroup("spatializer", out _spatializerGroup), "Creating channel group " + nameof(_spatializerGroup));

            // Adding DSP into channel group
            ECheck(_spatializerGroup.addDSP(CHANNELCONTROL_DSP_INDEX.HEAD, _spatializerDSP), "Adding DSP into channel group");
            ECheck(_masterGroup.addDSP(CHANNELCONTROL_DSP_INDEX.HEAD, _sharedReverb), "Adding DSP into channel group");

            // Shared reverb parameters
            ECheck(_sharedReverb.setParameterBool((int)OspGlobalsParamIndex.ReflectionEngineEnabled, true), "Enabling reverberation");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RoomWidth, 10f), "Setting room width");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RoomLength, 20f), "Setting room length");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RoomHeight, 4f), "Setting room height");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RefLeft, 1f), "Setting left wall reflection");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RefRight, 1f), "Setting right wall reflection");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RefUP, 1f), "Setting ceiling reflection");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RefDown, 1f), "Setting floor reflection");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RefNear, 1f), "Setting near reflection");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.RefFar, 1f), "Setting far reflection");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.ReverbRangeMin, 1f), "Setting ReverbRangeMin");
            ECheck(_sharedReverb.setParameterFloat((int)OspGlobalsParamIndex.ReverbRangeMax, 6f), "Setting ReverbRangeMax");

            ECheck(_sharedReverb.setParameterBool((int)OspGlobalsParamIndex.ReverbEnabled, true), "Enbaling reverberation");
            ECheck(_sharedReverb.setParameterBool((int)OspGlobalsParamIndex.BypasAll, false), "Switching bypas parameter off");
        }

        public void Play()
        {
            // Playing sound
            string fileName = "sound.wav";
            ECheck(_system.createSound(fileName, MODE.DEFAULT, out _sound), "Loading sound");
            ECheck(_system.playSound(_sound, _spatializerGroup, true, out _channel), "Playing sound");

            // Setting parameters
            ECheck(_spatializerDSP.setParameterBool((int)OspParamIndex.AttenuationEnabled, true), "Enabling attenuation");
            ECheck(_spatializerDSP.setParameterFloat((int)OspParamIndex.SourceVolumetricRadius, 11f), "Setting volumetric radius");

            // Setting sound position
            DSP_PARAMETER_3DATTRIBUTES attributes = new DSP_PARAMETER_3DATTRIBUTES()
            {
                absolute = new ATTRIBUTES_3D()
                {
                    velocity = new VECTOR() { x = 8f, y = 5f, z = 2f },
                    position = new VECTOR() { x = -14f, y = 0f, z = 0f }
                },

                relative = new ATTRIBUTES_3D()
                {
                    velocity = new VECTOR() { x = 2f, y = 4f, z = 7f },
                    position = new VECTOR() { x = -14f, y = 0f, z = 0f }
                }
            };

            // Putting structure into parameter
            int attributesSize = Marshal.SizeOf(typeof(ATTRIBUTES_3D));
            IntPtr attributesPtr = Marshal.AllocHGlobal(attributesSize);
            Marshal.StructureToPtr(attributes, attributesPtr, false);
            ECheck(_spatializerDSP.setParameterData(0, GetBytes(attributesPtr,
                                                                             attributesSize)), "Putting structure into parameter");
            Marshal.FreeHGlobal(attributesPtr);

            _channel.setPaused(false);
        }

        public void Release()
        {
            _system.release();
        }

        private static byte[] GetBytes(IntPtr ptr, int length)
        {
            if (ptr != IntPtr.Zero)
            {
                byte[] byteArray = new byte[length];
                Marshal.Copy(ptr, byteArray, 0, length);
                return byteArray;
            }
            // Return an empty array if the pointer is null.
            return new byte[1];
        }

        //mt

        //mtd

        private void ECheck(RESULT r, string activity)
        {
            if (r != RESULT.OK)
            {
                Say($"Chyba: {activity}.");
                Application.Exit();
            }
        }

        private void Say(string text)
                    => MessageBox.Show(text);

        //mtd
    }//cls
} //nsp
Tagged:
Sign In or Register to comment.