forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			365 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			365 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
/************************************************************************************
 | 
						|
Filename    :   ONSPAudioSource.cs
 | 
						|
Content     :   Interface into the Oculus Native Spatializer Plugin
 | 
						|
Copyright   :   Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
 | 
						|
 | 
						|
Licensed under the Oculus SDK Version 3.5 (the "License"); 
 | 
						|
you may not use the Oculus SDK except in compliance with the License, 
 | 
						|
which is provided at the time of installation or download, or which 
 | 
						|
otherwise accompanies this software in either electronic or hard copy form.
 | 
						|
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
https://developer.oculus.com/licenses/sdk-3.5/
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, the Oculus SDK 
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
************************************************************************************/
 | 
						|
 | 
						|
// Uncomment below to test access of read-only spatializer parameters
 | 
						|
//#define TEST_READONLY_PARAMETERS
 | 
						|
 | 
						|
using UnityEngine;
 | 
						|
using System;
 | 
						|
using System.Collections;
 | 
						|
using System.Runtime.InteropServices;
 | 
						|
 | 
						|
public class ONSPAudioSource : MonoBehaviour
 | 
						|
{
 | 
						|
#if TEST_READONLY_PARAMETERS
 | 
						|
    // Spatializer read-only system parameters (global)
 | 
						|
    static int readOnly_GlobalRelectionOn = 8;
 | 
						|
    static int readOnly_NumberOfUsedSpatializedVoices = 9;
 | 
						|
#endif
 | 
						|
 | 
						|
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
 | 
						|
    static void OnBeforeSceneLoadRuntimeMethod()
 | 
						|
    {
 | 
						|
        OSP_SetGlobalVoiceLimit(ONSPSettings.Instance.voiceLimit);
 | 
						|
    }
 | 
						|
 | 
						|
    // Import functions
 | 
						|
    public const string strONSPS = "AudioPluginOculusSpatializer";
 | 
						|
 | 
						|
    [DllImport(strONSPS)]
 | 
						|
    private static extern void ONSP_GetGlobalRoomReflectionValues(ref bool reflOn, ref bool reverbOn, 
 | 
						|
                                                                  ref float width, ref float height, ref float length);
 | 
						|
 | 
						|
    // Public
 | 
						|
 | 
						|
    [SerializeField]
 | 
						|
	private bool enableSpatialization = true;
 | 
						|
	public  bool EnableSpatialization
 | 
						|
	{
 | 
						|
		get
 | 
						|
		{
 | 
						|
			return enableSpatialization;
 | 
						|
		}
 | 
						|
		set
 | 
						|
		{
 | 
						|
			enableSpatialization = value;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	[SerializeField]
 | 
						|
	private float gain = 0.0f;
 | 
						|
	public  float Gain
 | 
						|
	{
 | 
						|
		get
 | 
						|
		{
 | 
						|
			return gain;
 | 
						|
		}
 | 
						|
		set
 | 
						|
		{
 | 
						|
			gain = Mathf.Clamp(value, 0.0f, 24.0f);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	[SerializeField]
 | 
						|
	private bool useInvSqr = false;
 | 
						|
	public  bool UseInvSqr
 | 
						|
	{
 | 
						|
		get
 | 
						|
		{
 | 
						|
			return useInvSqr;
 | 
						|
		}
 | 
						|
		set
 | 
						|
		{
 | 
						|
			useInvSqr = value;		
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	[SerializeField]
 | 
						|
	private float near = 0.25f;
 | 
						|
	public float Near
 | 
						|
	{
 | 
						|
		get
 | 
						|
		{
 | 
						|
			return near;
 | 
						|
		}
 | 
						|
		set
 | 
						|
		{
 | 
						|
			near = Mathf.Clamp(value, 0.0f, 1000000.0f);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	[SerializeField]
 | 
						|
	private float far = 250.0f;
 | 
						|
	public float Far
 | 
						|
	{
 | 
						|
		get
 | 
						|
		{
 | 
						|
			return far;
 | 
						|
		}
 | 
						|
		set
 | 
						|
		{
 | 
						|
			far = Mathf.Clamp(value, 0.0f, 1000000.0f);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
    [SerializeField]
 | 
						|
    private float volumetricRadius = 0.0f;
 | 
						|
    public float VolumetricRadius
 | 
						|
    {
 | 
						|
        get
 | 
						|
        {
 | 
						|
            return volumetricRadius;
 | 
						|
        }
 | 
						|
        set
 | 
						|
        {
 | 
						|
            volumetricRadius = Mathf.Clamp(value, 0.0f, 1000.0f);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    [SerializeField]
 | 
						|
    private float reverbSend = 0.0f;
 | 
						|
    public float ReverbSend
 | 
						|
    {
 | 
						|
        get
 | 
						|
        {
 | 
						|
            return reverbSend;
 | 
						|
        }
 | 
						|
        set
 | 
						|
        {
 | 
						|
            reverbSend = Mathf.Clamp(value, -60.0f, 20.0f);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    [SerializeField]
 | 
						|
	private bool enableRfl = false;
 | 
						|
	public  bool EnableRfl
 | 
						|
	{
 | 
						|
		get
 | 
						|
		{
 | 
						|
			return enableRfl;
 | 
						|
		}
 | 
						|
		set
 | 
						|
		{
 | 
						|
			enableRfl = value;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	/// <summary>
 | 
						|
	/// Awake this instance.
 | 
						|
	/// </summary>
 | 
						|
	void Awake()
 | 
						|
	{
 | 
						|
		// We might iterate through multiple sources / game object
 | 
						|
		var source = GetComponent<AudioSource>();
 | 
						|
		SetParameters(ref source);
 | 
						|
	}
 | 
						|
 | 
						|
	/// <summary>
 | 
						|
	/// Start this instance.
 | 
						|
	/// </summary>
 | 
						|
    void Start()
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
	/// <summary>
 | 
						|
	/// Update this instance.
 | 
						|
	/// </summary>
 | 
						|
    void Update()
 | 
						|
    {
 | 
						|
		// We might iterate through multiple sources / game object
 | 
						|
		var source = GetComponent<AudioSource>();
 | 
						|
 | 
						|
        // READ-ONLY PARAMETER TEST      
 | 
						|
#if TEST_READONLY_PARAMETERS
 | 
						|
        float rfl_enabled = 0.0f;
 | 
						|
        source.GetSpatializerFloat(readOnly_GlobalRelectionOn, out rfl_enabled);
 | 
						|
        float num_voices = 0.0f;
 | 
						|
        source.GetSpatializerFloat(readOnly_NumberOfUsedSpatializedVoices, out num_voices);
 | 
						|
 | 
						|
        String readOnly = System.String.Format
 | 
						|
        ("Read only values: refl enabled: {0:F0} num voices: {1:F0}", rfl_enabled, num_voices);
 | 
						|
        Debug.Log(readOnly);
 | 
						|
#endif
 | 
						|
 | 
						|
        // Check to see if we should disable spatializion
 | 
						|
        if ((Application.isPlaying == false) || 
 | 
						|
            (AudioListener.pause == true) || 
 | 
						|
            (source.isPlaying == false) ||
 | 
						|
            (source.isActiveAndEnabled == false)
 | 
						|
           )
 | 
						|
        {
 | 
						|
            source.spatialize = false;
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            SetParameters(ref source);	
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    enum Parameters : int
 | 
						|
    {
 | 
						|
        P_GAIN = 0,
 | 
						|
        P_USEINVSQR,
 | 
						|
        P_NEAR,
 | 
						|
        P_FAR,
 | 
						|
        P_RADIUS,
 | 
						|
        P_DISABLE_RFL,
 | 
						|
        P_VSPEAKERMODE,
 | 
						|
        P_AMBISTAT,
 | 
						|
        P_READONLY_GLOBAL_RFL_ENABLED, // READ-ONLY
 | 
						|
        P_READONLY_NUM_VOICES, // READ-ONLY
 | 
						|
        P_SENDLEVEL,
 | 
						|
        P_NUM
 | 
						|
    };
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Sets the parameters.
 | 
						|
    /// </summary>
 | 
						|
    /// <param name="source">Source.</param>
 | 
						|
    public void SetParameters(ref AudioSource source)
 | 
						|
	{
 | 
						|
        // See if we should enable spatialization
 | 
						|
        source.spatialize = enableSpatialization;
 | 
						|
		
 | 
						|
        source.SetSpatializerFloat((int)Parameters.P_GAIN, gain);
 | 
						|
		// All inputs are floats; convert bool to 0.0 and 1.0
 | 
						|
		if(useInvSqr == true)
 | 
						|
            source.SetSpatializerFloat((int)Parameters.P_USEINVSQR, 1.0f);
 | 
						|
		else
 | 
						|
            source.SetSpatializerFloat((int)Parameters.P_USEINVSQR, 0.0f);
 | 
						|
 | 
						|
        source.SetSpatializerFloat((int)Parameters.P_NEAR, near);
 | 
						|
        source.SetSpatializerFloat((int)Parameters.P_FAR, far);
 | 
						|
 | 
						|
        source.SetSpatializerFloat((int)Parameters.P_RADIUS, volumetricRadius);
 | 
						|
 | 
						|
		if(enableRfl == true)
 | 
						|
            source.SetSpatializerFloat((int)Parameters.P_DISABLE_RFL, 0.0f);
 | 
						|
		else
 | 
						|
            source.SetSpatializerFloat((int)Parameters.P_DISABLE_RFL, 1.0f);
 | 
						|
 | 
						|
        source.SetSpatializerFloat((int)Parameters.P_SENDLEVEL, reverbSend);
 | 
						|
	}
 | 
						|
 | 
						|
    private static ONSPAudioSource RoomReflectionGizmoAS = null; 
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// 
 | 
						|
    /// </summary>
 | 
						|
    void OnDrawGizmos()
 | 
						|
    {
 | 
						|
        // Are we the first one created? make sure to set our static ONSPAudioSource
 | 
						|
        // for drawing out room parameters once
 | 
						|
        if(RoomReflectionGizmoAS == null)
 | 
						|
        {
 | 
						|
            RoomReflectionGizmoAS = this;
 | 
						|
        }
 | 
						|
 | 
						|
        Color c;
 | 
						|
        const float colorSolidAlpha = 0.1f;
 | 
						|
 | 
						|
        // Draw the near/far spheres
 | 
						|
 | 
						|
        // Near (orange)
 | 
						|
        c.r = 1.0f;
 | 
						|
        c.g = 0.5f;
 | 
						|
        c.b = 0.0f;
 | 
						|
        c.a = 1.0f;
 | 
						|
        Gizmos.color = c;
 | 
						|
        Gizmos.DrawWireSphere(transform.position, Near);
 | 
						|
        c.a = colorSolidAlpha;
 | 
						|
        Gizmos.color = c;
 | 
						|
        Gizmos.DrawSphere(transform.position, Near);
 | 
						|
 | 
						|
        // Far (red)
 | 
						|
        c.r = 1.0f;
 | 
						|
        c.g = 0.0f;
 | 
						|
        c.b = 0.0f;
 | 
						|
        c.a = 1.0f;
 | 
						|
        Gizmos.color = Color.red;
 | 
						|
        Gizmos.DrawWireSphere(transform.position, Far);
 | 
						|
        c.a = colorSolidAlpha;
 | 
						|
        Gizmos.color = c;
 | 
						|
        Gizmos.DrawSphere(transform.position, Far);
 | 
						|
        
 | 
						|
        // VolumetricRadius (purple)
 | 
						|
        c.r = 1.0f;
 | 
						|
        c.g = 0.0f;
 | 
						|
        c.b = 1.0f;
 | 
						|
        c.a = 1.0f;
 | 
						|
        Gizmos.color = c;
 | 
						|
        Gizmos.DrawWireSphere(transform.position, VolumetricRadius);
 | 
						|
        c.a = colorSolidAlpha;
 | 
						|
        Gizmos.color = c;
 | 
						|
        Gizmos.DrawSphere(transform.position, VolumetricRadius);
 | 
						|
 | 
						|
        // Draw room parameters ONCE only, provided reflection engine is on
 | 
						|
        if (RoomReflectionGizmoAS == this)
 | 
						|
        {
 | 
						|
            // Get global room parameters (write new C api to get reflection values)
 | 
						|
            bool reflOn    = false;
 | 
						|
            bool reverbOn  = false;
 | 
						|
            float width    = 1.0f;
 | 
						|
            float height   = 1.0f;
 | 
						|
            float length   = 1.0f;
 | 
						|
 | 
						|
            ONSP_GetGlobalRoomReflectionValues(ref reflOn, ref reverbOn, ref width, ref height, ref length);
 | 
						|
 | 
						|
            // TO DO: Get the room reflection values and render those out as well (like we do in the VST)
 | 
						|
 | 
						|
            if((Camera.main != null) && (reflOn == true))
 | 
						|
            {
 | 
						|
                // Set color of cube (cyan is early reflections only, white is with reverb on)
 | 
						|
                if(reverbOn == true)
 | 
						|
                    c = Color.white;
 | 
						|
                else
 | 
						|
                    c = Color.cyan;
 | 
						|
 | 
						|
                Gizmos.color = c;
 | 
						|
                Gizmos.DrawWireCube(Camera.main.transform.position, new Vector3(width, height, length));
 | 
						|
                c.a = colorSolidAlpha;
 | 
						|
                Gizmos.color = c;
 | 
						|
                Gizmos.DrawCube(Camera.main.transform.position, new Vector3(width, height, length));
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// 
 | 
						|
    /// </summary>
 | 
						|
    void OnDestroy() 
 | 
						|
    {
 | 
						|
        // We will null out single pointer instance
 | 
						|
        // of the room reflection gizmo since we are being destroyed.
 | 
						|
        // Any ONSPAS that is alive or born will re-set this pointer
 | 
						|
        // so that we only draw it once
 | 
						|
        if(RoomReflectionGizmoAS == this)
 | 
						|
        {
 | 
						|
            RoomReflectionGizmoAS = null;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    [System.Runtime.InteropServices.DllImport("AudioPluginOculusSpatializer")]
 | 
						|
    private static extern int OSP_SetGlobalVoiceLimit(int VoiceLimit);
 | 
						|
}
 |