wilhelm kurz software

home
application notes

dynaplot application notes

loadwav

Load and Display a Windows Wav Audio File 

This application note shows how to read data from a Windows wav-file and display the sounds in a DynaPlot chart.

The program can read uncompressed PCM-encoded wave data with 8 or 16 bytes/sample and any number of channels (mono, stereo, quad, etc.).  A play function lets you listen to the sound. The code demonstrates how to pass an array of arrays to DynaPlot. 

Reading in the Wave Header 

A wav file consists of a header, followed by one or more chunks with format or other information followed by a data chunk. In order to be able to interpret the data  we need to read the format chunk. 

Private Type FMTCHUNK
    Format As Integer
    NumChannels As Integer
    SampleRate As Long
    BytesPerSecond As Long
    BytesPerSample As Integer
    BitsPerSample As Integer
End Type

From the format chunk we learn 

The number of channels (mono, stereo, etc.). For more than one channel the channel data in the data chunk are interleaved e.g. Left1, Right1, Left2, Right2, etc. and we have to separate the data streams when reading the file.

The sample rate. We use this information to calculate the time between two samples. This is the increment in our parametric definition of the curves' abscissa values.

The number of bits per sample. This tells us, which data type we must use when reading channel data. For 8 bits/sample we use bytes, for 16 bits/sample we use integers.

From the length field in the data chunk, which tells us the total length of the following wave data in bytes, we can compute the number of samples. 

Number of samples  = size of data chunk / (bits per sample / 8) / number of channel

With this information at hand we can start reading in the data. To read the samples from the file we use an array of bytes ReDim ybyte(NumChannels - 1, NumSamples - 1) As Byte and for 16 bit samples we use an array of integers ReDim yshort(NumChannels - 1, NumSamples - 1) As Integer. The layout of these arrays reflects the interleaved way the samples are stored in the array. 

 We cannot pass the interleaved channel data to DynaPlot, however. Instead, we allocate Y a twodimensional array of doubles which will hold our curve data. 

' must be Doubles for AddParametric
ReDim Y (NumSamples - 1, NumChannels - 1) As Double

Notice, how the data are organized here: Y (sample, channel).  This way, the samples of one channel are in a contiguous block in memory an we can pass a pointer to a channel's first sample to DynaPlot's AddParametric method in order to add the channel to the chart. 

Once the data have been read from the file, the only thing which remains for us to do is copy the samples over like in Y(i, c) = yshort(c, i). 

Reading in the Wave Data 

 If BitsPerSample = 8 Then
    ReDim ybyte(NumChannels - 1, NumSamples - 1) As Byte
    Get WaveFile, , ybyte ' read data in one go
    For i = 0 To NumSamples - 1
        For c = 0 To NumChannels - 1
            Y(i, c) = ybyte(c, i) - 128 '8 Bits/sample is unsigned
        Next
    Next
ElseIf BitsPerSample = 16 Then
    ReDim yshort(NumChannels - 1, NumSamples - 1) As Integer
    Get WaveFile, , yshort ' read data in one go
    For i = 0 To NumSamples - 1
        For c = 0 To NumChannels - 1
            Y(i, c) = yshort(c, i)
        Next
    Next
Else
    Close WaveFile
    MsgBox BitsPerSample & " bits/sample not supported"
    Exit Sub
End If

Displaying the channels

The final step is to pass the channel arrays to DynaPlot for display. We pass pointers to the columns of Y to DynaPlot's AddParametricCpp method. 

 For c = 0 To NumChannels - 1
   DynaPlot1.DataCurves.AddParametricCpp "Channel " & c + 1, 0, 1# / SampleRate, Y(0, c), NumSamples   
Next

 The project can also be downloaded: 

Download LoadWav.zip

  

[home] [products] [news] [contact] [links]