Solved

Wav length

Posted on 1998-11-17
7
487 Views
Last Modified: 2008-03-04
How would one report the length of a wav file to VB?
I assume that the header of the wav contains the bitrate, so theoretically, one could use Filelen()/bitrate???

How do i extract this header?

thanx!!

0
Comment
Question by:salocorgan
  • 4
  • 3
7 Comments
 
LVL 2

Expert Comment

by:trillo
ID: 1445235
I have some experience working with WAV file, but i don't understand quite well. Your question asks for the lenth of a Wav file... so I would say just the File lenth (This is obviously not what yo're asking for, I know)
What length are you talking about?... Te length in seconds?... The length in bytes of the data string?...
0
 

Author Comment

by:salocorgan
ID: 1445236
Yes -- length timewize.  Seconds would be great.
0
 
LVL 2

Accepted Solution

by:
trillo earned 70 total points
ID: 1445237
To retrieve the time length of a wave file (in seconds) you must calculate:

time = FileLenght / (SampleRate * Channels * BitsPerSample/8)
      =  FileLenght / bytespersecond

All this information can be retrieved from the Wav file header or Format chunk
There's a little detail: A WAV file is divided in chunks, each chunk has a specific meaning,  and there are at least 2 chunks: The format and the data chunk.
1) The format chunk is often at the beginning at the file and has the information about the Waveform format of the file: (samplerate, channnels, bitspersample, blockalign, etc..)
2) The data chunk contains the actual waveform data.

All the chunks have at least two parameters: The chunkID and the chunksize:
   a) ChunkID: identifies the chunk ('fmt ' for the format chunk, and 'data' for the data chunk)
   b) Chunksize: is the lenght of the chunk in bytes (not including the bytes used by the chunks header) This is the parameter with which you can know where does a chunk end and where does the next chunk begin (if any).

There are other optional chunks that are application-specific (for example a wave file can contain a song's lyrics, if saved by a program that supports it). THIS MEANS THE THE FILELENGTH DOES NOT ALWAYS REPRESENT THE TRUE SIZE IN BYTES OF THE WAVE DATA.

Anyway, in the most of the cases you could use the above equation to calculate the playtime of a WAVE file

¿How to extract the Header?
You have to read the first 36 bytes of the file
Bytes <-->Meaning
4:    "RIFF"
4:    size of file including header
4:    "WAVE"
4:    "fmt "
(16)
4:    (don't remember)
2:    formatTag
2:    number of channels (mono - stereo)
4:    Samples per second
4:    Bytes per Second    
(32)
2:    blockAlign (minimum atomic unit of data) = bitspersample/8
2:    bits per sample
(36)

The next  bytes represent the other chunks ... for example
bytes 36 to 39:  "data"
bytes 40 to 43:  size of sound data in bytes (lets call it X)
bytes 44 to X:    Your wave data
0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 

Author Comment

by:salocorgan
ID: 1445238
OK. So i need filelen - header /bytespersecond. But when i open a wav file with a text editor i only get gibberish inbetween things like RIFF and WAVE and the rest.  What format is that? And how do i convert it??

Thanx again for your help, much appreciated.
0
 
LVL 2

Expert Comment

by:trillo
ID: 1445239
Ok.... I just coded this lines and tested them (to make it easy place a command button on a form and paste the following code)

-----------------Code on a command button---------------
Private Sub Command1_Click()
    Dim MyInt As Integer
    Dim MyByte As Byte
    Dim MyStr As String * 4
    Dim MyLong As Long
    Dim SampleRate, BytesPerSample, FileSize As Long
   
    Open "d:\tmp.wav" For Binary Access Read Lock Read As #1
        Get #1, , MyStr:    Debug.Print "Riff = "; MyStr
        Get #1, , MyLong:   Debug.Print "File size = "; MyLong
        FileSize = MyLong
        Get #1, , MyStr:    Debug.Print "Wave = "; MyStr
        Get #1, , MyStr:    Debug.Print "Format = "; MyStr
        Get #1, , MyLong:   Debug.Print "Any = "; MyLong
        Get #1, , MyInt:    Debug.Print "formatTag = "; MyInt
        Get #1, , MyInt:    Debug.Print "Channels = "; MyInt
        Get #1, , MyLong:   Debug.Print "Samples per Sec = "; MyLong
        SampleRate = MyLong
        Get #1, , MyInt:    Debug.Print "Bytes per Sec = "; MyInt
        Get #1, , MyInt:    Debug.Print "BlockAlign = "; MyInt
        Get #1, , MyInt:    Debug.Print "Bytes per Sample = "; MyInt
        BytesPerSample = MyInt
    Close #1
    Debug.Print "Wave File Duration = "; _
        FileSize / (SampleRate * BytesPerSample); " seconds"
End Sub
---------------------------------------------------------
----------Output of the program on the debug window------
Riff = RIFF
File size =  68950
Wave = WAVE
Format = fmt
Any =  18
formatTag =  1
Channels =  2
Samples per Sec =  11025
Bytes per Sec = -21436
BlockAlign =  0
Bytes per Sample =  4
Wave File Duration =  1.56349206349206  seconds

Which is exactly the length that I got on Win95 sound recorder...
What do you think now?
0
 
LVL 2

Expert Comment

by:trillo
ID: 1445240
Oh... I forgot to tell somethin!
When you open a Wav file in notepad, you see only garbage, this is obvious because it's not a text file... it binary!
The trick is reading the file and putting them in the appropriate variables.... If you have to read a 2-byte-number you use an integer (Which needs 2 bytes to be stored), for a 4-bytes-number you'd use a long, etc.... Thet's different from a text file....
(Supose you have an integer i=1000. As you see we are using 4 bytes '1', '0', '0', '0'....That is TEXT. To store it as an integer you only need two bytes.
0
 

Author Comment

by:salocorgan
ID: 1445241
What do i think now? I think that was an EXCELLENT answer! Youre brilliant!!! ;-)  Thanx again. :)
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question