Парсинг метаданных FLAC-файлов на Ассемблере
Парсинг метаданных FLAC-файлов на Ассемблере
Продолжу тему парсинга метаданных из медиафайлов разных форматов. Сегодня разберем аудиофайлы FLAC. Это очень популярный кодек, предназначенный для сжатия аудиоданных без потерь, используется с 2001 года и поддерживается большинством плееров. Формат хорошо документирован, к тому же имеет очень простую внутреннюю структуру.
Файл начинается с сигнатуры "fLaC", после нее следует DWORD с размером обязательного блока STREAMINFO, после которого могут быть расположены блоки метаданных и, наконец, закодированный аудиопоток. Нам нужны только блоки метаданных, в которых содержится интересующая информация об исполнителе, названии трека, альбоме и т.п. Блок метаданных начинается с 4-байтного заголовка, в котором первый байт содержит тип блока, а следующие 3 байта - длина данных этого блока. При последовательном переборе отдельных блоков нужно найти тот, который имеет тип 4, то есть VORBIS_COMMENT, другие типы просто пропускаем. Блок с тегами начинается с DWORD, в котором записана длина название используемой для кодирования библиотеки. Эти данные можно пропустить. Дальше следует блок тегов, его парсинг выполнятся точно так же, как это делалось для файлов OGG, структура данных также соответствует схеме Vorbis.
Code (Assembler) : Убрать нумерацию
- ; Открыть файл для чтения
- invoke CreateFile,sample,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
- mov [desc],eax
- ; Прочитать заголовок файла
- invoke _lread,[desc],buff,8
- ; Проверить корректность файла
- mov esi,buff
- cmp dword [esi],'fLaC'
- jne loc_close
- ; Длина STREAMINFO
- mov ebx,[esi+4]
- bswap ebx
- ; Пропустить блок STREAMINFO
- invoke _llseek,[desc],ebx,FILE_CURRENT
- cmp eax,-1
- je loc_close
- loc_read:
- ; Заголовок блока
- invoke _lread,[desc],buff,4
- ; Проверить тип блока, 4 = VORBIS_COMMENT
- mov ebx,dword [buff]
- cmp bl,4
- je @f
- ; Длина данных для пропуска
- mov bl,0
- bswap ebx
- jmp loc_skip
- @@:
- ; Размер данных
- mov bl,0
- bswap ebx
- ; Выделить память под метаданные
- invoke GlobalAlloc,GMEM_ZEROINIT,ebx
- mov [hMem],eax
- invoke GlobalLock,[hMem]
- mov [pMem],eax
- ; Прочитать метаданные
- invoke _lread,[desc],[pMem],ebx
- mov esi,[pMem]
- add esi,dword [esi]
- add esi,4
- ; Количество тегов
- mov ebx,dword[esi]
- add esi,4
- ; Метаданных нет
- or ebx,ebx
- jz loc_free
- loc_get_tags:
- push ebx
- ; Размер тега
- mov ecx,dword[esi]
- add esi,4
- ; Первые 4 символа названия тега
- mov eax,[esi]
- ; Перевести в нижний регистр
- or eax,20202020h
- mov ebx,title
- cmp eax,'titl'
- je @f
- mov ebx,artist
- cmp eax,'arti'
- je @f
- mov ebx,album
- cmp eax,'albu'
- je @f
- ; Пропустить тег
- add esi,ecx
- jmp loc_next_tag
- @@:
- ; Найти символ-разделитель
- mov al,'='
- mov edi,esi
- repne scasb
- ; Передвинуть указатель на значение тега
- mov esi,edi
- ; Разделитель не нашелся, битые данные
- or ecx,ecx
- jz loc_next_tag
- ; UTF-8 -> юникод
- push ecx
- invoke MultiByteToWideChar,CP_UTF8,0,edi,ecx,0,0
- invoke MultiByteToWideChar,CP_UTF8,0,edi,-1,ebx,eax
- pop ecx
- ; Перейти к следующему тегу
- add esi,ecx
- loc_next_tag:
- pop ebx
- ; Все теги обработали?
- sub ebx,1
- jnz loc_get_tags
- invoke wsprintf,buff,mask,artist,album,title
- add esp,20
- invoke MessageBox,0,buff,szTitle,0
- loc_free:
- ; Освободить память
- invoke GlobalUnlock,[hMem]
- jmp loc_close
- loc_skip:
- ; Перейти к следующей странице
- invoke _llseek,[desc],ebx,FILE_CURRENT
- cmp eax,-1
- je loc_close
- jmp loc_read
- loc_close:
- invoke CloseHandle,[desc]
В приложении пример программы с исходным текстом, которая парсит метаданные из FLAC-файла и выводит их.
Просмотров: 560 | Комментариев: 0
Метки: Assembler, мультимедиа
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария