Главная » Программирование звука » Файлы формата Standard MIDI

0

Файл  MIDI  представляет  собой  последовательность  блоков  данных.  Эти  блоки имеют такой же основной формат, что и блоки, используемые в форматах AIFF, IFF  и WAVE.  Каждая  область  содержит  четырехсимвольное  поле  типа,  4-байтный код длины (в формате MSB) и данные. Однако в противоположность другим форматам блоки MIDI не вкладываются друг в друга.

B  настоящее  время  существует  всего  два  типа  блоков.  Первый   MThd  со-

держит общую заголовочную информацию, второй MTrk одну дорожку.

Идентификация файлов MIDI

Блок  MThd,  встречающейся  в  начале  каждого  файла  MIDI,  является  лучшим признаком, по которому можно идентифицировать файл в формате Standard MIDI.

Листинг22.1. Идентификация файла в формате MIDI

#define ChunkName(a,b,c,d) (                       \ ((static_cast<unsigned long>(a)&255)<<24)                 \

+ ((static_cast<unsigned long>(b)&255)<<16)             \

+ ((static_cast<unsigned long>(c)&255)<<8)              \

+ ((static_cast<unsigned long>(d)&255)))

bool IsMidiFile(istream &file) {

file.seekg(0); // Переходим  на   начало файла.

unsigned long form = ReadIntMsb(file,4);

return (form == ChunkName("M",’T’,’h’,’d’));

}

Блок заголовка MIDI

Область  MThd,  как  показано  в  табл.  22.1,  содержит  ряд  основных  характерис-

тик файла MIDI. Все значения хранятся в формате MSB.

Музыкальная информация в файле MIDI организована в виде нескольких дорожек. Например, файл MIDI может хранить партии пианино, трубы и флейты в виде отдельных дорожек. Это хотя слегка и усложняет воспроизведение, зато делает более легким использование файлов MIDI для обмена музыкальными партитурами.

Таблица 22.1. Содержимое области MIDI MThd

Байты                               Описание

2                                              Тип файла

2                                               Количество дорожек

2                                              Формат времени

Существует   три   типа   файлов   MIDI,   отличающихся   организацией   дорожек. Файлы нулевого muna (type zero) содержат всего  одну дорожку. Очевидно, что их легче  всего  проигрывать.  Именно  таким  файлам  следует  отдавать  предпочтение, если вы хотите быть уверены, что ваши файлы MIDI легко удастся воспроизвести кому-либо  еще.  Файлы  первого  muna  (type  one)  содержат  несколько  дорожек,  которые  проигрываются  одновременно.  Программы  для  проигрывания  файлов  первого  типа  должны  перед  проигрыванием  как-то  преобразовать,  «выровнять»  данные  в  единый  поток событий.  Наконец,  файлы  второго типа  (type two)  содержат несколько  дорожек,  но  не  предполагают  никакой  связи  между  дорожками.  Файлы второго типа используются относительно редко.

O  формате  хранения  информации  о  времени  мы  поговорим  немного  позднее,

когда будем более подробно рассматривать синхронизацию MIDI.

Листинг 22.2. Чтение блока заголовка MIDI

void MidiRead::ReadHeader(void) {

unsigned long chunkType = ReadIntMsb(_stream,4); unsigned long bytesRemaining = ReadIntMsb(_stream,4); if (chunkType != ChunkName(‘M’,’T’,’h’,’d’)) {

// Первый   блок  должен иметь  метку  MThd

cerr << "First chunk must be *MThd’ chunk\n";

exit(1);

}

_fileType = ReadIntMsb(_stream,2);

_numberTracks = ReadIntMsb(_stream,2);

_timeFormat = ReadIntMsb(_stream,2);

bytesRemaining = 6;

// Санитарная проверка  типа  файла и  количества

// дорожек.

switch(_fileType) {

case 0:

// Дорожек: 1 . cerr << "Tracks: 1\n"; if (_numberTracks != 1)

// Ho в  файле … дорожек?!?!

cerr << "But it has " << _numberTracks << " tracks?!?!\n";

break;

case 1:

// Дорожки   … воспроизводятся одновременно.

cerr << "Tracks: " << _numberTracks << " simultaneous.\n";

break;

case 2:

// Дорожки   … Воспроизводятся  независимо.

cerr << "Tracks: " << _numberTracks << " independent.\n";

break;

default:

// Тип  файла  не   распознан.

cerr << "Unknown file type: " << _fileType << "\n";

}

// Дамп  формата  времени.

if (_timeFormat < 0) {   // Временной  код   SMPTE.

// Формат   времени  … (SMPTE) .

cerr << "Time Format: "<< _timeFormat << " (SMPTE)\n";

} else { // Временной  код   продолжительности

// Формат  времени: … тиков/четвертей  ноты.

cerr << "Time Format: " << _timeFormat << " ticks/quarter note\n";

} SkipBytes(_stream,bytesRemaining);

}

Источник: Кинтцель Т.  Руководство программиста по работе со звуком = A Programmer’s Guide to Sound: Пер. с англ. М.: ДМК Пресс, 2000. 432 с, ил. (Серия «Для программистов»).

По теме:

  • Комментарии