<p>In the uncompressed situation I know I need to read the wav header, pull out the number of channels, bits, and sample rate and work it out from there:
(channels) * (bits) * (samples/s) * (seconds) = (filesize)</p>

<p>Is there a simpler way - a free library, or something in the .net framework perhaps?</p>

<p>How would I do this if the .wav file is compressed (with the mpeg codec for example)?</p>

[{'answer_id': 82344, 'author': 'xan', 'author_id': 15667, 'author_profile': 'https://Stackoverflow.com/users/15667', 'pm_score': 1, 'selected': False, 'text': '<p>You might find that the <a href="http://msdn.microsoft.com/en-us/xna/default.aspx" rel="nofollow noreferrer">XNA library</a> has some support for working with WAV\'s etc. if you are willing to go down that route. It is designed to work with C# for game programming, so might just take care of what you need.</p>\n'}, {'answer_id': 82364, 'author': 'moobaa', 'author_id': 3569, 'author_profile': 'https://Stackoverflow.com/users/3569', 'pm_score': 1, 'selected': False, 'text': '<p>There\'s a bit of a tutorial (with - presumably - working code you can leverage) over at <a href="http://www.codeproject.com/KB/audio-video/WaveEdit.aspx" rel="nofollow noreferrer">CodeProject</a>.</p>\n\n<p>The only thing you have to be a little careful of is that it\'s perfectly "normal" for a WAV file to be composed of multiple chunks - so you have to scoot over the entire file to ensure that all chunks are accounted for.</p>\n'}, {'answer_id': 82379, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 1, 'selected': False, 'text': "<p>What exactly is your application doing with compressed WAVs?  Compressed WAV files are always tricky - I always try and use an alternative container format in this case such as OGG or WMA files.  The XNA libraries tend to be designed to work with specific formats - although it is possible that within XACT you'll find a more generic wav playback method.  A possible alternative is to look into the SDL C# port, although I've only ever used it to play uncompressed WAVs - once opened you can query the number of samples to determine the length.</p>\n"}, {'answer_id': 82394, 'author': 'Cetra', 'author_id': 15087, 'author_profile': 'https://Stackoverflow.com/users/15087', 'pm_score': 2, 'selected': False, 'text': '<p>In the .net framework there is a mediaplayer class:</p>\n\n<p><a href="http://msdn.microsoft.com/en-us/library/system.windows.media.mediaplayer_members.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/system.windows.media.mediaplayer_members.aspx</a></p>\n\n<p>Here is an example:</p>\n\n<p><a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2667714&amp;SiteID=1&amp;pageid=0#2685871" rel="nofollow noreferrer">http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2667714&amp;SiteID=1&amp;pageid=0#2685871</a></p>\n'}, {'answer_id': 82408, 'author': 'Jan Zich', 'author_id': 15716, 'author_profile': 'https://Stackoverflow.com/users/15716', 'pm_score': 6, 'selected': True, 'text': '<p>You may consider using the mciSendString(...) function (error checking is omitted for clarity):</p>\n\n<pre><code>using System;\nusing System.Text;\nusing System.Runtime.InteropServices;\n\nnamespace Sound\n{\n    public static class SoundInfo\n    {\n        [DllImport("winmm.dll")]\n        private static extern uint mciSendString(\n            string command,\n            StringBuilder returnValue,\n            int returnLength,\n            IntPtr winHandle);\n\n        public static int GetSoundLength(string fileName)\n        {\n            StringBuilder lengthBuf = new StringBuilder(32);\n\n            mciSendString(string.Format("open \\"{0}\\" type waveaudio alias wave", fileName), null, 0, IntPtr.Zero);\n            mciSendString("status wave length", lengthBuf, lengthBuf.Capacity, IntPtr.Zero);\n            mciSendString("close wave", null, 0, IntPtr.Zero);\n\n            int length = 0;\n            int.TryParse(lengthBuf.ToString(), out length);\n\n            return length;\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 82439, 'author': 'sieben', 'author_id': 1147, 'author_profile': 'https://Stackoverflow.com/users/1147', 'pm_score': 1, 'selected': False, 'text': '<p>I\'m gonna have to say <a href="http://mediainfo.sourceforge.net/en" rel="nofollow noreferrer">MediaInfo</a>, I have been using it for over a year with a audio/video encoding application I\'m working on. It gives all the information for wav files along with almost every other format.</p>\n\n<p><a href="http://sourceforge.net/project/showfiles.php?group_id=86862&amp;package_id=90614" rel="nofollow noreferrer">MediaInfoDll</a> Comes with sample C# code on how to get it working.</p>\n'}, {'answer_id': 83276, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>I\'m going to assume that you\'re somewhat familiar with the structure of a .WAV file : it contains a WAVEFORMATEX header struct, followed by a number of other structs (or "chunks") containing various kinds of information.  See <a href="http://en.wikipedia.org/wiki/WAV" rel="nofollow noreferrer">Wikipedia</a> for more info on the file format.</p>\n\n<p>First, iterate through the .wav file and add up the the unpadded lengths of the "data" chunks (the "data" chunk contains the audio data for the file; usually there is only one of these, but it\'s possible that there could be more than one).  You now have the total size, in bytes, of the audio data.</p>\n\n<p>Next, get the "average bytes per second" member of the WAVEFORMATEX header struct of the file.</p>\n\n<p>Finally, divide the total size of the audio data by the average bytes per second - this will give you the duration of the file, in seconds.</p>\n\n<p>This works reasonably well for uncompressed and compressed files.</p>\n'}, {'answer_id': 396113, 'author': 'Lars', 'author_id': 42809, 'author_profile': 'https://Stackoverflow.com/users/42809', 'pm_score': 3, 'selected': False, 'text': '<p>I had difficulties with the example of the MediaPlayer-class above. It could take some time, before the player has opened the file. In the "real world" you have to register for the MediaOpened-event, after that has fired, the NaturalDuration is valid.\nIn a console-app you just have to wait a few seconds after the open.</p>\n\n<pre><code>using System;\nusing System.Text;\nusing System.Windows.Media;\nusing System.Windows;\n\nnamespace ConsoleApplication2\n{\n  class Program\n  {\n    static void Main(string[] args)\n    {\n      if (args.Length == 0)\n        return;\n      Console.Write(args[0] + ": ");\n      MediaPlayer player = new MediaPlayer();\n      Uri path = new Uri(args[0]);\n      player.Open(path);\n      TimeSpan maxWaitTime = TimeSpan.FromSeconds(10);\n      DateTime end = DateTime.Now + maxWaitTime;\n      while (DateTime.Now &lt; end)\n      {\n        System.Threading.Thread.Sleep(100);\n        Duration duration = player.NaturalDuration;\n        if (duration.HasTimeSpan)\n        {\n          Console.WriteLine(duration.TimeSpan.ToString());\n          break;\n        }\n      }\n      player.Close();\n    }\n  }\n}\n</code></pre>\n'}, {'answer_id': 2009777, 'author': 'Josh Stodola', 'author_id': 54420, 'author_profile': 'https://Stackoverflow.com/users/54420', 'pm_score': 3, 'selected': False, 'text': '<p>Not to take anything away from the answer already accepted, but I was able to get the duration of an audio file (several different formats, including AC3, which is what I needed at the time) using the  <code>Microsoft.DirectX.AudioVideoPlayBack</code> namespace.  This is part of <a href="http://msdn.microsoft.com/en-us/library/bb318658(VS.85).aspx" rel="noreferrer">DirectX 9.0 for Managed Code</a>.  Adding a reference to that made my code as simple as this...</p>\n\n<pre><code>Public Shared Function GetDuration(ByVal Path As String) As Integer\n    If File.Exists(Path) Then\n        Return CInt(New Audio(Path, False).Duration)\n    Else\n        Throw New FileNotFoundException("Audio File Not Found: " &amp; Path)\n    End If\nEnd Function\n</code></pre>\n\n<p>And it\'s pretty fast, too!  Here\'s a reference for the <a href="http://msdn.microsoft.com/en-us/library/bb324224(VS.85).aspx" rel="noreferrer">Audio</a> class.</p>\n'}, {'answer_id': 8181938, 'author': 'Monti Pal', 'author_id': 1053726, 'author_profile': 'https://Stackoverflow.com/users/1053726', 'pm_score': 5, 'selected': False, 'text': '<p>Download NAudio.dll\nfrom the link\n<a href="https://www.dll-files.com/naudio.dll.html" rel="nofollow noreferrer">https://www.dll-files.com/naudio.dll.html</a></p>\n<p>and then use this function</p>\n<pre><code>public static TimeSpan GetWavFileDuration(string fileName)       \n{     \n    WaveFileReader wf = new WaveFileReader(fileName);\n    return wf.TotalTime; \n}\n</code></pre>\n<p>you will get the  Duration</p>\n'}, {'answer_id': 12416165, 'author': 'Neoheurist', 'author_id': 1670042, 'author_profile': 'https://Stackoverflow.com/users/1670042', 'pm_score': -1, 'selected': False, 'text': '<pre><code>Imports System.IO\nImports System.Text\n\nImports System.Math\nImports System.BitConverter\n\nPublic Class PulseCodeModulation\n    \' Pulse Code Modulation WAV (RIFF) file layout\n\n    \' Header chunk\n\n    \' Type   Byte Offset  Description\n    \' Dword       0       Always ASCII "RIFF"\n    \' Dword       4       Number of bytes in the file after this value (= File Size - 8)\n    \' Dword       8       Always ASCII "WAVE"\n\n    \' Format Chunk\n\n    \' Type   Byte Offset  Description\n    \' Dword       12      Always ASCII "fmt "\n    \' Dword       16      Number of bytes in this chunk after this value\n    \' Word        20      Data format PCM = 1 (i.e. Linear quantization)\n    \' Word        22      Channels Mono = 1, Stereo = 2\n    \' Dword       24      Sample Rate per second e.g. 8000, 44100\n    \' Dword       28      Byte Rate per second (= Sample Rate * Channels * (Bits Per Sample / 8))\n    \' Word        32      Block Align (= Channels * (Bits Per Sample / 8))\n    \' Word        34      Bits Per Sample e.g. 8, 16\n\n    \' Data Chunk\n\n    \' Type   Byte Offset  Description\n    \' Dword       36      Always ASCII "data"\n    \' Dword       40      The number of bytes of sound data (Samples * Channels * (Bits Per Sample / 8))\n    \' Buffer      44      The sound data\n\n    Dim HeaderData(43) As Byte\n\n    Private AudioFileReference As String\n\n    Public Sub New(ByVal AudioFileReference As String)\n        Try\n            Me.HeaderData = Read(AudioFileReference, 0, Me.HeaderData.Length)\n        Catch Exception As Exception\n            Throw\n        End Try\n\n        \'Validate file format\n\n        Dim Encoder As New UTF8Encoding()\n\n        If "RIFF" &lt;&gt; Encoder.GetString(BlockCopy(Me.HeaderData, 0, 4)) Or _\n            "WAVE" &lt;&gt; Encoder.GetString(BlockCopy(Me.HeaderData, 8, 4)) Or _\n            "fmt " &lt;&gt; Encoder.GetString(BlockCopy(Me.HeaderData, 12, 4)) Or _\n            "data" &lt;&gt; Encoder.GetString(BlockCopy(Me.HeaderData, 36, 4)) Or _\n            16 &lt;&gt; ToUInt32(BlockCopy(Me.HeaderData, 16, 4), 0) Or _\n            1 &lt;&gt; ToUInt16(BlockCopy(Me.HeaderData, 20, 2), 0) _\n        Then\n            Throw New InvalidDataException("Invalid PCM WAV file")\n        End If\n\n        Me.AudioFileReference = AudioFileReference\n    End Sub\n\n    ReadOnly Property Channels() As Integer\n        Get\n            Return ToUInt16(BlockCopy(Me.HeaderData, 22, 2), 0) \'mono = 1, stereo = 2\n        End Get\n    End Property\n\n    ReadOnly Property SampleRate() As Integer\n        Get\n            Return ToUInt32(BlockCopy(Me.HeaderData, 24, 4), 0) \'per second\n        End Get\n    End Property\n\n    ReadOnly Property ByteRate() As Integer\n        Get\n            Return ToUInt32(BlockCopy(Me.HeaderData, 28, 4), 0) \'sample rate * channels * (bits per channel / 8)\n        End Get\n    End Property\n\n    ReadOnly Property BlockAlign() As Integer\n        Get\n            Return ToUInt16(BlockCopy(Me.HeaderData, 32, 2), 0) \'channels * (bits per sample / 8)\n        End Get\n    End Property\n\n    ReadOnly Property BitsPerSample() As Integer\n        Get\n            Return ToUInt16(BlockCopy(Me.HeaderData, 34, 2), 0)\n        End Get\n    End Property\n\n    ReadOnly Property Duration() As Integer\n        Get\n            Dim Size As Double = ToUInt32(BlockCopy(Me.HeaderData, 40, 4), 0)\n            Dim ByteRate As Double = ToUInt32(BlockCopy(Me.HeaderData, 28, 4), 0)\n            Return Ceiling(Size / ByteRate)\n        End Get\n    End Property\n\n    Public Sub Play()\n        Try\n            My.Computer.Audio.Play(Me.AudioFileReference, AudioPlayMode.Background)\n        Catch Exception As Exception\n            Throw\n        End Try\n    End Sub\n\n    Public Sub Play(playMode As AudioPlayMode)\n        Try\n            My.Computer.Audio.Play(Me.AudioFileReference, playMode)\n        Catch Exception As Exception\n            Throw\n        End Try\n    End Sub\n\n    Private Function Read(AudioFileReference As String, ByVal Offset As Long, ByVal Bytes As Long) As Byte()\n        Dim inputFile As System.IO.FileStream\n\n        Try\n            inputFile = IO.File.Open(AudioFileReference, IO.FileMode.Open)\n        Catch Exception As FileNotFoundException\n            Throw New FileNotFoundException("PCM WAV file not found")\n        Catch Exception As Exception\n            Throw\n        End Try\n\n        Dim BytesRead As Long\n        Dim Buffer(Bytes - 1) As Byte\n\n        Try\n            BytesRead = inputFile.Read(Buffer, Offset, Bytes)\n        Catch Exception As Exception\n            Throw\n        Finally\n            Try\n                inputFile.Close()\n            Catch Exception As Exception\n                \'Eat the second exception so as to not mask the previous exception\n            End Try\n        End Try\n\n        If BytesRead &lt; Bytes Then\n            Throw New InvalidDataException("PCM WAV file read failed")\n        End If\n\n        Return Buffer\n    End Function\n\n    Private Function BlockCopy(ByRef Source As Byte(), ByVal Offset As Long, ByVal Bytes As Long) As Byte()\n        Dim Destination(Bytes - 1) As Byte\n\n        Try\n            Buffer.BlockCopy(Source, Offset, Destination, 0, Bytes)\n        Catch Exception As Exception\n            Throw\n        End Try\n\n        Return Destination\n    End Function\nEnd Class\n</code></pre>\n'}, {'answer_id': 21500321, 'author': 'Aleks', 'author_id': 3258422, 'author_profile': 'https://Stackoverflow.com/users/3258422', 'pm_score': 2, 'selected': False, 'text': '<p>Try code below from <a href="http://alvas.net/alvas.audio,tips.aspx#tip25" rel="nofollow">How to determine the length of a .wav file in C#</a></p>\n\n<pre><code>    string path = @"c:\\test.wav";\n    WaveReader wr = new WaveReader(File.OpenRead(path));\n    int durationInMS = wr.GetDurationInMS();\n    wr.Close();\n</code></pre>\n'}, {'answer_id': 40933199, 'author': 'Manish Nayak', 'author_id': 4732757, 'author_profile': 'https://Stackoverflow.com/users/4732757', 'pm_score': 3, 'selected': False, 'text': '<p>Yes, There is a free library that can be used to get time duration of Audio file. This library also provides many more functionalities.</p>\n\n<p><a href="http://taglib.org/" rel="noreferrer"><strong>TagLib</strong></a></p>\n\n<p>TagLib is distributed under the GNU Lesser General Public License (LGPL) and Mozilla Public License (MPL).</p>\n\n<p>I implemented below code that returns time duration in seconds.</p>\n\n<pre><code>using TagLib.Mpeg;\n\npublic static double GetSoundLength(string FilePath)\n{\n    AudioFile ObjAF = new AudioFile(FilePath);\n    return ObjAF.Properties.Duration.TotalSeconds;\n}\n</code></pre>\n'}, {'answer_id': 52929705, 'author': 'Martin Abilev', 'author_id': 7424574, 'author_profile': 'https://Stackoverflow.com/users/7424574', 'pm_score': 1, 'selected': False, 'text': '<p>time = FileLength / (Sample Rate * Channels * Bits per sample /8)</p>\n'}, {'answer_id': 54192641, 'author': 'item.wu', 'author_id': 10915057, 'author_profile': 'https://Stackoverflow.com/users/10915057', 'pm_score': 2, 'selected': False, 'text': '<p>i have tested blew code would fail,file formats are like "\\\\ip\\dir\\*.wav\'</p>\n\n<pre><code> public static class SoundInfo\n   {\n     [DllImport("winmm.dll")]\n     private static extern uint mciSendString\n     (\n        string command,\n        StringBuilder returnValue,\n        int returnLength,\n        IntPtr winHandle\n     );\n\n     public static int GetSoundLength(string fileName)\n      {\n        StringBuilder lengthBuf = new StringBuilder(32);\n\n        mciSendString(string.Format("open \\"{0}\\" type waveaudio alias wave", fileName), null, 0, IntPtr.Zero);\n        mciSendString("status wave length", lengthBuf, lengthBuf.Capacity, IntPtr.Zero);\n        mciSendString("close wave", null, 0, IntPtr.Zero);\n\n        int length = 0;\n        int.TryParse(lengthBuf.ToString(), out length);\n\n        return length;\n    }\n}\n</code></pre>\n\n<p>while naudio works</p>\n\n<pre><code>    public static int GetSoundLength(string fileName)\n     {\n        using (WaveFileReader wf = new WaveFileReader(fileName))\n        {\n            return (int)wf.TotalTime.TotalMilliseconds;\n        }\n     }`\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/82319', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1078/']