有没有办法在框架内或使用 P/Invoke 来确定内存流中保存的 wav 文件的持续时间?
我已经看过Managed DirectX和另一个类似的问题,但一切似乎都适用于路径,而不是提供任何传入流的方式。我引用的问题中的一个链接(A simple C# Wave editor ....)清楚地表明我可以解析MemoryStream
来确定 wav 文件的持续时间。理想情况下,我不想重新发明轮子。
有没有办法在框架内或使用 P/Invoke 来确定内存流中保存的 wav 文件的持续时间?
我已经看过Managed DirectX和另一个类似的问题,但一切似乎都适用于路径,而不是提供任何传入流的方式。我引用的问题中的一个链接(A simple C# Wave editor ....)清楚地表明我可以解析MemoryStream
来确定 wav 文件的持续时间。理想情况下,我不想重新发明轮子。
我同意亚历克斯。我花时间编写了一个包含三行代码的小程序,用于打印 wav 文件的持续时间。
var stream=new MemoryStream(File.ReadAllBytes("test.wav"));
var wave = new WaveFileReader(stream);
Console.WriteLine(wave.TotalTime); // wave.TotalTime -> TimeSpan
下载NAudio库:您会在包中找到 NAudio.dll。
只需在您的项目中引用 NAudio.dll。
在撰写本文时,它是 1.3 版。
正如作者在他的博客上所说,WaveFileReader 也接受一个Stream;不仅仅是文件路径。
请记住,版本 1.3 是为 x86 构建的。如果您希望它在 x64 上工作,您需要强制您的项目使用 x86。如果您想要用于 x64 的 NAudio.dll(像我一样),您需要使用“任何 cpu”重新编译。对我来说,这两种解决方案都很有魅力。
试试下面的计算
streamSize == headerSizeIfAny + playTime * 采样 * singleSampleSize ->
playTime = ( streamSize[in bytes] - headerSizeIfAny ) / ( sampling [samples per second] * singleSampleSize[bytes])
看一下这个:
http://www.sonicspot.com/guide/wavefiles.html
还有这个
typedef struct {
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;} WAVEFORMATEX;
所以你有你的记忆流......寻求0x10(跳过Riff头)+ 0x08(用于格式头)= 24
你在上面的结构中。
使用stream.ReadInt16()
andstream.ReadInt32()
来读取想要的结构成员。
然后,寻找 54,读取一个DWORD
,那么多字节就是你的样本数据。
然后从这些变量中计算出你的持续时间。
注意:这仅适用于存储在内存流中的最简单的 PCM 波形文件。对于其他人,您必须尊重标头并正确解析它们,找到数据块并根据其大小计算持续时间。