// %BANNER_BEGIN% // --------------------------------------------------------------------- // %COPYRIGHT_BEGIN% // Copyright (c) (2018-2022) Magic Leap, Inc. All Rights Reserved. // Use of this file is governed by the Software License Agreement, located here: https://www.magicleap.com/software-license-agreement-ml2 // Terms and conditions applicable to third-party materials accompanying this distribution may also be found in the top-level NOTICE file appearing herein. // %COPYRIGHT_END% // --------------------------------------------------------------------- // %BANNER_END% // Disable warnings about missing documentation for native interop. #pragma warning disable 1591 namespace UnityEngine.XR.MagicLeap { using System; using System.Runtime.InteropServices; using MagicLeap.Native; /// /// Manages Audio. /// public sealed partial class MLAudioOutput { /// /// See ml_audio.h for additional comments. /// internal class NativeBindings : MagicLeapNativeBindings { /// /// The callback that occurs when the master volume changes. /// /// The value of the master volume. /// A pointer to the callback. public delegate void MLAudioMasterVolumeChangedCallback(float volume, IntPtr callback); /// /// Callback to notify when a media event has occurred. /// /// The new media event. /// A pointer to the callback. public delegate void MLAudioMediaEventCallback(MediaEvent mediaEvent, IntPtr callback); /// /// Gets the current audio output device. /// /// The audio output device. /// /// MLResult.Result will be MLResult.Code.Ok if successful. /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if failed due to internal error. /// MLResult.Result will be MLResult.Code.InvalidParam if input parameter is invalid. /// MLResult.Result will be MLResult.Code.NotImplemented. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioGetOutputDevice(out MLAudioOutput.Device device); /// /// Gets the value of the master volume. /// /// The value of the master volume. /// /// MLResult.Result will be MLResult.Code.Ok if successful. /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if failed due to internal error. /// MLResult.Result will be MLResult.Code.InvalidParam if input parameter is invalid. /// MLResult.Result will be MLResult.Code.NotImplemented. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioGetMasterVolume(out float volume); /// /// Registers a callback for when the master volume changes. /// /// A pointer to the callback. /// A generic data pointer passed back to the callback. /// /// MLResult.Result will be MLResult.Code.Ok if successful. /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if failed due to internal error. /// MLResult.Result will be MLResult.Code.AllocFailed if failed due to internal error. /// MLResult.Result will be MLResult.Code.NotImplemented. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioSetMasterVolumeCallback(MLAudioMasterVolumeChangedCallback callback, IntPtr data); /// /// Gets the result string for a MLResult.Code. /// /// The MLResult.Code to be requested. /// A pointer to the result string. [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr MLAudioGetResultString(MLResult.Code result); /// /// Enables/disables 3D audio processing for a sound output. /// /// MLHandle used to identify the sound output. /// Determines whether 3D processing is on or off. /// /// MLResult.Result will be MLResult.Code.Ok if successful. /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if failed due to internal error. /// MLResult.Result will be MLResult.Code.AudioHandleNotFound if handle was not found. /// MLResult.Result will be MLResult.Code.AudioInternalConfigError if internal config error. /// MLResult.Result will be MLResult.Code.NotImplemented. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioSetSpatialSoundEnable(ulong handle, bool enable); /// /// Enables/disables 3D audio processing for a sound output. /// /// MLHandle used to identify the sound output. /// Indicates whether 3D processing is on or off. /// /// MLResult.Result will be MLResult.Code.Ok if successful. /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if failed due to internal error. /// MLResult.Result will be MLResult.Code.AudioHandleNotFound if handle was not found. /// MLResult.Result will be MLResult.Code.AudioInternalConfigError if internal config error. /// MLResult.Result will be MLResult.Code.NotImplemented. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioGetSpatialSoundEnable(ulong handle, out bool enabled); /// /// Sets the 3D position for one channel of a sound output. /// /// MLHandle used to identify the sound output. /// Selects the channel whose position is being set. /// Struct to set the position /// /// MLResult.Result will be MLResult.Code.Ok if successful. /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if failed due to internal error. /// MLResult.Result will be MLResult.Code.AudioHandleNotFound if handle was not found. /// MLResult.Result will be MLResult.Code.AudioInternalConfigError if internal config error. /// MLResult.Result will be MLResult.Code.NotImplemented. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioSetSpatialSoundPosition(ulong handle, uint channel, [In] ref MagicLeapNativeBindings.MLVec3f position); /// /// Returns the 3D position for one channel of a sound output. /// /// MLHandle used to identify the sound output. /// Selects the channel whose position is being set. /// Struct to set the position /// /// MLResult.Result will be MLResult.Code.Ok if successful. /// MLResult.Result will be MLResult.Code.UnspecifiedFailure if failed due to internal error. /// MLResult.Result will be MLResult.Code.AudioHandleNotFound if handle was not found. /// MLResult.Result will be MLResult.Code.AudioInternalConfigError if internal config error. /// MLResult.Result will be MLResult.Code.NotImplemented. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioGetSpatialSoundPosition(ulong handle, uint channel, out MagicLeapNativeBindings.MLVec3f position); /// /// Registers a callback for user-issued media control events. Events that can result in a callback being called include: /// pressing a play button; pressing a stop button; pressing a pause button; pressing a next track button, pressing a /// previous track button; The particular event type (MLAudioMediaEvent) that caused the callback is passed to the callback as its /// first argument. The 'context' argument is passed back to the callback as its second argument. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioSetMediaEventCallback(MLAudioMediaEventCallback callback, IntPtr context); /// /// Setting this option on a sound output causes its output to bypass master volume, making /// it effectively "always audible" (assuming it is neither muted nor set to zero volume /// on a per-sound basis). This option can only be set on medical-enabled devices (60601 /// compliant), and will only work for non-spatial sounds.Non-spatial sound parameters /// such as volume, mute, pitch and looping are still in effect for sounds that are /// bypassing master volume. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioSetSoundBypassesMasterVolume(ulong audioHandle, [MarshalAs(UnmanagedType.I1)] bool isBypassing); /// /// Queries whether a sound output is exempt from attenuation due to master volume. /// This call reports whether the output from a sound output is bypassing master volume, /// making it effectively "always audible" (assuming it is neither muted nor set to zero volume /// on a per-sound basis). This option can only be set on medical-enabled devices(60601 /// compliant), and will only work for non-spatial sounds.Non-spatial sound parameters /// such as volume, mute, pitch and looping are still in effect for sounds that are /// bypassing master volume. /// [DllImport(AudioPlayerDLL, CallingConvention = CallingConvention.Cdecl)] public static extern MLResult.Code MLAudioGetSoundBypassesMasterVolume(ulong audioHandle, [MarshalAs(UnmanagedType.I1)] out bool isBypassing); [DllImport(MLSdkLoaderDll, CallingConvention = CallingConvention.Cdecl)] internal static extern ulong MLUnityAudioGetHandle(); [StructLayout(LayoutKind.Sequential)] public readonly struct MLAudioBufferFormat { public readonly uint ChannelCount; public readonly uint SamplesPerSecond; public readonly uint BitsPerSample; public readonly uint ValidBitsPerSample; public readonly MLAudioOutput.SampleFormatType SampleFormat; public readonly MLAudioOutput.ChannelFormatType ChannelFormat; public MLAudioBufferFormat(MLAudioOutput.BufferFormat bufferFormat) { this.ChannelCount = bufferFormat.ChannelCount; this.SamplesPerSecond = bufferFormat.SamplesPerSecond; this.BitsPerSample = bufferFormat.BitsPerSample; this.ValidBitsPerSample = bufferFormat.ValidBitsPerSample; this.SampleFormat = bufferFormat.SampleFormat; this.ChannelFormat = bufferFormat.ChannelFormat; } } [StructLayout(LayoutKind.Sequential)] public struct MLAudioBuffer { public IntPtr Ptr; public uint Size; public MLAudioBuffer(IntPtr ptr, uint size) { this.Ptr = ptr; this.Size = size; } } /// /// Properties specifying send levels for a spatial sound. /// [StructLayout(LayoutKind.Sequential)] public struct MLAudioSpatialSoundSendLevels { /// /// Volume scale (0-1) for all freqs. /// private readonly float gain; /// /// Volume scale (0-1) for low freqs. /// private readonly float gainLF; /// /// Volume scale (0-1) for mid freqs. /// private readonly float gainMF; /// /// Volume scale (0-1) for high freqs. /// private readonly float gainHF; public MLAudioSpatialSoundSendLevels(SpatialSound.SendLevels sendLevels) { this.gain = sendLevels.Gain; this.gainLF = sendLevels.GainLF; this.gainMF = sendLevels.GainMF; this.gainHF = sendLevels.GainHF; } } /// /// Properties specifying the distance response of a spatial sound. /// [StructLayout(LayoutKind.Sequential)] public struct MLAudioSpatialSoundDistanceProperties { /// /// Distance where sound is at full volume. /// private readonly float minDistance; /// /// Distance beyond which sound gets no quieter. /// private readonly float maxDistance; /// /// Modification to real-world distance response. /// private readonly float rolloffFactor; public MLAudioSpatialSoundDistanceProperties(SpatialSound.DistanceProperties distanceProperties) { this.minDistance = distanceProperties.MinDistance; this.maxDistance = distanceProperties.MaxDistance; this.rolloffFactor = distanceProperties.RolloffFactor; } } /// /// Properties specifying the directivity of a spatial sound. /// [StructLayout(LayoutKind.Sequential)] public struct MLAudioSpatialSoundRadiationProperties { /// /// Inner cone angle (0-360); radiation unaffected. /// private readonly float innerAngle; /// /// Outer cone angle (0-360); directivity at maximum. /// private readonly float outerAngle; /// /// Volume scale (0-1) beyond outer cone for all freqs. /// private readonly float outerGain; /// /// Volume scale (0-1) beyond outer cone for low freqs. /// private readonly float outerGainLF; /// /// Volume scale (0-1) beyond outer cone for mid freqs. /// private readonly float outerGainMF; /// /// Volume scale (0-1) beyond outer cone for high freqs. /// private readonly float outerGainHF; public MLAudioSpatialSoundRadiationProperties(SpatialSound.RadiationProperties radiationProperties) { this.innerAngle = radiationProperties.InnerAngle; this.outerAngle = radiationProperties.OuterAngle; this.outerGain = radiationProperties.OuterGain; this.outerGainLF = radiationProperties.OuterGainLF; this.outerGainMF = radiationProperties.OuterGainMF; this.outerGainHF = radiationProperties.OuterGainHF; } } } } }