Version 2.0!
Features
Tutorials
Files
Glossary
Projects
Contact
Links
Message Board
Extras
LuckyCam
Old News
Sign Guestbook
View Guestbook
VB Horoscope
VB Photo Album
.
ATTENTION READERS! Lucky's VB Gaming Site is no longer active. For updated game programming information and tutorials, please visit The Game Programming Wiki!

Loading Buffers from Custom Binary Resource Files

Firstly: *backpat* Thanks MetalWarrior, for helping me get the ball rolling on this!

Now then, I hope there're no vegetarians among us today cuz I'm going to get straight to the meat! Harken, behold:

DirectSoundBuffer.WriteBuffer(start As Long, size As Long, buffer As Any, flags As CONST_DSBLOCKFLAGS)

I wonder if anyone has ever bothered to look at this method of the DirectSoundBuffer object before. I know I certainly hadn't paid it any attention prior to October! But what a thing of beauty she is. All you do is indicate where to write within the buffer (start, usually at the beginning: zero), how much stuff you want to write (size) and what you want to write in that space (buffer). The buffer must be an array of bytes, but you pass only the first element of that array. There's also a flags variable to pass, which can be either DSBLOCK_FROMWRITECURSOR (which writes from the current position of the buffer's playback and ignores the start variable), or DSBLOCK_ENTIREBUFFER (which writes to the entire buffer and ignores the size variable).

As great as WriteBuffer is, we're still not in the clear. We need some method of extracting the byte data from a wave file in order to pass it as our buffer variable, AND we also must find a way to fill a WAVEFORMATEX structure so that we can initialize the buffer correctly when we create it manually. How? Lucky's patented (not) wave file extractor! :)

'Wave file format info
Private Type WAVETYPE
    strHead As String * 12
    strFormatID As String * 4
    lngChunkSize As Long
    intFormat As Integer
    intChannels As Integer
    lngSamplesPerSec As Long
    lngAvgBytesPerSec As Long
    intBlockAlign As Integer
    intBitsPerSample As Integer
End Type
Global gudtHeader As WAVETYPE
Global glngChunkSize As Long
Global gbytData() As Byte

Sub ExtractWaveData(strFileName As String, lngOffset As Long)

Dim intWAVFile As Integer
Dim i As Long
Dim strTemp As String * 4
Dim blnFound As Boolean

    'Open the wave
    intWAVFile = FreeFile()
    Open strFileName For Binary Access Read Lock Write As intWAVFile
        'Get the header info
        Get intWAVFile, lngOffset, gudtHeader
        'Find the "data" portion of the file
        For i = lngOffset To LOF(intWAVFile)
            Get intWAVFile, i, strTemp
            If strTemp = "data" Then
                blnFound = True
                Exit For
            End If
        Next i
        'Ensure this is a wave file
        If blnFound = False Then
            MsgBox "Invalid wave data.", vbCritical, "Invalid Wave"
            Close intWAVFile
            Exit Sub
        End If
        'Get the data information
        Get intWAVFile, , glngChunkSize
        ReDim gbytData(glngChunkSize)
        Get intWAVFile, , gbytData
    Close intWAVFile
    
End Sub

This gives us everything we need! We now have the wave data buffer (gbytData) and know its size (glngChunkSize). Also, gudtHeader contains the essential info we need for filling a WAVEFORMATEX structure and initializing a buffer from scratch! Observe:

Public Sub LoadSound(objBuffer As DirectSoundBuffer)

Dim udtBufferDesc As DSBUFFERDESC
Dim udtFormat As WAVEFORMATEX
   
    'Set the Wave Format
    With udtFormat
        .nFormatTag = gudtHeader.intFormat
        .nChannels = gudtHeader.intChannels
        .lSamplesPerSec = gudtHeader.lngSamplesPerSec
        .nBitsPerSample = gudtHeader.intBitsPerSample
        .nBlockAlign = gudtHeader.intBlockAlign
        .lAvgBytesPerSec = gudtHeader.lngAvgBytesPerSec
    End With
    
    'Create the buffer
    udtBufferDesc.lBufferBytes = glngChunkSize
    Set objBuffer = mobjDS.CreateSoundBuffer(udtBufferDesc, udtFormat)
    
    'Load the buffer with data
    objBuffer.WriteBuffer 0, glngChunkSize, gbytData(0), DSBLOCK_ENTIREBUFFER
    
End Sub

After extracting the wave data from a file we can run this LoadSound routine to create a buffer and load it properly. I realize this tutorial is quite advanced and hope this source code may serve to clarify somewhat. Ta-ta for now! *waves* ;)