Blog. Just Blog

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

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

Аудиоформат Speex был создан в 2002 году как часть проекта Vorbis и использовался преимущественно для кодирования речи и в VoIP-телефонии. Этот формат сжимает аудиопоток с потерями, что означает снижение качества звука ради уменьшения размера файлов. Сегодня Speex считается устаревшим, его заменил более современный формат Opus. Однако файлы в формате Speex все еще можно встретить в интернете, поэтому важно уметь работать с их метаданными.

Speex, как и Opus, по сути является производным от базового формата OGG. Основные особенности работы с этим форматом описаны в соответствующей статье, поэтому повторяться не будем. Единственное отличие Speex заключается в сигнатуре блока метаданных - это четырехбайтная строка "Lavf". В остальном структура файла остается неизменной. Пример кода для парсинга метаданных SPX-файлов будет примерно следующим:
  1.         invoke  CreateFile,sample,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
  2.         mov     [desc],eax
  3. loc_read:
  4.         ; Прочитать заголовок страницы
  5.         invoke  _lread,[desc],buff,sizeof.OGG_PAGE_HEADER
  6.  
  7.         ; Проверить корректность страницы
  8.         mov     esi,buff
  9.         cmp     [esi+OGG_PAGE_HEADER.dMagic],'OggS'
  10.         jne     loc_close
  11.  
  12.         ; Количество сегментов в странице
  13.         movzx   ebx,[esi+OGG_PAGE_HEADER.bSegnemts]
  14.  
  15.         ; Прочитать таблицу размеров сегментов
  16.         invoke  _lread,[desc],tTable,ebx
  17.  
  18.         ; Подсчитать длину всех сегментов
  19.         mov     ecx,ebx
  20.         mov     esi,tTable
  21.         xor     ebx,ebx
  22. @@:
  23.         lodsb
  24.         movzx   eax,al
  25.         add     ebx,eax
  26.         loop    @b
  27.  
  28.         ; Метаданные записаны в страницу 1
  29.         mov     esi,buff
  30.         cmp     [esi+OGG_PAGE_HEADER.dPage],1
  31.         jne     loc_skip
  32.  
  33.         ; Выделить память под метаданные
  34.         invoke  GlobalAlloc,GMEM_ZEROINIT,ebx
  35.         mov     [hMem],eax
  36.         invoke  GlobalLock,[hMem]
  37.         mov     [pMem],eax
  38.  
  39.         ; Прочитать метаданные
  40.         invoke  _lread,[desc],[pMem],ebx
  41.  
  42.         ; Сигнатура блока метаданных
  43.         mov     esi,[pMem]
  44.         cmp     dword [esi+4],'Lavf'
  45.         jne     loc_free
  46.  
  47.         add     esi,dword[esi]
  48.         add     esi,4
  49.         ; Количество тегов
  50.         mov     ebx,dword[esi]
  51.         add     esi,4
  52.  
  53.         ; Метаданных нет
  54.         or      ebx,ebx
  55.         jz      loc_free
  56. loc_get_tags:
  57.         push    ebx
  58.  
  59.         ; Размер тега
  60.         mov     ecx,dword[esi]
  61.         add     esi,4
  62.  
  63.         ; Первые 4 символа названия тега
  64.         mov     eax,[esi]
  65.         ; Перевести в нижний регистр
  66.         or      eax,20202020h
  67.         mov     ebx,title
  68.         cmp     eax,'titl'
  69.         je      @f
  70.         mov     ebx,artist
  71.         cmp     eax,'arti'
  72.         je      @f
  73.         mov     ebx,album
  74.         cmp     eax,'albu'
  75.         je      @f
  76.  
  77.         ; Пропустить тег
  78.         add     esi,ecx
  79.         jmp     loc_next_tag
  80. @@:
  81.         ; Найти символ-разделитель
  82.         mov     al,'='
  83.         mov     edi,esi
  84.         repne   scasb
  85.         ; Передвинуть указатель на значение тега
  86.         mov     esi,edi
  87.         ; Разделитель не нашелся, битые данные
  88.         or      ecx,ecx
  89.         jz      loc_next_tag
  90.  
  91.         ; UTF-8 -> юникод
  92.         push    ecx
  93.         invoke  MultiByteToWideChar,CP_UTF8,0,edi,ecx,0,0
  94.         invoke  MultiByteToWideChar,CP_UTF8,0,edi,-1,ebx,eax
  95.         pop     ecx
  96.         ; Перейти к следующему тегу
  97.         add     esi,ecx
  98. loc_next_tag:
  99.         pop     ebx
  100.         ; Все теги обработали?
  101.         sub     ebx,1
  102.         jnz     loc_get_tags
  103.  
  104.         ...
  105.         ; artist -> наименование исполнителя
  106.         ; album -> название альбома
  107.         ; title -> название трека
  108.         ... 
  109.  
  110. loc_free:
  111.         ; Освободить память
  112.         invoke  GlobalUnlock,[hMem]
  113.  
  114.         jmp     loc_close
  115.  
  116. loc_skip:
  117.         ; Перейти к следующей странице
  118.         invoke  _llseek,[desc],ebx,FILE_CURRENT
  119.         cmp     eax,-1
  120.         je      loc_close
  121.         jmp     loc_read
  122. loc_close:
  123.         invoke  CloseHandle,[desc]
В приложении пример программы с исходным текстом, которая парсит метаданные из SPX-файла и выводит их.

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

SPX.Metadata.Demo.zip (402,544 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 218 | Комментариев: 0

Комментарии

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

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

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

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