Skip to content

Instantly share code, notes, and snippets.

@shmerl
Last active May 28, 2022 09:04
Show Gist options
  • Save shmerl/dfbd8db87874ee4929f86fa070a80863 to your computer and use it in GitHub Desktop.
Save shmerl/dfbd8db87874ee4929f86fa070a80863 to your computer and use it in GitHub Desktop.
#!/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
@chris246
Copy link

It seems as if <game_dir>/content/content0/bundles/xml.bundle does not contain mappings for Blood and Wine.
Does anybody know where to find those?

@duracotton
Copy link

duracotton commented Jul 22, 2018

@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

@mainrs
Copy link

mainrs commented Aug 21, 2018

Is there a difference between the GOG and Steam version? @shmerl

@shmerl
Copy link
Author

shmerl commented Nov 27, 2018

@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.

@shmerl
Copy link
Author

shmerl commented Oct 27, 2019

@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