Opening an audio (wav) file from a MemoryStream to determine the duration

大憨熊 提交于 2019-12-22 08:31:53

问题


Is there a way, either within the Framework or by using P/Invoke to determine the duration of a wav file that's held in a MemoryStream?

I've already had a look at Managed DirectX and another similar question, but everything seems to work with paths, rather than providing any way to pass in a stream. One of the links in the question I've referenced (A simple C# Wave editor....) makes it fairly clear that I could parse the MemoryStream to determine the duration of the wav file. Ideally I'd like to not re-invent the wheel.


回答1:


I agree with Alex. I took the time to put together a small program with three lines of code that prints the duration of a wav file.

        var stream=new MemoryStream(File.ReadAllBytes("test.wav"));
        var wave = new WaveFileReader(stream);
        Console.WriteLine(wave.TotalTime); // wave.TotalTime -> TimeSpan

Download NAudio library: you will find NAudio.dll in the package.

Just reference NAudio.dll in your project.

At time of writing it's release 1.3.

Like the author says on his blog, WaveFileReader accept a Stream too; not just a file path.

Remember that version 1.3 is built for x86. If you want it to work on x64 you need to force your project to x86. If you want NAudio.dll for x64 (like me) you need to recompile with 'any cpu'. For me both solutions worked like a charm.




回答2:


Try following calculation

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

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




回答3:


Check this out:

http://www.sonicspot.com/guide/wavefiles.html

and this

typedef struct {
  WORD wFormatTag; 
  WORD nChannels; 
  DWORD nSamplesPerSec; 
  DWORD nAvgBytesPerSec; 
  WORD nBlockAlign; 
  WORD wBitsPerSample; 
  WORD cbSize;} WAVEFORMATEX; 

So you have your memorystream... Seek to 0x10 (to skip Riff header) + 0x08 (for format header) = 24

And you are in the structure above.

Use stream.ReadInt16() and stream.ReadInt32() to read wanted structure members.

Then, seek to 54, read one DWORD, and that many bytes is your sample data.

Then figure out your duration from this variables.

NOTE: that will work for ONLY THE SIMPLEST PCM wave files stored in your memorystream. For others, you'll have to honor headers and properly parse them, finding the data chunk and calculating duration according to it's size.



来源:https://stackoverflow.com/questions/3502408/opening-an-audio-wav-file-from-a-memorystream-to-determine-the-duration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!