Microsoft DirectX 8.0 (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