Example of RIFF File I/O

The following code fragment shows how to open a RIFF file for buffered I/O, as well as how to descend, ascend, and read RIFF chunks.

/* ReversePlay--Plays a WAVE waveform audio file backwards
 */
void ReversePlay()
{
    char        szFileName[128];    // filename of file to open
    HMMIO       hmmio;              // file handle for open file
    MMCKINFO    mmckinfoParent;     // parent chunk information structure
    MMCKINFO    mmckinfoSubchunk;   // subchunk information structure
    DWORD       dwFmtSize;          // size of "fmt " chunk
    DWORD       dwDataSize;         // size of "data" chunk
    WAVEFORMAT  *pFormat;           // pointer to memory for "fmt " chunk
    HPSTR       lpData;             // pointer to memory for "data" chunk
    ...
   
    /* Get the filename from the edit control
     */
     ...
   
    /* Open the given file for reading with buffered I/O
     * using the default internal buffer
     */
    if(!(hmmio = mmioOpen(szFileName, NULL, MMIO_READ | MMIO_ALLOCBUF))){
        Error("Failed to open file.");
        return;
    }

    /* Locate a "RIFF" chunk with a "WAVE" form type
     * to make sure the file is a WAVE file
     */
    mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');
    if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL,
                    MMIO_FINDRIFF)){
        Error("This is not a WAVE file.");
        mmioClose(hmmio, 0);
        return;
    }
    


    /* Find the "fmt " chunk (form type "fmt "); it must be
     * a subchunk of the "RIFF" parent chunk
     */
    mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
    if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,
                    MMIO_FINDCHUNK)){
        Error("WAVE file has no "fmt " chunk.");
        mmioClose(hmmio, 0);
        return;
    }

    /* Get the size of the "fmt " chunk--allocate and lock memory for it
     */
    dwFmtSize = mmckinfoSubchunk.cksize;
    ...

    /* Read the "fmt " chunk
     */
    if (mmioRead(hmmio, (HPSTR) pFormat, dwFmtSize) != dwFmtSize){
        Error("Failed to read format chunk.");
        ...
        mmioClose(hmmio, 0);
        return;
    }

    /* Ascend out of the "fmt " subchunk
     */
    mmioAscend(hmmio, &mmckinfoSubchunk 0);
   
    /* Find the data subchunk. The current file position should be at the
     * beginning of the data chunk, however, you should not make this                             * assumption--use mmioDescend to locate the data chunk.
     */
    mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a');
    if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent,
                    MMIO_FINDCHUNK)){
        Error("WAVE file has no data chunk.");
        ...
        mmioClose(hmmio, 0);
        return;
    }


    /* Get the size of the data subchunk
     */
    dwDataSize = mmckinfoSubchunk.cksize;
    if (dwDataSize == 0L){
        Error("The data chunk contains no data.");
        ...
        mmioClose(hmmio, 0);
        return;
    }
   
    /* Open a waveform output device
     */
    ...

    /* Allocate and lock memory for the waveform data
     */
    ...

    /* Read the waveform data subchunk
     */
    if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != dwDataSize){
        Error("Failed to read data chunk.");
        ...
        mmioClose(hmmio, 0);
        return;
    }

    /* Close the file
     */
    mmioClose(hmmio, 0);

    /* Reverse the sound and play it
     */
    ...
   
}