using Rive.Utils;
using UnityEngine;
namespace Rive.Components
{
///
/// Provides audio playback functionality for Rive Widgets.
/// This component is not supported in WebGL builds; on that platform, system audio is used instead of routing through Unity's AudioSource.
///
[RequireComponent(typeof(AudioSource))]
public class AudioProvider : MonoBehaviour
{
private AudioEngine m_audioEngine;
private AudioSource m_audioSource;
private bool m_isDestroyed = false;
///
/// The Rive Audio Engine instance used by this AudioProvider.
///
internal AudioEngine AudioEngine
{
get
{
if (m_audioEngine == null && !m_isDestroyed)
{
m_audioEngine = InitEngine();
}
return m_audioEngine;
}
}
///
/// The AudioSource component used for audio playback.
///
public AudioSource AudioSource
{
get
{
return m_audioSource;
}
}
private void Awake()
{
LogWebGLWarningIfNeeded();
m_audioSource = GetComponent();
if (m_audioSource == null)
{
DebugLogger.Instance.LogError($"AudioProvider component is missing an AudioSource component on the same game object.");
return;
}
// On iOS and Android, audio doesn't start automatically unless we call manually Play() here.
// It works fine in the Unity Editor and standalone PC/Mac builds without this, though.
// For consistency, we call Play() here always until we find a better solution.
if (!m_audioSource.isPlaying)
{
m_audioSource.Play();
}
}
void OnAudioFilterRead(float[] data, int channels)
{
if (m_audioEngine == null)
{
return;
}
m_audioEngine.Sum(data, channels);
}
private AudioEngine InitEngine()
{
int channelCount = 1;
switch (AudioSettings.speakerMode)
{
case AudioSpeakerMode.Mono:
channelCount = 1;
break;
case AudioSpeakerMode.Stereo:
channelCount = 2;
break;
case AudioSpeakerMode.Quad:
channelCount = 4;
break;
case AudioSpeakerMode.Surround:
channelCount = 5;
break;
case AudioSpeakerMode.Mode5point1:
channelCount = 6;
break;
case AudioSpeakerMode.Mode7point1:
channelCount = 8;
break;
case AudioSpeakerMode.Prologic:
channelCount = 2;
break;
}
return Rive.AudioEngine.Make(channelCount, AudioSettings.outputSampleRate);
}
private void LogWebGLWarningIfNeeded()
{
#if UNITY_WEBGL && !UNITY_EDITOR
DebugLogger.Instance.LogWarning($"The {nameof(AudioProvider)} component is not supported in WebGL builds. System audio will be used instead of routing audio through Unity's AudioSource.");
#endif
}
private void OnDestroy()
{
m_isDestroyed = true;
}
}
}