开发者

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

开发者 https://www.devze.com 2023-01-11 17:59 出处:网络
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?

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 th开发者_开发知识库at I could parse the MemoryStream to determine the duration of the wav file. Ideally I'd like to not re-invent the wheel.


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.


Try following calculation

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

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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号