BufferedAudioStream.cs
2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//#define VERBOSE_LOGGING
using UnityEngine;
using System.Collections;
using System;
using Oculus.Platform;
public class BufferedAudioStream {
const bool VerboseLogging = false;
AudioSource audio;
float[] audioBuffer;
int writePos;
const float bufferLengthSeconds = 0.25f;
const int sampleRate = 48000;
const int bufferSize = (int)(sampleRate * bufferLengthSeconds);
const float playbackDelayTimeSeconds = 0.05f;
float playbackDelayRemaining;
float remainingBufferTime;
public BufferedAudioStream(AudioSource audio) {
audioBuffer = new float[bufferSize];
this.audio = audio;
audio.loop = true;
audio.clip = AudioClip.Create("", bufferSize, 1, sampleRate, false);
Stop();
}
public void Update () {
if(remainingBufferTime > 0)
{
#if VERBOSE_LOGGING
Debug.Log(string.Format("current time: {0}, remainingBufferTime: {1}", Time.time, remainingBufferTime));
#endif
if (!audio.isPlaying && remainingBufferTime > playbackDelayTimeSeconds)
{
playbackDelayRemaining -= Time.deltaTime;
if (playbackDelayRemaining <= 0)
{
#if VERBOSE_LOGGING
Debug.Log("Starting playback");
#endif
audio.Play();
}
}
if (audio.isPlaying)
{
remainingBufferTime -= Time.deltaTime;
if (remainingBufferTime < 0)
{
remainingBufferTime = 0;
}
}
}
if (remainingBufferTime <= 0)
{
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?");
}
}
}
}
void Stop()
{
audio.Stop();
audio.time = 0;
writePos = 0;
playbackDelayRemaining = playbackDelayTimeSeconds;
}
public void AddData(float[] samples) {
int remainingWriteLength = samples.Length;
if(writePos > audioBuffer.Length) {
throw new Exception();
}
do {
int writeLength = remainingWriteLength;
int remainingSpace = audioBuffer.Length - writePos;
if(writeLength > remainingSpace) {
writeLength = remainingSpace;
}
Array.Copy(samples, 0, audioBuffer, writePos, writeLength);
remainingWriteLength -= writeLength;
writePos += writeLength;
if(writePos > audioBuffer.Length) {
throw new Exception();
}
if(writePos == audioBuffer.Length) {
writePos = 0;
}
} while(remainingWriteLength > 0);
#if VERBOSE_LOGGING
float prev = remainingBufferTime;
#endif
remainingBufferTime += (float)samples.Length / sampleRate;
#if VERBOSE_LOGGING
Debug.Log(string.Format("previous remaining: {0}, new remaining: {1}, added {2} samples", prev, remainingBufferTime, samples.Length));
#endif
audio.clip.SetData(audioBuffer, 0);
}
}