从MemoryStream打开音频(wav)文件以确定持续时间

时间:2010-08-17 12:34:24

标签: c# audio stream wav memorystream

是否有一种方法,在框架内或使用P / Invoke来确定在MemoryStream中保存的wav文件的持续时间?

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

3 个答案:

答案 0 :(得分:6)

我同意Alex的观点。 我花时间整理了一个包含三行代码的小程序,用于打印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。 如果您想要NA64.dll for x64(像我一样),您需要使用'any cpu'重新编译。 对我来说,这两种解决方案都像魅力一样。

答案 1 :(得分:0)

尝试以下计算

streamSize == headerSizeIfAny + playTime * sampling * singleSampleSize - >

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

答案 2 :(得分: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()stream.ReadInt32()来阅读想要的结构成员。

然后,寻求54,读一个DWORD,那么多个字节就是你的样本数据。

然后从这些变量中找出你的持续时间。

注意:这仅适用于存储在内存流中的简单PCM wave文件。对于其他人,你必须尊重标题并正确解析它们,找到数据块并根据它的大小计算持续时间。