WaveLoader.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using NAudio.Flac;
  2. using NAudio.Wave;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. namespace SongVocalIsolateAutomation.AudioProcessing
  8. {
  9. internal class WaveLoader
  10. {
  11. public static WaveData LoadFlac(string path, bool trimZeroPrefix = true)
  12. {
  13. using (var waveStream = new FlacReader(path))
  14. {
  15. var waveFormat = waveStream.WaveFormat;
  16. var allSamples = ReadAllSamples(waveStream, waveFormat);
  17. allSamples = trimZeroPrefix
  18. ? allSamples.SkipWhile(p => p == 0).ToArray()
  19. : allSamples;
  20. return new WaveData(allSamples, waveFormat.Channels, waveFormat.SampleRate);
  21. }
  22. }
  23. private static float[] ReadAllSamples(WaveStream waveStream, WaveFormat waveFormat)
  24. {
  25. if (WaveFormatEncoding.Pcm != waveFormat.Encoding)
  26. throw new NotSupportedException("PCM only support");
  27. if (16 != waveFormat.BitsPerSample && 24 != waveFormat.BitsPerSample)
  28. throw new NotSupportedException("16 or 24 bit per sample only support");
  29. float[] allSamples;
  30. {
  31. waveStream.Seek(0, SeekOrigin.Begin);
  32. var sampleData = new List<float>((int)((waveStream.TotalTime.TotalSeconds + 1) * waveFormat.SampleRate));
  33. if (16 == waveFormat.BitsPerSample)
  34. {
  35. var buffer = new byte[waveFormat.BlockAlign];
  36. while (true)
  37. {
  38. var read = waveStream.Read(buffer, 0, buffer.Length);
  39. if (buffer.Length != read) break;
  40. for (var i = 0; i < waveFormat.BlockAlign; i++)
  41. {
  42. //little-endian
  43. var value = (short)(buffer[i] | (buffer[++i] << 8));
  44. sampleData.Add(value / 32768f);
  45. }
  46. }
  47. }
  48. if (24 == waveFormat.BitsPerSample)
  49. {
  50. var buffer = new byte[waveFormat.BlockAlign];
  51. while (true)
  52. {
  53. var read = waveStream.Read(buffer, 0, buffer.Length);
  54. if (buffer.Length != read) break;
  55. for (var i = 0; i < waveFormat.BlockAlign; i++)
  56. {
  57. //little-endian
  58. var value = (int)(buffer[i] | (buffer[++i] << 8) | (buffer[++i] << 24));
  59. sampleData.Add(value / 2147483648f);
  60. }
  61. }
  62. }
  63. allSamples = sampleData.ToArray();
  64. }
  65. return allSamples;
  66. }
  67. }
  68. }