2025-06-07 17:43:34 +08:00

185 lines
5.6 KiB
C#

/* Copyright (C) 2014 DaikonForge */
namespace DaikonForge.VoIP
{
using UnityEngine;
/// <summary>
/// Implements an audio player which writes to a streaming audio clip
/// </summary>
[AddComponentMenu("DFVoice/Unity Audio Player")]
[RequireComponent(typeof(AudioSource))]
public class UnityAudioPlayer : MonoBehaviour, IAudioPlayer
{
public AudioClip testClip;
public bool PlayingSound
{
get
{
return GetComponent<AudioSource>().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 * LocalVoiceController.RecordMaxLength, 1, frequency, false);
// backwards compatibility
if (GetComponent<AudioSource>() == null)
gameObject.AddComponent<AudioSource>();
GetComponent<AudioSource>().clip = playClip;
GetComponent<AudioSource>().Stop();
GetComponent<AudioSource>().loop = false;
if (testClip != null)
{
GetComponent<AudioSource>().PlayOneShot(testClip);
}
GetComponent<AudioSource>().spatialBlend = IsThreeDimensional ? 1f : 0f;
}
//PS:unity4.x用边解码边播放会出现不连贯的问题,unity5不会,注意使用
//void Update()
//{
// if (GetComponent<AudioSource>().isPlaying)
// {
// if (lastTime > GetComponent<AudioSource>().timeSamples)
// {
// played += GetComponent<AudioSource>().clip.samples;
// }
// lastTime = GetComponent<AudioSource>().timeSamples;
// currentGain = Mathf.MoveTowards(currentGain, targetGain, Time.deltaTime * EqualizeSpeed);
// if (played + GetComponent<AudioSource>().timeSamples >= totalWritten)
// {
// GetComponent<AudioSource>().Pause();
// delayForFrames = 2;
// }
// }
//}
void OnDestroy()
{
Destroy(GetComponent<AudioSource>().clip);
}
public void SetSampleRate(int sampleRate, int seconds)
{
//if( GetComponent<AudioSource>() == null ) return;
//if( GetComponent<AudioSource>().clip != null && GetComponent<AudioSource>().clip.frequency == sampleRate ) return;
this.frequency = sampleRate;
if (GetComponent<AudioSource>().clip != null)
Destroy(GetComponent<AudioSource>().clip);
playClip = AudioClip.Create( "vc", frequency * seconds, 1, frequency, false);
GetComponent<AudioSource>().clip = playClip;
GetComponent<AudioSource>().Stop();
GetComponent<AudioSource>().loop = false;
writeHead = 0;
totalWritten = 0;
//delayForFrames = 0;
//lastTime = 0;
//played = 0;
}
public void BufferAudio(BigArray<float> audioData)
{
//if (GetComponent<AudioSource>() == null) return;
float[] temp = TempArray<float>.Obtain(audioData.Length);
audioData.CopyTo(0, temp, 0, audioData.Length * 4);
if (Equalize)
{
float maxAmp = AudioUtils.GetMaxAmplitude(temp);
targetGain = TargetEqualizeVolume / maxAmp;
//currentGain = Mathf.MoveTowards(currentGain, targetGain, Time.deltaTime * EqualizeSpeed);
if (targetGain > MaxEqualization)
targetGain = MaxEqualization;
if (targetGain < currentGain)
{
currentGain = targetGain;
}
AudioUtils.ApplyGain(temp, targetGain);
}
playClip.SetData(temp, writeHead);
TempArray<float>.Release(temp);
writeHead += audioData.Length;
totalWritten += audioData.Length;
writeHead %= playClip.samples;
//PS:unity4.x用边解码边播放会出现不连贯的问题,unity5不会,注意使用
//Debug.LogWarning("---" + writeHead);
//if (!GetComponent<AudioSource>().isPlaying)
//{
// delayForFrames--;
// if (delayForFrames <= 0)
// {
// GetComponent<AudioSource>().Play();
// }
//}
}
public void Play(string filePath)
{
//StartCoroutine(PlayBack(filePath));
GetComponent<AudioSource>().Play();
}
public AudioClip GetAudioClip()
{
//return GetComponent<AudioSource>().clip;
return playClip;
}
//System.Collections.IEnumerator PlayBack(string filePath)
//{
// WWW www = new WWW("file://" + filePath);
// yield return www;
// AudioClip clip = www.GetAudioClipCompressed(false,AudioType.OGGVORBIS);
// AudioSource source = GetComponent<AudioSource>();
// source.PlayOneShot(clip);
//}
}
}