Getting time length of a .wav song
I have some songs in the resources of my application and want to get their time length so that I can set a timer to tick when the song ends. And then start the next song. I want to do that in my code, and get the time length of a song as an integer value.
I have been googling for it for many hours. I'm a beginner. So please try to explain in a simple language. Thanks in advance.
Re: Getting time length of a .wav song
There are two ways, a hard way (path of light) and an easy way (path of darkness).
The hard way:
Parse the header of your wav using this information:
https://ccrma.stanford.edu/courses/4...ts/WaveFormat/
Now, the Dark side way (using MCI):
vb.net Code:
Imports System.Runtime.InteropServices
Public Class MCI
<DllImport("winmm", setlasterror:=True, entrypoint:="mciSendString", CharSet:=CharSet.Auto)> _
Private Shared Function mciSendString( _
ByVal lpstrCommand As String, _
ByVal lpstrReturnString As String, _
ByRef uReturnLength As Integer, _
ByVal hwndCallBack As IntPtr) As Integer
End Function
Public Shared Function GetMediaLength(ByVal FileName As String) As ULong
Dim MediaLength As ULong
Dim RetString As New String(" "c, 50)
Dim CommandString As String
'open the media file
If Not IO.File.Exists(FileName) Then
Throw New IO.FileNotFoundException(String.Format("File {0} was not found.", FileName))
Return Nothing
End If
CommandString = "Open " & FileName & " alias MediaFile"
mciSendString(CommandString, String.Empty, 0, IntPtr.Zero)
'get the media file length
CommandString = "Set MediaFile time format milliseconds"
mciSendString(CommandString, String.Empty, 0, IntPtr.Zero)
CommandString = "Status MediaFile length"
mciSendString(CommandString, RetString, RetString.Length, IntPtr.Zero)
RetString = RetString.Trim
If Not ULong.TryParse(RetString, MediaLength) Then
MsgBox(String.Format("Failed to retrieve the media length for '{0}'.", FileName))
Return Nothing
End If
'close the media file
CommandString = "Close MediaFile"
mciSendString(CommandString, vbNullString, 0, IntPtr.Zero)
Return MediaLength
End Function
End Class
Usage:
vb.net Code:
MCI.GetMediaLength(filename) ' The return value will be in milliseconds.
By the way this same function also works with all media formats supported by MCI (Media Control Interface)
http://en.wikipedia.org/wiki/Media_Control_Interface
Re: Getting time length of a .wav song
Re: Getting time length of a .wav song
Wow! What a complication! I didn't understand neither of the ways. I copied and pasted the dark way. And used the MCI like this:
Timer3.Interval = MCI.GetMediaLength(music(0))
It gave me an error pointing to that line and saying:
InvalidCastException was unhandled
Converting from type "UnmanagedMemoryStream" to type "String" is invalid.
What's the problem? I'm a beginner and I don't get it. Visual Basic is supposed to have easier ways for stuff like that.
Re: Getting time length of a .wav song
You should provide a filename to it, not stream.
Re: Getting time length of a .wav song
After some struggle I got it working. Thanks. Visual Basic should have had simpler ways of doing such stuff.
Re: Getting time length of a .wav song
Just for the record, the so-called "hard way" isn't hard at all. In the header is a value, BytesPerSecond and we just divide this into the filesize (also in the header).
The following code is VB6, but perhaps someone would be kind enough to convert it to VB.NET.
Code:
Type RIFFHEADER
RIFFtag As String * 4 ' "RIFF"
Filesize As Long
WAVtag As String * 4 ' "WAVE"
FMTtag As String * 4 ' "fmt "
FMTsize As Long
CompressType As Integer
Channels As Integer
SampleRate As Long ' Samples per sec
BytesPerSec As Long ' = SampleRate * BytesPerSample
BytesPerSample As Integer
BitsPerSample As Integer
End Type
Dim WAVHEADER As RIFFHEADER
Function WavLength(ByVal wName As String) As Long ' length in seconds
Dim fv As Integer
fv = FreeFile
If Dir$(wName) = "" Then Exit Function ' ensure we only open an existing file
Open wName For Binary As fv
Get #fv, 1, WAVHEADER
Close #fv
With WAVHEADER
If .FMTtag <> "fmt " Then Exit Function
WavLength = .Filesize \ .BytesPerSec
End With
End Function
Re: Getting time length of a .wav song
I too am trying to get the duration of a WAV file. The dark side MCI does not work for many of my WAV files. I'm not sure why, they play fine, and the Windows explorer seems to report a valid duration.
I tried the above VB6 stuff and it works perfectly. I've been trying to get it converted to vb.net but i'm struggling. I can't figure out how to create a data structure or read a data stream into that data structure.
Any one know?
Re: Getting time length of a .wav song
I got something simple working--no error checking but you get the point
Private Function GetDuration(ByVal filename As String) As Double
Dim rifftag(4) As Char
Dim Filesize As Long
Dim WAVtag(4) As Char
Dim FMTtag(4) As Char
Dim FMTsize As Long
Dim compresstype As Integer
Dim channels As Integer
Dim samplerate As Long
Dim bytespersec As Long
Dim bytespersample As Integer
Dim bitspersample As Integer
Dim wavlength As Double
Dim reader = New BinaryReader(File.Open(strFileName, FileMode.Open))
rifftag = reader.ReadChars(4)
Filesize = reader.ReadInt32
WAVtag = reader.ReadChars(4)
FMTtag = reader.ReadChars(4)
FMTsize = reader.ReadInt32
compresstype = reader.ReadInt16
channels = reader.ReadInt16
samplerate = reader.ReadInt32
bytespersec = reader.ReadInt32
bytespersample = reader.ReadInt16
bitspersample = reader.ReadInt16
wavlength = (Filesize / bytespersec) * 1000 ' return in milliseconds
reader.Close()
Return wavlength
End Function