PocAsioDSFPlay.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using System;
  2. using System.Linq.Expressions;
  3. using System.Runtime.InteropServices;
  4. using System.Threading;
  5. using System.Threading.Channels;
  6. using Bmp.Core.Playback.Inputs;
  7. using Bmp.Core.Playback.Outputs.NAudioASIO;
  8. namespace Bmp.Poc.PoCs;
  9. internal static class PocAsioDSFPlay
  10. {
  11. public static void MainFunc()
  12. {
  13. var dsfFilePath = Const.FileDsf;
  14. var asioDriverName = "Creative SB USB DSD ASIO Device";
  15. var dsfStream = new DsfSourceStream(dsfFilePath);
  16. var drv = new AsioDriverExt(asioDriverName);
  17. drv.Future_SetIoFormat_DSD();
  18. var flagDSD1 = drv.Future_GetIoFormat_Is_DSD();
  19. if (flagDSD1)
  20. {
  21. var flag = drv.IsSampleRateSupported(dsfStream.SampleRate);
  22. if (flag) drv.SetSampleRate(dsfStream.SampleRate, false);
  23. else throw new NotSupportedException("Failure to set sample rate");
  24. }
  25. else
  26. {
  27. throw new NotSupportedException("Device is not support DSD");
  28. }
  29. var nbSamples = drv.CreateBuffers(dsfStream.ChannelNum, 0, false);
  30. var outputBufBytes = nbSamples / 8;
  31. var channelBlockBuf = new byte[dsfStream.BlockSizePerChannel * dsfStream.ChannelNum];
  32. var channelOffset = 0;
  33. //生产者-消费者 模式, 结束检测
  34. bool ReadBlock()
  35. {
  36. var readCount = 0;
  37. do
  38. {
  39. var read = dsfStream.Read(channelBlockBuf, readCount, channelBlockBuf.Length - readCount);
  40. if (read == 0) return false;
  41. readCount += read;
  42. } while (readCount < channelBlockBuf.Length);
  43. return true;
  44. }
  45. ReadBlock();
  46. drv.FillBufferCallback = (inputChannels, outputChannels) =>
  47. {
  48. for (int iBuf = 0; iBuf < outputBufBytes; iBuf++)
  49. {
  50. for (int ich = 0; ich < dsfStream.ChannelNum; ich++)
  51. {
  52. Marshal.WriteByte(outputChannels[ich] + iBuf, channelBlockBuf[dsfStream.BlockSizePerChannel * ich + channelOffset]);
  53. }
  54. channelOffset++;
  55. if (channelOffset >= dsfStream.BlockSizePerChannel)
  56. {
  57. if (!ReadBlock())
  58. {
  59. drv.Stop(); //END
  60. return;
  61. }
  62. channelOffset = 0;
  63. }
  64. }
  65. };
  66. drv.Start();
  67. while (true)
  68. {
  69. Console.WriteLine($"{dsfStream.CurrentTime}");
  70. Thread.Sleep(3000);
  71. dsfStream.CurrentTime += TimeSpan.FromSeconds(-1);
  72. }
  73. }
  74. }