// %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;
}
}
}
}
}