/* 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(); } } } } }