Sound Replay in Visual Basic

Visual Basic is a widespread and easy to use programming environment that could be useful for experimental work in speech. However documentation about how to generate and replay sounds within VB programs is not readily available. This page provides some simple code for sound generation and replay of waveforms in Visual Basic 6, Visual Basic .NET 2005, and Visual Basic .NET 2008.


DirectX

DirectX is the name Microsoft gives to a group of technologies to support audio, video and graphics applications on Windows PCs. The DirectX SDK (software development kit) can be downloaded free from the MSDN web site. In these demonstrations we will be using the DirectSound component. End-users of DirectX applications may need the DirectX run-time components, also available from the MSDN web site.

Visual Basic 6

We present a very simple application that plays a one second tone. Set up the form to look like this with a single button called "Play":

Ensure your application references the DirectX8 Type library. Under Project|References, select this as follows:

If the DirectX8 Type library is not listed, you will need to download and install the DirectX SDK.

The code you need is then just:

    Option Explicit
    '
    ' DirectSound access
    Dim DX As DirectX8
    Dim DS As DirectSound8
    Dim dsToneBuffer As DirectSoundSecondaryBuffer8
    Dim desc As DSBUFFERDESC
    '
    ' Global variables
    Const PI = 3.14159265358979
    Const SRATE = 44100             ' Sampling Rate
    Const DUR = 1                   ' Tone duration
    Const FREQ = 500                ' Tone frequency
    Dim sbuf(0 To DUR * SRATE) As Integer
    
    Private Sub Form_Load()
    '
    ' initialise DirectSound
    Set DX = New DirectX8
    Set DS = DX.DirectSoundCreate("")
    DS.SetCooperativeLevel Me.hWnd, DSSCL_NORMAL
    '
    ' create a buffer
    desc.fxFormat.nFormatTag = WAVE_FORMAT_PCM
    desc.fxFormat.nSize = 0
    desc.fxFormat.lExtra = 0
    desc.fxFormat.nChannels = 1
    desc.fxFormat.lSamplesPerSec = SRATE
    desc.fxFormat.nBitsPerSample = 16
    desc.fxFormat.nBlockAlign = 2
    desc.fxFormat.lAvgBytesPerSec = 2 * SRATE
    desc.lFlags = 0
    desc.lBufferBytes = 2 * DUR * SRATE
    Set dsToneBuffer = DS.CreateSoundBuffer(desc)
    '
    ' create a tone
    Dim i
    For i = 0 To DUR * SRATE
        sbuf(i) = 10000 * Sin(2 * PI * FREQ * i / SRATE)
    Next i
    '
    ' copy tone to buffer
    dsToneBuffer.WriteBuffer 0, 2 * DUR * SRATE, sbuf(0), DSBLOCK_DEFAULT
    '
    End Sub
    
    Private Sub Play_Click()
    '
    ' play the tone
    dsToneBuffer.Play DSBPLAY_DEFAULT
    '
    End Sub

If you want to fill the sound buffer from a WAV file, rather than build it from scratch, use:

    Dim idesc As DSBUFFERDESC
    idesc.lFlags = 0
    Set dsToneBuffer = DS.CreateSoundBufferFromFile(App.Path & "\six.wav", idesc)


Visual Basic .NET 2005

Visual Basic .NET 2005 edition is no longer supported on the Microsoft Express Editions web site. However, this code may still be of use for users of that version.

We present a very simple application that plays a one second tone. Set up the form to look as above with a single button called "Play". Ensure your application references the DirectX8 Type library. Under Project|Properties|References, add the reference as follows:

If the DirectX8 Type library is not listed, you will need to download and install the DirectX SDK.

