forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			127 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
//#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);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
}
 |