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 both Visual Basic 6 and Visual Basic .NET.
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. The lastest version of DirectX is version 9, but for compatibility we will be using version 8 which is more widespread and is still supported. In these demonstrations we will be using the DirectSound component. End-users of DirectX applications will 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
An excellent free version of Visual Basic .NET called Visual Basic 2005 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 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)
|