Мультимедиа для Windows

5b239685

Функции для работы с RIFF-файлами


Ваше приложение может работать с RIFF-файлами с использованием обычных функций ввода/вывода или с помощью функций, описанных выше (что удобнее). Дополнительно в библиотеке mmsystem.dll есть функции, сильно облегчающие работу с фрагментами RIFF-файлов. Эти функции помогут вам заполнить четырехбайтовый идентификатор фрагмента, найти в файле нужный фрагмент и установить на него (или за него) текущую позицию файла, а также создать новый фрагмент в новом файле.

При формировании нового фрагмента удобна функция mmioFOURCC , с помощью которой можно создать четырехбуквенный код фрагмента из отдельных букв.

Функция mmioFOURCC

FOURCC mmioFOURCC( CHAR ch0, // первая буква кода CHAR ch1, // вторая буква кода CHAR ch2, // третья буква кода CHAR ch3); // четвертая буква кода

Параметры функции:

ch0, ch1, ch2, ch3

Коды букв, из которых будет составлен четырехбуквенный код

Возвращаемое значение:

Возвращается значение четырехбуквенного идентификатора, который можно использовать при формировании нового фрагмента

Функция mmioFOURCC реализована как макрокоманда, выполняющая упаковку четырех байт в двойное слово:

#define mmioFOURCC(ch0, ch1, ch2, ch3) \ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))

Для формирования, например, идентификатора фрагмента "WAVE" вы можете использовать эту макрокоманда следующим образом:

FOURCC fourccWaveID; fourccWaveID = mmioFOURCC('W', 'A', 'V', 'E');



В некоторых случаях может оказаться удобнее формировать четырехбуквенный идентификатор не из отдельных букв, а из строки символов. Для этого можно использовать функцию mmioStringToFOURCC .

Функция mmioStringToFOURCC

FOURCC mmioStringToFOURCC( LPCSTR szString, // преобразуемая строка UINT wFlags); // режим преобразования

Параметры функции:

szString

Указатель на преобразуемую строку, закрытую двоичным нулем

wFlags

Если указан флаг MMIO_TOUPPER , все буквы строки будут преобразованы в заглавные

Возвращаемое значение:


Возвращается значение четырехбуквенного идентификатора, который можно использовать при формировании нового фрагмента

Пример использования функции mmioStringToFOURCC:

FOURCC fourccWaveID; fourccWaveID = mmioStringToFOURCC("wave", MMIO_TOUPPER);

Для создания нового фрагмента в RIFF-файле удобно использовать функцию mmioCreateChunk . Новый фрагмент создается в текущей позиции файла, открытого с помощью функции mmioOpen.

Функция mmioCreateChunk

UINT mmioCreateChunk( HMMIO hmmio, // идентификатор открытого файла LPMMCKINFO lpck, // указатель на структуру MMCKINFO UINT wFlags); // тип фрагмента

Параметры функции:

hmmio

Идентификатор открытого файла, полученный с помощью функции mmioOpen

lpck

Указатель на структуру MMCKINFO, содержащую информацию о создаваемом фрагменте

wFlags

Если указан флаг MMIO_CREATERIFF , создается фрагмент "RIFF", а если MMIO_CREATELIST - создается фрагмент "LIST"

Возвращаемое значение:

При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки

Структура MMCKINFO и указатели на нее определены в файле mmsystem.h:

typedef struct _MMCKINFO { FOURCC ckid; DWORD cksize; FOURCC fccType; DWORD dwDataOffset; DWORD dwFlags; } MMCKINFO; typedef MMCKINFO *PMMCKINFO; typedef MMCKINFO NEAR *NPMMCKINFO; typedef MMCKINFO FAR *LPMMCKINFO;

Опишем назначение отдельных полей этой структуры.

Поле Описание
ckid Код, соответствующий четырехбуквенному идентификатору фрагмента
cksize Размер фрагмента в байтах без учета идентификатора фрагмента, поля длины фрагмента и дополнительных байтов выравнивания, которые могут находиться в конце фрагмента
fccType Тип фрагмента
dwDataOffset Смещение области данных относительно начала файла в байтах
dwFlags В этом поле может находиться нулевое значение или флаг MMIO_DIRTY, в последнем случае длина фрагмента может быть изменена, поэтому для ее обновления следует вызвать функцию mmioAscend. Флаг MMIO_DIRTY может быть установлен при создании фрагмента функцией mmioCreateChunk
<


В приведенном ниже фрагменте кода создается новый файл, подготавливается структура MMCKINFO, а затем создается фрагмент "RIFF", для чего вызывается функция mmioCreateChunk:

hFile = mmioOpen(szFileName, NULL, MMIO_CREATE | MMIO_READWRITE); if(hFile != NULL) { ck.ckid = MMIO_CREATERIFF; ck.cksize = waveiocbIn.lpWaveHdr->dwBytesRecorded + sizeof(PCMWAVEFORMAT) + 20; ck.fccType = mmioFOURCC('W', 'A', 'V', 'E'); mmioCreateChunk(hFile, (LPMMCKINFO)&ck, MMIO_CREATERIFF); }

Более подробно этот фрагмент кода будет описан позже, когда мы будем рассказывать вам о приложении WAVE, работающим с wav-файлами и звуковым адаптером на низком уровне.

Для поиска нужного фрагмента внутри RIFF-файла у вас нет необходимости выполнять побайтовое чтение файла и анализ его внутренней структуры. Найти нужный фрагмент и выполнить позиционирование относительно этого фрагмента вам помогут функции mmioDescend и mmioAscend.

Функция mmioDescend ищет заданный фрагмент начиная с текущей позиции. Если фрагмент найден, текущая позиция устанавливается на область данных. Напомним, что область данных расположена на 8 байт ближе к концу файла от начала фрагмента (рис. 2.3).

Функция mmioDescend

UINT mmioDescend( HMMIO hmmio, // идентификатор открытого файла LPMMCKINFO lpck, // указатель на структуру MMCKINFO // для текущего фрагмента LPMMCKINFO lpckParent, // указатель на структуру MMCKINFO // для внешнего фрагмента UINT wFlags); // режим поиска

Параметры функции:

hmmio

Идентификатор открытого файла, полученный с помощью функции mmioOpen

lpck

Указатель на структуру MMCKINFO, в которую будет записана информация о текущем фрагменте

lpckParent

Указатель на структуру MMCKINFO, описывающую внешний фрагмент, внутри которого выполняется поиск. В качестве внешнего фрагмента могут выступать только фрагменты "RIFF" или "LIST". Этот параметр можно указывать как NULL, если внешний фрагмент отсутствует

wFlags

Если указан флаг MMIO_FINDCHUNK , выполняется поиск фрагмента, заданного своим идентификатором, если MMIO_FINDLIST - выполняется поиск фрагмента внутри фрагмента "LIST", если MMIO_FINDRIFF - внутри фрагмента "RIFF".



Возвращаемое значение:

При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки

В приведенном ниже фрагменте кода открывается на чтение wav-файл, затем в нем выполняется поиск фрагментов "WAVE" и "fmt ":

hmmio = mmioOpen((LPSTR)lpszFileName, NULL, MMIO_READ | MMIO_ALLOCBUF); if(!hmmio) return WIOERR_FILEERROR;

memset(&ckRIFF, 0, sizeof(MMCKINFO)); ckRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E'); if(mmioDescend(hmmio, &ckRIFF, NULL, MMIO_FINDRIFF)) { mmioClose(hmmio,0); return WIOERR_BADFORMAT; }

memset(&ckFMT, 0, sizeof(MMCKINFO)); ckFMT.ckid = mmioFOURCC('f', 'm', 't', ' '); if(mmioDescend(hmmio, &ckFMT, &ckRIFF, MMIO_FINDCHUNK)) { mmioClose(hmmio,0); return WIOERR_BADFORMAT; }

Функция mmioAscend предназначена для продвижения текущей позиции к началу следующего фрагмента.

Функция mmioAscend

UINT mmioAscend( HMMIO hmmio, // идентификатор открытого файла LPMMCKINFO lpck, // указатель на структуру MMCKINFO UINT wFlags); // режим поиска

Параметры функции:

hmmio

Идентификатор открытого файла, полученный с помощью функции mmioOpen

lpck

Указатель на структуру MMCKINFO, предварительно заполненную функцией mmioDescend или mmioCreatechunk

wFlags

Параметр не используется, необходимо передавать нулевое значение.

Возвращаемое значение:

При нормальном завершении возвращается нулевое значение. В противном случае возвращается код ошибки


Содержание раздела