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,0
  31.         bswap   ebx
  32.         jmp     loc_skip
  33. @@:
  34.         ; Размер данных
  35.         mov     bl,0
  36.         bswap   ebx
  37.  
  38.         ; Выделить память под метаданные
  39.         invoke  GlobalAlloc,GMEM_ZEROINIT,ebx
  40.         mov     [hMem],eax
  41.         invoke  GlobalLock,[hMem]
  42.         mov     [pMem],eax
  43.  
  44.         ; Прочитать метаданные
  45.         invoke  _lread,[desc],[pMem],ebx
  46.  
  47.         mov     esi,[pMem]
  48.         add     esi,dword [esi]
  49.         add     esi,4
  50.         ; Количество тегов
  51.         mov     ebx,dword[esi]
  52.         add     esi,4
  53.  
  54.         ; Метаданных нет
  55.         or      ebx,ebx
  56.         jz      loc_free
  57. loc_get_tags:
  58.         push    ebx
  59.  
  60.         ; Размер тега
  61.         mov     ecx,dword[esi]
  62.         add     esi,4
  63.  
  64.         ; Первые 4 символа названия тега
  65.         mov     eax,[esi]
  66.         ; Перевести в нижний регистр
  67.         or      eax,20202020h
  68.         mov     ebx,title
  69.         cmp     eax,'titl'
  70.         je      @f
  71.         mov     ebx,artist
  72.         cmp     eax,'arti'
  73.         je      @f
  74.         mov     ebx,album
  75.         cmp     eax,'albu'
  76.         je      @f
  77.  
  78.         ; Пропустить тег
  79.         add     esi,ecx
  80.         jmp     loc_next_tag
  81. @@:
  82.         ; Найти символ-разделитель
  83.         mov     al,'='
  84.         mov     edi,esi
  85.         repne   scasb
  86.         ; Передвинуть указатель на значение тега
  87.         mov     esi,edi
  88.         ; Разделитель не нашелся, битые данные
  89.         or      ecx,ecx
  90.         jz      loc_next_tag
  91.  
  92.         ; UTF-8 -> юникод
  93.         push    ecx
  94.         invoke  MultiByteToWideChar,CP_UTF8,0,edi,ecx,0,0
  95.         invoke  MultiByteToWideChar,CP_UTF8,0,edi,-1,ebx,eax
  96.         pop     ecx
  97.         ; Перейти к следующему тегу
  98.         add     esi,ecx
  99. loc_next_tag:
  100.         pop     ebx
  101.         ; Все теги обработали?
  102.         sub     ebx,1
  103.         jnz     loc_get_tags
  104.  
  105.         invoke  wsprintf,buff,mask,artist,album,title
  106.         add     esp,20
  107.         invoke  MessageBox,0,buff,szTitle,0
  108.  
  109. loc_free:
  110.         ; Освободить память
  111.         invoke  GlobalUnlock,[hMem]
  112.  
  113.         jmp     loc_close
  114.  
  115. loc_skip:
  116.         ; Перейти к следующей странице
  117.         invoke  _llseek,[desc],ebx,FILE_CURRENT
  118.         cmp     eax,-1
  119.         je      loc_close
  120.         jmp     loc_read
  121. loc_close:
  122.         invoke  CloseHandle,[desc]
Более подробное описание тегов Vorbis можно посмотреть здесь, а их рекомендованный список, наверное, такой же. Ну и не забывайте внимательно читать документацию, так как где-то для описания длины различных данных используется порядок байт big-endian, а где-то little-endian.

В приложении пример программы с исходным текстом, которая парсит метаданные из FLAC-файла и выводит их.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

FLAC.Metadata.Demo.zip (196,924 bytes)


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 188 | Комментариев: 0

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2022
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0044 сек.) / Память: 5 Mb
Наверх