Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
2.9 KiB

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