Парсинг метаданных Opus-файлов на Ассемблере
Парсинг метаданных Opus-файлов на Ассемблере
Пиратил тут очередную партию музыкальных новинок и один из альбомов оказался в невиданном ранее формате с расширением ".opus". Естественно, первым желанием было не послушать, а поковыряться во внутренностях файлов. Как оказалось, аудиокодек Opus это детище тех же разработчиков, которые до этого выпустили кодек OGG. Несомненно, алгоритмы кодирования звукового потока отличаются, а вот сама внутренняя структура файла практически в точности повторяет разобранный ранее формат OGG. В том числе и способ хранения метаданных, которые меня интересуют.
Все особенности работы с форматом OGG я описал в статье по приведенной выше ссылке, дублировать информацию не буду. Отличие заключается только в том, что сигнатура блока метаданных - это восьмибайтная строка "OpusTags", в остальном все без изменений. Код для парсинга метаданных Opus-файлов будет примерно следующим:
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],'Opus'
- jne loc_free
- cmp dword [esi+4],'Tags'
- jne loc_free
- ; Пропустить сигнатуру
- add esi,8
- ; Длина строки названия кодировщика
- 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]
Просмотров: 488 | Комментариев: 0
Метки: Assembler, мультимедиа
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария