aeroson

updated CustomAudioFileReader .cs

Sep 8th, 2015
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.83 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using NAudio.Wave.SampleProviders;
  4. using NAudio.Wave;
  5. using NAudio;
  6.  
  7. namespace RuntimeAudioClipLoader
  8. {
  9. /// <summary>
  10. /// AudioFormat enum, lists only supported formats
  11. /// </summary>
  12. public enum AudioFormat
  13. {
  14. wav,
  15. mp3,
  16. aiff,
  17. ogg,
  18. unknown = -1,
  19. }
  20.  
  21. /// <summary>
  22. /// This is a custom modified NAudio.Wave.AudioFileReader, with added support for ogg with NVorbis.NAudioSupport.VorbisWaveReader
  23. /// AudioFileReader simplifies opening an audio file in NAudio
  24. /// Simply pass in the filename, and it will attempt to open the
  25. /// file and set up a conversion path that turns into PCM IEEE float.
  26. /// ACM codecs will be used for conversion.
  27. /// It provides a volume property and implements both WaveStream and
  28. /// ISampleProvider, making it possibly the only stage in your audio
  29. /// pipeline necessary for simple playback scenarios
  30. /// </summary>
  31. internal class CustomAudioFileReader : WaveStream, ISampleProvider
  32. {
  33.  
  34. private WaveStream readerStream; // the waveStream which we will use for all positioning
  35. private readonly SampleChannel sampleChannel; // sample provider that gives us most stuff we need
  36. private readonly int destBytesPerSample;
  37. private readonly int sourceBytesPerSample;
  38. private readonly long length;
  39. private readonly object lockObject;
  40.  
  41.  
  42. /// <summary>
  43. /// Initializes a new instance of AudioFileReader
  44. /// </summary>
  45. /// <param name="stream">The file to open</param>
  46. public CustomAudioFileReader(Stream stream, AudioFormat format)
  47. {
  48. lockObject = new object();
  49. CreateReaderStream(stream, format);
  50. sourceBytesPerSample = (readerStream.WaveFormat.BitsPerSample / 8) * readerStream.WaveFormat.Channels;
  51. sampleChannel = new SampleChannel(readerStream, false);
  52. destBytesPerSample = 4 * sampleChannel.WaveFormat.Channels;
  53. length = SourceToDest(readerStream.Length);
  54. }
  55.  
  56. /// <summary>
  57. /// Creates the reader stream, supporting all filetypes in the core NAudio library,
  58. /// and ensuring we are in PCM format
  59. /// </summary>
  60. /// <param name="stream">File Name</param>
  61. private void CreateReaderStream(Stream stream, AudioFormat format)
  62. {
  63. if (format==AudioFormat.wav)
  64. {
  65. readerStream = new WaveFileReader(stream);
  66. if (readerStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm && readerStream.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat)
  67. {
  68. readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
  69. readerStream = new BlockAlignReductionStream(readerStream);
  70. }
  71. }
  72. else if (format == AudioFormat.mp3)
  73. {
  74. readerStream = new Mp3FileReader(stream);
  75. }
  76. else if (format == AudioFormat.aiff)
  77. {
  78. readerStream = new AiffFileReader(stream);
  79. }
  80. else if (format == AudioFormat.ogg)
  81. {
  82. readerStream = new NVorbis.NAudioSupport.VorbisWaveReader(stream);
  83. }
  84. else
  85. {
  86. UnityEngine.Debug.LogWarning("Audio format " + format + " is not supported");
  87. }
  88. /*else
  89. {
  90. // fall back to media foundation reader, see if that can play it
  91. readerStream = new MediaFoundationReader(fileName);
  92. }*/
  93. }
  94.  
  95. /// <summary>
  96. /// WaveFormat of this stream
  97. /// </summary>
  98. public override WaveFormat WaveFormat
  99. {
  100. get { return sampleChannel.WaveFormat; }
  101. }
  102.  
  103. /// <summary>
  104. /// Length of this stream (in bytes)
  105. /// </summary>
  106. public override long Length
  107. {
  108. get { return length; }
  109. }
  110.  
  111. /// <summary>
  112. /// Position of this stream (in bytes)
  113. /// </summary>
  114. public override long Position
  115. {
  116. get { return SourceToDest(readerStream.Position); }
  117. set { lock (lockObject) { readerStream.Position = DestToSource(value); } }
  118. }
  119.  
  120. /// <summary>
  121. /// Reads from this wave stream
  122. /// </summary>
  123. /// <param name="buffer">Audio buffer</param>
  124. /// <param name="offset">Offset into buffer</param>
  125. /// <param name="count">Number of bytes required</param>
  126. /// <returns>Number of bytes read</returns>
  127. public override int Read(byte[] buffer, int offset, int count)
  128. {
  129. var waveBuffer = new WaveBuffer(buffer);
  130. int samplesRequired = count / 4;
  131. int samplesRead = Read(waveBuffer.FloatBuffer, offset / 4, samplesRequired);
  132. return samplesRead * 4;
  133. }
  134.  
  135. /// <summary>
  136. /// Reads audio from this sample provider
  137. /// </summary>
  138. /// <param name="buffer">Sample buffer</param>
  139. /// <param name="offset">Offset into sample buffer</param>
  140. /// <param name="count">Number of samples required</param>
  141. /// <returns>Number of samples read</returns>
  142. public int Read(float[] buffer, int offset, int count)
  143. {
  144. lock (lockObject)
  145. {
  146. return sampleChannel.Read(buffer, offset, count);
  147. }
  148. }
  149.  
  150. /// <summary>
  151. /// Gets or Sets the Volume of this AudioFileReader. 1.0f is full volume
  152. /// </summary>
  153. public float Volume
  154. {
  155. get { return sampleChannel.Volume; }
  156. set { sampleChannel.Volume = value; }
  157. }
  158.  
  159. /// <summary>
  160. /// Helper to convert source to dest bytes
  161. /// </summary>
  162. private long SourceToDest(long sourceBytes)
  163. {
  164. return destBytesPerSample * (sourceBytes / sourceBytesPerSample);
  165. }
  166.  
  167. /// <summary>
  168. /// Helper to convert dest to source bytes
  169. /// </summary>
  170. private long DestToSource(long destBytes)
  171. {
  172. return sourceBytesPerSample * (destBytes / destBytesPerSample);
  173. }
  174.  
  175. /// <summary>
  176. /// Disposes this AudioFileReader
  177. /// </summary>
  178. /// <param name="disposing">True if called from Dispose</param>
  179. protected override void Dispose(bool disposing)
  180. {
  181. if (disposing)
  182. {
  183. if (readerStream != null)
  184. {
  185. readerStream.Dispose();
  186. readerStream = null;
  187. }
  188. }
  189. base.Dispose(disposing);
  190. }
  191. }
  192. }
Advertisement
Add Comment
Please, Sign In to add comment