Navigating RIFF Files

RIFF files consist of nested chunks of data. Multimedia file I/O services include two functions you can use to navigate between chunks in a RIFF file: mmioAscend and mmioDescend. You might think of these functions as high-level seek functions. When you descend into a chunk, the file position is set to the data field of the chunk (8 bytes from the beginning of the chunk). For “RIFF” and “LIST” chunks, the file position is set to the location following the form type or list type (12 bytes from the beginning of the chunk). When you ascend out of a chunk, the file position is set to the location following the end of the chunk.

Descending Into a Chunk

The mmioDescend function descends into a chunk or searches for a chunk, beginning at the current file position. The mmioDescend function has the following syntax:

WORD mmioDescend(hmmio, lpck, lpckParent, wFlags)

The hmmio parameter specifies the file handle for an open RIFF file.

The lpck parameter specifies a far pointer to an MMCKINFO structure that mmioDescend fills with information on the current chunk. The structure can also contain additional parameters, depending on the wFlags parameter.

The lpckParent parameter specifies a far pointer to an MMCKINFO structure describing the parent or enclosing chunk. If there is no parent chunk, this parameter should be NULL.

The wFlags parameter specifies options for searching for a chunk. Valid flags are MMIO_FINDCHUNK, MMIO_FINDRIFF, and MMIO_FINDLIST. If no flags are specified, mmioDescend descends into the chunk at the current file position.

The return value is zero if the operation is successful; otherwise, the return value specifies an error code.

The mmioDescend function fills an MMCKINFO structure with information on the chunk. This information includes the chunk ID, the size of the data field, and the form type, or list type if the chunk is a “RIFF” or “LIST” chunk.

Searching for a Chunk

To search for a chunk in an open RIFF file, specify the MMIO_FINDCHUNK flag in the wFlags parameter of mmioDescend. Set the ckid field of the MMCKINFO structure referenced by lpck to the four-character code of the chunk you want to search for.

If you are searching for a “RIFF” or ”LIST” chunk, you don't need to set the ckid field of the MMCKINFO structure—mmioDescend sets this field for you. Set the fccType field to the four-character code of the form type or list type of the chunk.

Summary: Searching for a “RIFF” Chunk

The following code fragment searches for a “RIFF” chunk with a form type of “WAVE” to verify that the file that has just been opened is a WAVE waveform audio file.

HMMIO                hmmio;
MMCKINFO        mmckinfoParent;
MMCKINFO        mmckinfoSubchunk;
.
.
.
/* 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))
        /* The file is not a WAVE file. */
else
        /* The file is a WAVE file */

If the chunk you are searching for is a subchunk enclosed by a parent chunk (as are all chunks other than “RIFF” chunks), you should identify the parent chunk with the lpckParent parameter. In this case, mmioDescend will only search within the specified parent chunk.

Summary: Searching for a Subchunk

The following code fragment searches for the “fmt ” chunk in the “RIFF” chunk descended into by the previous example:

/* Find the format chunk (form type "fmt "); it should be
 * a subchunk of the "RIFF" parent chunk
 */
mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' ');
if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK))
        /* Error, cannot find the "fmt " chunk */
else
        /* "fmt " chunk found */

If you do not specify a parent chunk, the current file position should be at the beginning of a chunk before you call mmioDescend to search for a chunk. If you do specify a parent chunk, the current file position can be anywhere in the parent chunk.

If the search for a subchunk fails, the current file position is undefined. You can use mmioSeek and the dwDataOffset field of the MMCKINFO structure for the enclosing parent chunk to seek back to the beginning of the parent chunk, as in the following example:

mmioSeek(hmmio, mmckinfoParent.dwDataOffset + 4, SEEK_SET);

Since the dwDataOffset field specifies the offset to the beginning of the data portion of the chunk, you must seek four bytes past dwDataOffset to set the file position to be after the form type.

Ascending Out of a Chunk

After you descend into a chunk and read the data in the chunk, you can move the file position to the beginning of the next chunk by ascending out of the chunk by using the mmioAscend function. The mmioAscend function has the following syntax:

WORD mmioAscend(hmmio, lpck, wFlags)

The hmmio parameter specifies the file handle for an open RIFF file.

The lpck parameter specifies a far pointer to an MMCKINFO structure identifying a chunk. The function ascends to the location following the end of this chunk.

The wFlags parameter is not used and should be set to zero.

The return value is zero if the operation is successful; otherwise, the return value specifies an error code.

Summary: Ascending Out of a Subchunk

For example, the following statement ascends out of the “fmt ” subchunk descended into by the previous example, illustrating searching for a subchunk:

/* Ascend out of the "fmt " subchunk
 */
mmioAscend(hmmio, &mmckinfoSubchunk, 0);