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

Парсинг метаданных файлов SPX на Ассемблере
Аудиоформат Speex был создан в 2002 году как часть проекта Vorbis и использовался преимущественно для кодирования речи и в VoIP-телефонии. Этот формат сжимает аудиопоток с потерями, что означает снижение качества звука ради уменьшения размера файлов. Сегодня Speex считается устаревшим, его заменил более современный формат Opus. Однако файлы в формате Speex все еще можно встретить в интернете, поэтому важно уметь работать с их метаданными.
Speex, как и Opus, по сути является производным от базового формата OGG. Основные особенности работы с этим форматом описаны в соответствующей статье, поэтому повторяться не будем. Единственное отличие Speex заключается в сигнатуре блока метаданных - это четырехбайтная строка "Lavf". В остальном структура файла остается неизменной. Пример кода для парсинга метаданных SPX-файлов будет примерно следующим:
Code (Assembler) : Убрать нумерацию
- invoke CreateFile,sample,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
- mov [desc],eax
- loc_read:
- ; Прочитать заголовок страницы
- invoke _lread,[desc],buff,sizeof.OGG_PAGE_HEADER
- ; Проверить корректность страницы
- mov esi,buff
- cmp [esi+OGG_PAGE_HEADER.dMagic],'OggS'
- jne loc_close
- ; Количество сегментов в странице
- movzx ebx,[esi+OGG_PAGE_HEADER.bSegnemts]
- ; Прочитать таблицу размеров сегментов
- invoke _lread,[desc],tTable,ebx
- ; Подсчитать длину всех сегментов
- mov ecx,ebx
- mov esi,tTable
- xor ebx,ebx
- @@:
- lodsb
- movzx eax,al
- add ebx,eax
- loop @b
- ; Метаданные записаны в страницу 1
- mov esi,buff
- cmp [esi+OGG_PAGE_HEADER.dPage],1
- jne loc_skip
- ; Выделить память под метаданные
- invoke GlobalAlloc,GMEM_ZEROINIT,ebx
- mov [hMem],eax
- invoke GlobalLock,[hMem]
- mov [pMem],eax
- ; Прочитать метаданные
- invoke _lread,[desc],[pMem],ebx
- ; Сигнатура блока метаданных
- mov esi,[pMem]
- cmp dword [esi+4],'Lavf'
- jne loc_free
- 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
- ...
- ; artist -> наименование исполнителя
- ; album -> название альбома
- ; title -> название трека
- ...
- 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]
Просмотров: 218 | Комментариев: 0
Метки: Assembler, мультимедиа

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

Добавить комментарий
Заполните форму для добавления комментария
