2

First, Thank You for considering my question. I have searched for a solution to this problem, and have not found anything that makes use of the modern Visual Studio features/libraries/namespaces, etc...

I need to determine the duration (length of time) of a WAV audio file. I would like to get the results in milliseconds - I can format the data to my needs from there.

Can you please provide an example of how this might be done?

THANK YOU

fdcpp
  • 1,677
  • 1
  • 14
  • 25
iic1tls
  • 63
  • 5
  • Do you currently have any code at all? – fdcpp Jan 06 '21 at 10:13
  • No - Unfortunately, after navigating Microsoft docs, I have not found anything at all on this subject. THANK YOU – iic1tls Jan 06 '21 at 11:10
  • Which language are you using? And in that language do you have a basic example of how to open a file? – fdcpp Jan 06 '21 at 11:45
  • I am working with Visual Studio 2019 - Visual Basic. As I mentioned, I am looking for an example of using Visual Basic's standard Libraries/Namespaces to perform this task. – iic1tls Jan 06 '21 at 14:04
  • In that case it will be worthwhile adding a [vb.net] tag to your question and you should get the right attention. Visual Studio can be used to program anything really, so it won't be enough to go on – fdcpp Jan 06 '21 at 14:37
  • That said, this question [VB.NET getting the attributes of a .wav file](https://stackoverflow.com/questions/780304/vb-net-getting-the-attributes-of-a-wav-file) leads to [How can I determine the length (i.e. duration) of a .wav file in C#?](https://stackoverflow.com/questions/82319/how-can-i-determine-the-length-i-e-duration-of-a-wav-file-in-c) – fdcpp Jan 06 '21 at 14:39
  • Thank You for that advise, however, I have done that before posting here. I dont want to waste people's time like that... – iic1tls Jan 06 '21 at 14:46
  • I'm not sure I follow. You'll be very unlikely to find an audience that can answer your question if you don't make it easy for them to find. With regard to wasting time, so long as you can supply a very simple code example of what you have so far along with what you have attempted in order to find an answer, then you will not be wasting anyone's time. – fdcpp Jan 06 '21 at 15:18
  • Do you have a code example of how to perform this task? Do you program in Visual Basic? I'm asking if someone could please post an example of how to do this. THANK YOU – iic1tls Jan 06 '21 at 15:20
  • 2
    The best way to get the most out of SO is to provide as much as you can up front so that other can fill in the blanks. Asking for a a straight up solution isn't wrong per se, but you are less likely to get a response. Have a skim of [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask), it has definitely helped me in the past. – fdcpp Jan 06 '21 at 15:27
  • If you are looking for code examples, then GitHub, in particular Gist, is a great resource with the right search query. A search of [wav language:"Visual Basic .NET"](https://gist.github.com/search?q=wav+language%3A%22Visual+Basic+.NET%22&ref=searchresults) yields a few results in particular this Gist about [Reading Audio Details in a Wav File](https://gist.github.com/GroupDocsGists/6c669dd39bed926d9c84df00ef5754ff) – fdcpp Jan 06 '21 at 15:29
  • Thank You for the Advise; but once again, I am asking if someone here can provide an example of how this is done in the modern VB environment, or can point me in the direction of where to look. Can you please do that? THANK YOU – iic1tls Jan 06 '21 at 15:31
  • [did this not work?](https://gist.github.com/GroupDocsGists/6c669dd39bed926d9c84df00ef5754ff) – fdcpp Jan 06 '21 at 15:34
  • I have studied those examples: the problem is that those examples are very old, and do not work in the new Visual Studio VB2019 env. This is why I am asking here if any one can provide an example of how to find the duration (time) of a WAV file in VB2019. Thank You. – iic1tls Jan 06 '21 at 15:42
  • Any luck with this? – fdcpp Jan 06 '21 at 20:24
  • @fdcpp at some point you have to recognise a [**help-vampire**](https://meta.stackexchange.com/questions/19665/the-help-vampire-problem) and move on. That line _"Thank You for the Advise; but once again, I am asking if someone here can provide an example of how this is done"_ tells you that they think SO is a code request site. It is ridiculous to think reading bytes in a programming language is _"too old"_ (notice how no error message is mentioned when trying them). – VC.One Jan 06 '21 at 21:33
  • @iic1tls You need to check or follow tutorials on how to read byte values from your WAV file. If you read first `Byte[0]=82` and get second `Byte[1]=73` and get third `Byte[2]=70` then you're doing it right. From there you need to read some other numbers that will be used to calculate the duration. A WAV header has file size in bytes, but not audio duration in time. It must be calculated. Use [edit mode](https://stackoverflow.com/review/suggested-edits/28017550) to show how you read each of the first 4 bytes of your WAV file. Then we can show you how to extend it so you learn the skill. – VC.One Jan 06 '21 at 21:47
  • 1
    @VC.One oh don't worry, I recognise the help-vampires, I just use the same approach as I do with my students which is that I can be far more tedious than any inquisitor. The only difference here is that I have never used Basic / Visual Basic before so it is an interesting opportunity to learn more. – fdcpp Jan 06 '21 at 21:56

1 Answers1

2

For those searching for this solution, here is the debugged code. Note that the MilliSecond to timestring conversion was not included here. Also Note that based on the comments made to this posting, there is no standard Visual Basic Library that will derive the duration of a WAV file.


Option Explicit On Option Strict On Imports System.IO

Public Shared Function GetWAVDuration(ByVal strPathAndFilename As String) As String

    REM *** SEE ALSO
    REM *** http://soundfile.sapp.org/doc/WaveFormat/
    REM *** CAUTION
    REM *** On the WaveFormat web page, the positions of the values
    REM *** SampleRate and BitsPerSample have been reversed.
    REM *** https://stackoverflow.com/questions/65588931/determine-wav-duration-time-in-visual-studio-2019/65616287#65616287

    REM *** DEFINE LOCAL VARIABLES

    REM *** Define Visual Basic BYTE Array Types
    Dim byNumberOfChannels() As Byte
    Dim bySamplesPerSec() As Byte
    Dim byBitsPerSample() As Byte
    Dim bySubChunkToSizeData() As Byte

    Dim nNumberOfChannels As Int16
    Dim nSamplesPerSec As Int16
    Dim nBitsPerSample As Int32
    Dim nSubChunkToSizeData As Int32

    Dim dNumberOfSamples As Double
    Dim nDurationInMillis As Int32

    Dim strDuration As String

    REM *** INITIALIZE LOCAL VARIABLES
    byNumberOfChannels = New Byte(2) {}
    bySamplesPerSec = New Byte(2) {}
    byBitsPerSample = New Byte(4) {}
    bySubChunkToSizeData = New Byte(4) {}

    nNumberOfChannels = 0
    nSamplesPerSec = 0
    nBitsPerSample = 0L
    nSubChunkToSizeData = 0L

    dNumberOfSamples = 0.0
    nDurationInMillis = 0

    strDuration = ""

    REM *** Initialize the return string value
    GetWAVDuration = ""

    REM ***************************************************************************

    REM *** Open the Input File for READ Operations
    Using fsFileStream = File.OpenRead(strPathAndFilename)

        REM *** Get the Number of Audio Channels
        fsFileStream.Seek(22, SeekOrigin.Begin)
        fsFileStream.Read(byNumberOfChannels, 0, 2)

        REM *** Get the Number of Bits Per Audio Sample
        fsFileStream.Seek(24, SeekOrigin.Begin)
        fsFileStream.Read(byBitsPerSample, 0, 4)

        REM *** Get the number of samples taken per second
        fsFileStream.Seek(34, SeekOrigin.Begin)
        fsFileStream.Read(bySamplesPerSec, 0, 2)

        REM *** Retrieve the size of the WAV data
        REM *** payload in the file
        fsFileStream.Seek(40, SeekOrigin.Begin)
        fsFileStream.Read(bySubChunkToSizeData, 0, 4)

    End Using

    REM *** Convert Values from their BYTE representation

    nNumberOfChannels = BitConverter.ToInt16(byNumberOfChannels, 0)
    nBitsPerSample = BitConverter.ToInt32(byBitsPerSample, 0)
    nSamplesPerSec = BitConverter.ToInt16(bySamplesPerSec, 0)
    nSubChunkToSizeData = BitConverter.ToInt32(bySubChunkToSizeData, 0)

    REM *** Compute the Duration of the WAV File
    REM *** Derives the duration in milliseconds

    REM *** Determine the number of Sound Samples 
    dNumberOfSamples = (nSubChunkToSizeData * 8) / (nNumberOfChannels * nBitsPerSample)
    nDurationInMillis = Convert.ToInt32(1000 * Convert.ToSingle(dNumberOfSamples) / Convert.ToSingle(nSamplesPerSec))

    REM *** Convert the time in Milliseconds to a string format
    REM *** represented by "hh:mm:ss"
    strDuration = ConvertMillisToTimeString(nDurationInMillis)

    REM *** POST METHOD RETURNS
    GetWAVDuration = strDuration

End Function
iic1tls
  • 63
  • 5
  • This is a solid answer. The only recommendation I can make is changing the naming convention of the `SubChunkToSize` variables to `SubChunk2Size` or even `SubChunkTwoSize` to avoid confusion. `SubChunk2Size` relates to the second subchunk of the RIFF file rather than a conversion from a _subchunk_ to a _size_ of some kind – fdcpp Jan 07 '21 at 20:54
  • Thank You for the recommendation. Thank You for your indulgence in this request. – iic1tls Jan 07 '21 at 21:23