110 lines
2.0 KiB
C#
110 lines
2.0 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
public class BufferedAudioStream
|
|
{
|
|
private const bool VerboseLogging = false;
|
|
|
|
private AudioSource audio;
|
|
|
|
private float[] audioBuffer;
|
|
|
|
private int writePos;
|
|
|
|
private const float bufferLengthSeconds = 0.25f;
|
|
|
|
private const int sampleRate = 48000;
|
|
|
|
private const int bufferSize = 12000;
|
|
|
|
private const float playbackDelayTimeSeconds = 0.05f;
|
|
|
|
private float playbackDelayRemaining;
|
|
|
|
private float remainingBufferTime;
|
|
|
|
public BufferedAudioStream(AudioSource audio)
|
|
{
|
|
audioBuffer = new float[12000];
|
|
this.audio = audio;
|
|
audio.loop = true;
|
|
audio.clip = AudioClip.Create(string.Empty, 12000, 1, 48000, false);
|
|
Stop();
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (remainingBufferTime > 0f)
|
|
{
|
|
if (!audio.isPlaying && remainingBufferTime > 0.05f)
|
|
{
|
|
playbackDelayRemaining -= Time.deltaTime;
|
|
if (playbackDelayRemaining <= 0f)
|
|
{
|
|
audio.Play();
|
|
}
|
|
}
|
|
if (audio.isPlaying)
|
|
{
|
|
remainingBufferTime -= Time.deltaTime;
|
|
if (remainingBufferTime < 0f)
|
|
{
|
|
remainingBufferTime = 0f;
|
|
}
|
|
}
|
|
}
|
|
if (remainingBufferTime <= 0f)
|
|
{
|
|
if (audio.isPlaying)
|
|
{
|
|
Debug.Log("Buffer empty, stopping " + DateTime.Now);
|
|
Stop();
|
|
}
|
|
else if (writePos != 0)
|
|
{
|
|
Debug.LogError("writePos non zero while not playing, how did this happen?");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Stop()
|
|
{
|
|
audio.Stop();
|
|
audio.time = 0f;
|
|
writePos = 0;
|
|
playbackDelayRemaining = 0.05f;
|
|
}
|
|
|
|
public void AddData(float[] samples)
|
|
{
|
|
int num = samples.Length;
|
|
if (writePos > audioBuffer.Length)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
do
|
|
{
|
|
int num2 = num;
|
|
int num3 = audioBuffer.Length - writePos;
|
|
if (num2 > num3)
|
|
{
|
|
num2 = num3;
|
|
}
|
|
Array.Copy(samples, 0, audioBuffer, writePos, num2);
|
|
num -= num2;
|
|
writePos += num2;
|
|
if (writePos > audioBuffer.Length)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
if (writePos == audioBuffer.Length)
|
|
{
|
|
writePos = 0;
|
|
}
|
|
}
|
|
while (num > 0);
|
|
remainingBufferTime += (float)samples.Length / 48000f;
|
|
audio.clip.SetData(audioBuffer, 0);
|
|
}
|
|
}
|