Blog. Just Blog

Парсинг метаданных FLAC-файлов на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Парсинг метаданных FLAC-файлов на Ассемблере
Парсинг метаданных FLAC-файлов на Ассемблере

Продолжу тему парсинга метаданных из медиафайлов разных форматов. Сегодня разберем аудиофайлы FLAC. Это очень популярный кодек, предназначенный для сжатия аудиоданных без потерь, используется с 2001 года и поддерживается большинством плееров. Формат хорошо документирован, к тому же имеет очень простую внутреннюю структуру.

Файл начинается с сигнатуры "fLaC", после нее следует DWORD с размером обязательного блока STREAMINFO, после которого могут быть расположены блоки метаданных и, наконец, закодированный аудиопоток. Нам нужны только блоки метаданных, в которых содержится интересующая информация об исполнителе, названии трека, альбоме и т.п. Блок метаданных начинается с 4-байтного заголовка, в котором первый байт содержит тип блока, а следующие 3 байта - длина данных этого блока. При последовательном переборе отдельных блоков нужно найти тот, который имеет тип 4, то есть VORBIS_COMMENT, другие типы просто пропускаем. Блок с тегами начинается с DWORD, в котором записана длина название используемой для кодирования библиотеки. Эти данные можно пропустить. Дальше следует блок тегов, его парсинг выполнятся точно так же, как это делалось для файлов OGG, структура данных также соответствует схеме Vorbis.
  1.         ; Открыть файл для чтения
  2.         invoke  CreateFile,sample,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
  3.         mov     [desc],eax
  4.  
  5.         ; Прочитать заголовок файла
  6.         invoke  _lread,[desc],buff,8
  7.  
  8.         ; Проверить корректность файла
  9.         mov     esi,buff
  10.         cmp     dword [esi],'fLaC'
  11.         jne     loc_close
  12.  
  13.         ; Длина STREAMINFO
  14.         mov     ebx,[esi+4]
  15.         bswap   ebx
  16.         ; Пропустить блок STREAMINFO
  17.         invoke  _llseek,[desc],ebx,FILE_CURRENT
  18.         cmp     eax,-1
  19.         je      loc_close
  20. loc_read:
  21.         ; Заголовок блока
  22.         invoke  _lread,[desc],buff,4
  23.  
  24.         ; Проверить тип блока, 4 = VORBIS_COMMENT
  25.         mov     ebx,dword [buff]
  26.         cmp     bl,4
  27.         je      @f
  28.  
  29.         ; Длина данных для пропуска
  30.         mov     bl