4

有没有办法在框架内或使用 P/Invoke 来确定内存流中保存的 wav 文件的持续时间?

我已经看过Managed DirectX和另一个类似的问题,但一切似乎都适用于路径,而不是提供任何传入流的方式。我引用的问题中的一个链接(A simple C# Wave editor ....)清楚地表明我可以解析MemoryStream来确定 wav 文件的持续时间。理想情况下,我不想重新发明轮子。

4

3 回答 3

6

我同意亚历克斯。我花时间编写了一个包含三行代码的小程序,用于打印 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”重新编译。对我来说,这两种解决方案都很有魅力。

于 2010-11-09T16:51:00.860 回答
0

试试下面的计算

streamSize == headerSizeIfAny + playTime * 采样 * singleSampleSize ->

playTime = ( streamSize[in bytes] - headerSizeIfAny ) / ( sampling [samples per second] * singleSampleSize[bytes])

于 2010-09-01T14:38:29.687 回答
0

看一下这个:

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 波形文件。对于其他人,您必须尊重标头并正确解析它们,找到数据块并根据其大小计算持续时间。

于 2010-10-20T16:24:31.857 回答