Технологии программирования миди

 Навигация:

 Поиск:

 Новости:

17.02.2007
Полностью переработан дизайн сайта.

6.01.2007
Добавлен раздел Наработки Полезные и интересные программы и их исходники от автора.

19.11.2006
Функции WriteVarLen и ReadVarLen портированы с СИ на Delphi читать

14.11.2006
Появилась cтатья Midi-протокол глазами программиста

24.10.2006
Написана вторая часть MMSystem Функции midiOutGetVolume midiOutSetVolume midiOutMessage midiOutShortMsg и midiOutLongMsg

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

1.09.2006
Добавлен раздел MMSystem в котором находятся
подробные опсания функций winmm.dll, определенных в модуле mmSystem.pas,
с примерами их использования в Delphi.

13.08.2006
Опубликован исходник приложения, записывающего игру на клавиатуре
в стандартный midi-файл SMF - 0

4.07.2006
Добавлен раздел Структура формата миди-файла

 Счетчики:
Rambler's Top100 Яндекс цитирования Rambler's Top100
 Контент:

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

Библиотека mmsystem.dll содержит удобные функции, специально предназначенные для работы с файлами RIFF-формата (хотя можно поль-зоваться стандартные функции ввода -вывода или функции семейства _hread и _hwrite). Специализированные функции успешно работают с блоками памяти большого размера (более 64 Кбайт), так как звуковые дан-ные редко помещаются в одном сегменте памяти.

Открытиефайла совершается функцией mmioOpen. Эта функция мо-жет открыть файл для буферизованного или небуферизованного ввода или для работы с файлом в оперативной памяти (полностью возможности ука-занной функции приведены в поставляемой совместно с MS SDK докумен-тации). Ниже приведен прототип функции mmioOpen

HMMIO
mmioOpen(LPSTR szFilename,
LPMMIOINFO lpmmioinfo,
DWORD dwOpenFlags);

Здесь szFilename -дальний указатель на текстовую строку, содержа-щую путь к открываемому файлу, lpmmioinfo -указатель на содержащую дополнительные параметры для операции открытия файла структуру MMIOINFO (может быть задан как NULL), dwOpenFlags -определяю-щие режим открытия файла флаги.

При успехе функция mmioOpen возвращает (нестандартный) иденти-фикатор открытого файла, который можно использовать только в функци-ях с префиксом mmio. Код ошибки можно определить, анализируя поле wErrorRet структуры MMIOINFO.

Формат структуры MMINFO описан в файле mmsystem.h как

typedef struct _MMIOINFO

