Microsoft DirectX 8.1 (Visual Basic) |
Short sounds can be saved from a secondary buffer to a wave file by using DirectSoundSecondaryBuffer8.SaveToFile. This method copies the entire contents of the buffer to a file.
In most cases, the sound that you want to save starts out in a capture buffer. The following code shows how to move data from a capture buffer, dscb, to a secondary buffer and then to a file.
Dim ds As DirectSound8
Dim dscb As DirectSoundCaptureBuffer8
Dim dscd As DSCBUFFERDESC
Dim dsd As DSBUFFERDESC
Dim capCurs As DSCURSORS
Dim numBytes As Long
Dim ByteBuffer() As Integer
.
.
.
' Assume that ds has been created, dscb has been created and
' contains data, and dscd holds the format of the capture buffer.
' Create a secondary buffer with the same format, and large enough
' to contain all data so far written to the capture buffer.
dscb.GetCurrentPosition capCurs
numBytes = capCurs.lWrite + 1
dsd.lBufferBytes = numBytes
dsd.fxFormat = dscd.fxFormat
Set dsb = ds.CreateSoundBuffer(dsd)
' Make a private buffer large enough to hold the same data.
ReDim ByteBuffer(numBytes)
' Read the contents of the capture buffer into the private buffer.
dscb.ReadBuffer 0, numBytes, ByteBuffer(0), DSCBLOCK_DEFAULT
' Write the private buffer to the secondary buffer.
dsb.WriteBuffer 0, numBytes, ByteBuffer(0), DSBLOCK_DEFAULT
' Save the wave.
dsb.SaveToFile "captured.wav"
For sounds that might exceed the length of the capture buffer, you need to create the wave file yourself and stream data into it. Streaming captured data to a wave file is done in the following steps:
The following code creates a file and writes the RIFF header information:
Private Type FileHeader
lRiff As Long
lFileSize As Long
lWave As Long
lFormat As Long
lFormatLength As Long
End Type
Private Type WaveFormat
wFormatTag As Integer
nChannels As Integer
nSamplesPerSec As Long
nAvgBytesPerSec As Long
nBlockAlign As Integer
wBitsPerSample As Integer
' cbSize As Integer
End Type
Private Type ChunkHeader
lType As Long
lLen As Long
End Type
Dim fh As FileHeader
Dim wf As WaveFormat
Dim ch As ChunkHeader
Private Sub OpenFile(WaveFileName As String)
Open WaveFileName For Binary Access Write As #1
With fh
.lRiff = &H46464952 ' <RIFF> chunk tag
.lFileSize = 0 ' Will get later
.lWave = &H45564157 ' <WAVE> chunk tag
.lFormat = &H20746D66 ' <fmt > chunk tag
.lFormatLength = Len(wf)
End With
Put #1, , fh
With wf
.wFormatTag = dscbDesc.fxFormat.nFormatTag
.nChannels = dscbDesc.fxFormat.nChannels
.nSamplesPerSec = dscbDesc.fxFormat.lSamplesPerSec
.wBitsPerSample = dscbDesc.fxFormat.nBitsPerSample
.nBlockAlign = dscbDesc.fxFormat.nBlockAlign
.nAvgBytesPerSec = dscbDesc.fxFormat.lAvgBytesPerSec
End With
Put #1, , wf
ch.lType = &H61746164 ' <data> chunk tag
Put #1, , ch
End Sub
Captured data can now be appended to the file. Assuming that the number of data bytes written to the file is kept in a Long called BytesWritten, the file is closed by using the following procedure:
Private Sub CloseFile()
Dim fsize As Long
' Write file size.
fsize = Len(fh) + Len(wf) + Len(ch) + BytesWritten
Put #1, 5, fsize
' Rewrite data chunk header with size.
ch.lLen = BytesWritten
Put #1, Len(fh) + Len(wf) + 1, ch
Close #1
End Sub