/* Copyright (C) 2014 DaikonForge */
namespace DaikonForge.VoIP
{
using UnityEngine;
///
/// Implements an audio player which writes to a streaming audio clip
///
[AddComponentMenu( "DFVoice/Unity Audio Player" )]
[RequireComponent( typeof( AudioSource ) )]
public class UnityAudioPlayer : MonoBehaviour, IAudioPlayer
{
public bool PlayingSound
{
get
{
return GetComponent().isPlaying;
}
}
public bool IsThreeDimensional = false;
public bool Equalize = false;
public float EqualizeSpeed = 1f;
public float TargetEqualizeVolume = 0.75f;
public float MaxEqualization = 5f;
private int frequency = 16000;
private int writeHead = 0;
private int totalWritten = 0;
private AudioClip playClip;
private int delayForFrames = 0;
private int lastTime = 0;
private int played = 0;
private float currentGain = 1f;
private float targetGain = 1f;
void Start()
{
playClip = AudioClip.Create( "vc", frequency * 10, 1, frequency, false );
// backwards compatibility
if( GetComponent() == null )
gameObject.AddComponent();
GetComponent().clip = playClip;
GetComponent().Stop();
GetComponent().loop = true;
GetComponent().spatialBlend = IsThreeDimensional ? 1f : 0f;
}
void Update()
{
if( GetComponent().isPlaying )
{
if( lastTime > GetComponent().timeSamples )
{
played += GetComponent().clip.samples;
}
lastTime = GetComponent().timeSamples;
currentGain = Mathf.MoveTowards( currentGain, targetGain, Time.deltaTime * EqualizeSpeed );
if( played + GetComponent().timeSamples >= totalWritten )
{
GetComponent().Pause();
delayForFrames = 2;
}
}
}
void OnDestroy()
{
Destroy( GetComponent().clip );
}
public void SetSampleRate( int sampleRate )
{
if( GetComponent() == null ) return;
if( GetComponent().clip != null && GetComponent().clip.frequency == sampleRate ) return;
this.frequency = sampleRate;
if( GetComponent().clip != null )
Destroy( GetComponent().clip );
playClip = AudioClip.Create( "vc", frequency * 10, 1, frequency, false );
GetComponent().clip = playClip;
GetComponent().Stop();
GetComponent().loop = true;
writeHead = 0;
totalWritten = 0;
delayForFrames = 0;
lastTime = 0;
played = 0;
}
public void BufferAudio( BigArray audioData )
{
if( GetComponent() == null ) return;
float[] temp = TempArray.Obtain( audioData.Length );
audioData.CopyTo( 0, temp, 0, audioData.Length * 4 );
if( Equalize )
{
float maxAmp = AudioUtils.GetMaxAmplitude( temp );
targetGain = TargetEqualizeVolume / maxAmp;
if( targetGain > MaxEqualization )
targetGain = MaxEqualization;
if( targetGain < currentGain )
{
currentGain = targetGain;
}
AudioUtils.ApplyGain( temp, currentGain );
}
playClip.SetData( temp, writeHead );
TempArray.Release( temp );
writeHead += audioData.Length;
totalWritten += audioData.Length;
writeHead %= playClip.samples;
if( !GetComponent().isPlaying )
{
delayForFrames--;
if( delayForFrames <= 0 )
{
GetComponent().Play();
}
}
}
}
}