{

// поля общего назначения

DWORD dwFlags; // общий флаг состояния

FOURCC fccIOProc; // код идентификации процедуры // ввода -вывода

LPMMIOPROC pIOProc; // указатель на процедуру // ввода -вывода

UINT wErrorRet; // код завершения

HTASK htask; // идентификатор локальной процедуры // ввода -вывода // поля для буферизированного ввода -вывода

LONG ccBuffer; // размер буфера (или 0L) HPSTR pchBuffer; // указатель на буфер (или NULL) HPSTR pchNext; // указатель на следующий байт при // операциях чтении или записи

HPSTR pchEndRead; // указатель на последний прочитанный байт

HPSTR pchEndWrite; // указатель на последний записанный байт

LONG lBufOffset; // дискового смещение начала буфера // поля для процедур ввода -вывода

LONG lDiskOffset; // дисковое смещение для следующей // операции чтения или записи

DWORD adwInfo[3]; // дополнительные данные // для типа MMIOPROC // прочие поля

DWORD dwReserved1; // зарезервировано

DWORD dwReserved2; // зарезервировано

HMMIO hmmio; // идентификатор открытого файла } MMIOINFO;

typedef MMIOINFO *PMMIOINFO: typedef MMIOINFO NEAR *NPMMIOINFO; typedef MMIOINFO FAF *LPMMIOINFO;

Структура MMIOINFO дает возможность задавать многочисленные способы работы с файлами -можно использовать файлы в памяти, можно определить собственную процедуру для выполнения нестандартного ввода или вывода или работать с открытыми средствами MS-DOS идентифика-торами файлов. В простейших случаях можно указать второй параметр функции mmioOpen как NULL и не использовать структуру MMIOINFO вообще.
hmmio=mmioOpen((LPSTR)lpszFilename, NULL, MMIO_READ | MMIO_ALLOCBUF);

Последний параметр функции mmioOpen предназначен для опреде-ления режима открытия файла в виде логической комбинации ИЛИ от-дельных флагов, ниже приведен их список

Идентификатор флага Описание режима открытия файла
MMIO_READ Чтение
MMIO_WRITE Запись
MMIO_READWRITE Чтение и запись
MMIO_CREATE Создание нового файла (если файл с таким именем уже существует, он обрезается до нулевой длины)
MMIO_DELETE Удаление файла (если удаление выполнено корректно, возвращается TRUE, в противном случае -FALSE)
MMIO_PARSE Создание текстовой строки, содержащей полный путь к файлу на основе пути, переданного функции через па-раметр szFilename; результат замещает буфер szFilename
MMIO_EXIST Определяет существование указанного файла (при су-ществовании создается текстовая строка, содержащая полный путь к файлу)
MMIO_ALLOCBUF Файл открывается для буферизованного ввода -вывода (по умолчанию размер буфера равен 8 Кбайт; изменить размер буфера можно заданием его в поле cchBuffer структуры MMIOINFO)
MMIO_COMPAT Файл открывается в режиме совместимости (файл может быть открыт несколько раз)
MMIO_EXCLUSIVE Файл будет открыт в монопольном режиме
MMIO_DENYWRITE Запрещает другим приложения открывать этот файл на запись
MMIO_DENYREAD Запрещает другим приложения открывать этот файл на чтение
MMIO_DENYNONE Другие приложения могут открывать файл и на запись, и на чтение
MMIO_GETTEMP Создание текстовой строки для открытия временного файла (строка записывается в буфер, адрес которого пе-редается через первый параметр функции; собственно открытие файла не выполняется)

В нижеследующем фрагменте кода выполняется создание файла, от-крываемого и на чтение, и на запись
hFile=mmioOpen(szFileName, NULL, MMIO_CREATE | MMIO_READWRITE);

Закрытиефайла, открытого функцией mmioOpen (после завершения работы с ним) должно осуществляться функцией mmioClose.
UINT mmioClose(HMMIO hmmio, UINT wFlags);

Параметр hmmio -полученный ранее с помощью функции mmioOpen идентификатор открытого файла, wFlags -определяющие режим закрытия файла флаги (можно указать флаг MMIO_FHOPEN для закрытия файла, открытого средствами MS-DOS). При успехе возвращается нулевое значе-ние, в противном случае -код ошибки.

Записьв открытый с помощью функции mmioOpen файл осуществля-ется с помощью функции mmioWrite. Эта функция позволяет за единич-ный вызов записать в файл блок данных размером большим 64 Кбайт; по-сле записи осуществляется перемещение текущей позиции в файле вперед на количество записанных байт.

LONG

mmioWrite(HMMIO hmmio, // идентификатор открытого файла
HPSTR hpBuff, // указатель на буфер данных LONG dwBytes); // размер буфера
При успехе функция mmioWrite возвращает количество записанных байт или -1 при возникновении ошибки.

Чтениеиз открытого с помощью функции mmioOpen файла выполня-ется функцией mmioRead, также позволяющей за один вызов прочитать блок данных размером более 64 Кбайт; после чтения осуществляется пере-мещение текущей позиции в файле вперед на количество прочитанных байт.

LONG
mmioRead(HMMIO hmmio, // идентификатор открытого файла
HPSTR hpBuff, // указатель на буфер данных LONG dwBytes); // размер буфера

При успехе функция mmioRead возвращает количество прочитанных байт или -1 при возникновении ошибки; при достижении конца файла воз-вращается нулевое значение.

Позиционированиев открытом с помощью функции mmioOpen файла выполняется функцией mmioSeek.

LONG

mmioSeek(HMMIO hmmio, // идентикатор открытого файла
LONG dwOffset, // смещение для текущей позиции int nOrigin); // код отсчета смещения

Величины dwOffset и nOrigin интерпретируются обычным для фай-ловых операций в языке С образом. При успехе функция mmioSeek воз-вращает новое смещение текущей позиции в файле (от начала файла, в байтах) или -1 при возникновении ошибки.

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

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

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=mmmioFOURCC(‘W’, ‘A’, ‘V’, ‘E’);

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

FOURCC mmioStringToFOURCC(LPCSTR szString, UINT wFlags);

Здесь szString -указатель на преобразуемую строку, закрытую дво-ичным нулем, при wFlags=MMIO_TOUPPER все символы строки будут преобразованы в заглавные. Функция mmioStringToFOURCC возвращает значение четырехбуквенного идентификатора, могущего быть использо-ванным при формировании нового фрагмента; пример использования функции приведен ниже

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

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

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

При wFlags=MMIO_CREATERIFF создается фрагмент "RIFF", при wFlags=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=waveioocbIn.lpWaveHdr->dwBytesRecorded
+ sizeof(PCMWAVEFORMAT) + 20; ck.fccType=mmioFOURCC(‘W’, ‘A’, ‘V’, ‘E’); mmioCreateChunk(hFile, (LPMMCKINFO) &ck, MMIO_CREATERIFF); }

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

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

Здесь lpckParent -указатель на структуру MMCKINFO, описываю-щую внешний фрагмент, внутри которого выполняется поиск. В качестве внешнего фрагмента могут выступать только фрагменты ‘RIFF’ или ‘LIST’; если внешний фрагмент отсутствует, этот параметр можно указы-вать как NULL. Если указан
wFlags=MMIO_FINDCHUNK, выполняется поиск фрагмента, заданного своим идентификатором, если
wFlags=MMIO_FINDLIST -выполняется поиск фрагмента внутри фраг-мента ‘LIST’, при
wFlags=MMIO_FINDRIFF -внутри фрагмента ‘RIFF’.

При нормальном завершении функция mmioDescend возвращает ну-левое значение, в противном случае -код ошибки. В нижеприведенном примере кода открывается на чтение 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 предназначена для продвижения текущей по-зиции к началу следующего фрагмента.

UINT

mmioAscend(HMMIO hmmio, // идентификатор открытого файла

LPMMCKINFO lpck, // указатель на стр-ру MMCKINFO

UINT wFlags); // режим поиска

Структура MMCKINFO должна быть предварительно заполнена функцией mmioDescend или mmioCreateChunk, параметр wFlags не ис-пользуется и должен быть нулевым.
При нормальном завершении функция mmioAscend возвращает нуле-вое значение, в противном случае -код ошибки.

Содержание
 Bash.org.ru:

 Реклама:

 ©Copyright:
http://www.last.h16.ru - программирование миди. Идея, разработка и поддержка : Mo-skin © 2006-2007
X