The code you need is then just:

    Option Strict Off
    Option Explicit On
    Imports System.Runtime.InteropServices
    Friend Class Form1
    Inherits System.Windows.Forms.Form
    '
    ' Direct Sound access
    Dim DX As DxVBLibA.DirectX8
    Dim DS As DxVBLibA.DirectSound8
    Dim dsToneBuffer As DxVBLibA.DirectSoundSecondaryBuffer8
    Dim desc As DxVBLibA.DSBUFFERDESC
    '
    ' Global variables
    Const PI As Double = 3.14159265358979
    Const SRATE As Integer = 44100            ' Sampling Rate
    Const DUR As Double = 1                   ' Tone duration
    Const FREQ As Double = 500                ' Tone frequency
    Dim sbuf(0 To DUR * SRATE) As Short
    
    Private Sub Form1_Load(ByVal eventSender As System.Object, _
        ByVal eventArgs As System.EventArgs) Handles MyBase.Load
    '
    ' initialise DirectSound
    DX = New DxVBLibA.DirectX8
    DS = DX.DirectSoundCreate("")
    DS.SetCooperativeLevel(Me.Handle.ToInt32, _
        DxVBLibA.CONST_DSSCLFLAGS.DSSCL_NORMAL)
    '
    ' create a buffer
    desc.fxFormat.nFormatTag = DxVBLibA.CONST_DSOUND.WAVE_FORMAT_PCM
    desc.fxFormat.nSize = 0
    desc.fxFormat.lExtra = 0
    desc.fxFormat.nChannels = 1
    desc.fxFormat.lSamplesPerSec = SRATE
    desc.fxFormat.nBitsPerSample = 16
    desc.fxFormat.nBlockAlign = 2
    desc.fxFormat.lAvgBytesPerSec = 2 * SRATE
    desc.lFlags = 0
    desc.lBufferBytes = 2 * DUR * SRATE
    dsToneBuffer = DS.CreateSoundBuffer(desc)
    '
    ' create a tone
    Dim i As Integer
    For i = 0 To DUR * SRATE
        sbuf(i) = 10000 * System.Math.Sin(2 * PI * FREQ * i / SRATE)
    Next i
    '
    ' copy tone to buffer
    Dim hmem As GCHandle = GCHandle.Alloc(sbuf, GCHandleType.Pinned)
    dsToneBuffer.WriteBuffer(0, 2 * DUR * SRATE, hmem.AddrOfPinnedObject(), _
        DxVBLibA.CONST_DSBLOCKFLAGS.DSBLOCK_DEFAULT)
    hmem.Free()
    '
    End Sub
    
    Private Sub Play_Click(ByVal eventSender As System.Object, _
        ByVal eventArgs As System.EventArgs) Handles Play.Click
    '
    ' play the tone
    dsToneBuffer.Play(DxVBLibA.CONST_DSBPLAYFLAGS.DSBPLAY_DEFAULT)
    '
    End Sub
    End Class

If you want to fill the sound buffer from a WAV file, rather than build it from scratch, use:

    Public Function App_Path() As String
        Return System.AppDomain.CurrentDomain.BaseDirectory()
    End Function
    
    Dim idesc As DxVBLibA.DSBUFFERDESC idesc.lFlags = 0 dsToneBuffer = DS.CreateSoundBufferFromFile(App_Path() & "six.wav", idesc)


Visual Basic .NET 2008 Edition

An excellent free version of Visual Basic .NET called Visual Basic 2008 Express Edition can be downloaded from the MSDN web site.

We present a very simple application that plays a one second tone. Set up the form to look as above with a single button called "Play". Ensure your application references the DirectSound .NET library. Under Project|Properties|References, add the reference as follows:

If the DirectSound .NET library is not listed, you will need to download and install the DirectX SDK.

The code you need is then just:

    Imports Microsoft.DirectX.DirectSound
    Public Class Form1
        Dim DS As Device
        Dim wvFormat As WaveFormat
        Dim dsBuffer As SecondaryBuffer
        Dim dsDesc As BufferDescription
        Const SRATE As Integer = 44100
        Const DUR As Double = 1
        Const FREQ As Double = 500
        Dim sbuf(DUR * SRATE) As Short
    
        Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load
            ' Open DirectSound
            DS = New Microsoft.DirectX.DirectSound.Device
            DS.SetCooperativeLevel(Me, CooperativeLevel.Normal)
            ' Create a waveform description
            wvFormat.FormatTag = WaveFormatTag.Pcm
            wvFormat.Channels = 1
            wvFormat.SamplesPerSecond = SRATE
            wvFormat.BitsPerSample = 16
            wvFormat.AverageBytesPerSecond = 2 * SRATE
            wvFormat.BlockAlign = 2
            dsDesc = New BufferDescription(wvFormat)
            dsDesc.BufferBytes = 2 * DUR * SRATE
            dsDesc.Flags = 0
            ' create a buffer
            dsBuffer = New SecondaryBuffer(dsDesc, DS)
            ' create tone
            For i As Integer = 0 To DUR * SRATE
                sbuf(i) = 10000 * Math.Sin(2 * Math.PI * FREQ * i / SRATE)
            Next
            ' copy to buffer
            dsBuffer.Write(0, sbuf, LockFlag.EntireBuffer)
    
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
            dsBuffer.Play(0, BufferPlayFlags.Default)
        End Sub
    
    End Class

If you want to fill the sound buffer from a WAV file, rather than build it from scratch, use:

    Dim dsFile = New SecondaryBuffer("c:/sfs/demo/six.wav", DS)
    dsFile.Play(0, BufferPlayFlags.Default)


© 2010


University College London - Gower Street - London - WC1E 6BT - Telephone: +44 (0)20 7679 2000 - Copyright © 1999-2015 UCL