Skip to content

Instantly share code, notes, and snippets.

@infval
Created January 2, 2019 04:07
Show Gist options
  • Save infval/f1b34736f289fc9cc7e64cee2d645c1f to your computer and use it in GitHub Desktop.
Save infval/f1b34736f289fc9cc7e64cee2d645c1f to your computer and use it in GitHub Desktop.
#-*- coding: utf-8 -*-
#!/usr/bin/env python3
"""
Pursuit Force: Extreme Justice (PSP)
VDB/VIB extractor
VAG без заголовка
В MFAudio аудиофайлы можно задать как:
'RAW - Raw Sound Data - Compressed ADPCM'
"""
import os
import sys
from struct import *
if len(sys.argv) > 1:
filename = sys.argv[1][:-4]
else:
sys.exit(1)
filename_vib = filename + ".vib"
filename_vdb = filename + ".vdb"
path_extract = filename + "_files"
with open(filename_vib, "rb") as f:
vib = f.read()
with open(filename_vdb, "rb") as f:
vdb = f.read()
if not os.path.exists(path_extract):
os.makedirs(path_extract)
add_vag_header = True
mfaudio = False
if os.path.exists("MFAudio.exe"):
mfaudio = True
"""
Структура VIB-файла
# Заголовок (20 байт)
0x00: 4 байта - VIB и \0
0x04: 4 - ? значение 01 00 00 00
0x08: 4 - ? значение 01 00 00 00
0x0C: 4 - количество VAG-файлов
0x10: 4 - количество Категорий после VAG-файлов
# Для каждого VAG-файла (50 байт)
32 - название файла с путём
4 - смещение относительно файла
4 - размер
4 - частота дискретизации
4 - ?
4 - индекс Категории от 0
# Для каждой Категории (40 байт)
32 - название Категории
4 - количество VAG-файлов в Категории
4 - ?
"""
files_offset = 20
files_count = unpack('<I', vib[0xC:0xC+4])[0]
print("Number of files:", files_count)
print("Format: [name, offset, size, frequency, ?, index of category]")
for i in range(files_count):
file_info = vib[files_offset+i*52:files_offset+(i+1)*52]
file_info = list(unpack('<32sIIIII', file_info))
file_info[0] = file_info[0].rstrip(b"\x00").decode("utf-8")
file_info[0] = file_info[0].replace("\\", "_")
filename_vag = "{:04}{}".format(i, file_info[0])
path = os.path.join(path_extract, filename_vag)
# Простой НЕправильный VAG-заголовок, нужен только для распознания
# задаёт частоту, размер (файл + 80) и моно
vag_header = b"VAGp" + pack('>IIII', 3, 0, file_info[2] + 80, file_info[3]) + b"\0" * (64-20)
with open(path, "wb") as f:
if add_vag_header:
f.write(vag_header)
f.write(vdb[file_info[1]:file_info[1]+file_info[2]])
if mfaudio:
os.system("MFAudio.exe /IF{0:05} /IC1 /OF{0:05} /OC1 /OTWAVU \"{1}\" \"{1}.wav\"".format(file_info[3], path))
print(file_info)
cat_offset = 20 + files_count * 52
cat_count = unpack('<I', vib[0x10:0x10+4])[0]
print("Number of categories:", cat_count)
print("Format: [name, number of vag, ?]")
for i in range(cat_count):
file_info = vib[cat_offset+i*40:cat_offset+(i+1)*40]
file_info = list(unpack('<32sII', file_info))
file_info[0] = file_info[0].rstrip(b"\x00").decode("utf-8")
print(file_info)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment