Last active
May 28, 2022 09:04
-
-
Save shmerl/dfbd8db87874ee4929f86fa070a80863 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Usage: gog_tw3_extract_music.sh <game_dir> | |
# | |
# The script relies on these utilities: | |
# 1. QuickBMS extractor (quickbms) | |
# See http://aluigi.altervista.org/quickbms.htm | |
# Source: http://aluigi.altervista.org/papers/quickbms_src.zip | |
# | |
# 2. Witcher 3 BMS script to be used with QuickBMS (witcher3.bms) | |
# Source: http://aluigi.altervista.org/bms/witcher3.bms | |
# | |
# 3. Wwise BNK extractor | |
# Source: https://github.com/eXpl0it3r/bnkextr | |
# | |
# 4. Wwise WEM to ogg convertor | |
# Source: https://github.com/hcs64/ww2ogg | |
# | |
# 4.1 Binary codebooks for ww2ogg | |
# https://github.com/hcs64/ww2ogg/raw/master/packed_codebooks_aoTuV_603.bin | |
# | |
# Notes: | |
# | |
# 1. <game_dir> is the directory where the Witcher 3 is installed (which has subdir like content and etc.). | |
# | |
# 2. The script assumes, all extraction tools are placed in ${HOME}/bin/extractors | |
# override extractors variables when running the script if you placed them elsewhere or they are named differently. | |
# | |
# 3. By default the script will clean temporary files. If you want to preserve them for your own investigation, | |
# override clean variable. | |
# | |
# 4. [Optional]: To get titles for numbered files, use official TW3 Mod Kit (it works in Wine), and uncook | |
# <game_dir>/content/content0/bundles/xml.bundle | |
# | |
# Example (from Wine cmd, using <game_dir> relative to Wine's C:/ location): | |
# wcc_lite uncook -indir=C:/<game_dir>/content/content0/bundles -outdir=<target-dir> -infile=C:/<game_dir>/content/content0/bundles/xml.bundle | |
# | |
# Then locate <target-dir>/soundbanks/pc/soundbanksinfo.xml which contains needed mappings. | |
# | |
base_path="$1" | |
quickbms=${quickbms:-"$HOME/bin/extractors/quickbms"} | |
witcher3bms=${witcher3bms:-"$HOME/bin/extractors/witcher3.bms"} | |
ww2ogg=${ww2ogg:-"$HOME/bin/extractors/ww2ogg"} | |
codebooks=${codebooks:-"$HOME/bin/extractors/packed_codebooks_aoTuV_603.bin"} | |
bnkextr=${bnkextr:-"$HOME/bin/extractors/bnkextr"} | |
clean=${clean:-true} # Override as false if you want to keep temporary files. | |
sources=( | |
content/content0/soundspc.cache | |
content/content1/soundspc.cache | |
content/content2/soundspc.cache | |
content/content3/soundspc.cache | |
content/content4/soundspc.cache | |
content/content5/soundspc.cache | |
content/content6/soundspc.cache | |
content/content7/soundspc.cache | |
content/content10/soundspc.cache | |
) | |
function extract_tw3_soundcache() { | |
local source="$1" | |
local target_dir="$2" | |
echo "Extracting ${source} -> ${target_dir}" | |
$quickbms $witcher3bms "${source}" "${target_dir}" | |
} | |
function extract_wem() { | |
local source="$1" | |
local target_dir="$2" | |
local source_name=$(basename "$source") | |
local target="${target_dir}/${source_name%%.*}.ogg" | |
mkdir -v -p "$target_dir" | |
echo "Extracting ${source} -> ${target}" | |
$ww2ogg "$source" -o "$target" --pcb $codebooks | |
} | |
function extract_bnk() { | |
local source="$1" | |
local target_dir="$2" | |
cd "$target_dir" | |
$bnkextr "$source" | |
for tmpwem in *.wem; do | |
local name=$(basename $source) | |
mv -v "$tmpwem" "${name%%.*}_${tmpwem}" | |
done | |
cd - | |
} | |
for ((i=0; i < ${#sources[@]}; i++)); do | |
mkdir -p ${i} | |
mkdir tmp | |
extract_tw3_soundcache "${base_path}/${sources[$i]}" ${i} | |
for src in ${i}/*.bnk; do | |
extract_bnk "$(pwd)/$src" "tmp" | |
mv -v tmp/*.wem ${i} | |
if ${clean}; then | |
rm -v "$src" | |
fi | |
done | |
for src in ${i}/*.wem; do | |
source_dir=$(dirname "$src") | |
target_dir="${source_dir}/ogg" | |
extract_wem "$src" "${target_dir}" | |
if ${clean}; then | |
rm -v "$src" | |
fi | |
done | |
rmdir -v tmp | |
done |
Is there a difference between the GOG and Steam version? @shmerl
@chris246 @duracotton @sirwindfield: sorry, missed your comments because Github doesn't notify about them. Thanks for the heads up about the updated xml source for titles. I'll take a look and update the notes in the script.
Regarding differences with Steam, I didn't compare, since I only have GOG version. Thus the script name.
@duracotton: I just checked, and I actually don't have content\patch1\bundles\patch.bundle
at all. May be latest version combines them all in content/content0/bundles/xml.bundle
properly?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@chris246: Yes, the \The Witcher 3\content\content0\bundles\xml.bundle contains the old soundbanksinfo.xml
The updated one including BaW mappings can be found here: \The Witcher 3\content\patch1\bundles\patch.bundle