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)
|