Skip to content

Instantly share code, notes, and snippets.

@shmerl
Last active May 9, 2025 21:43
Show Gist options
  • Save shmerl/5a9c1be1d5b10f080fc8d88d7ec8999d to your computer and use it in GitHub Desktop.
Save shmerl/5a9c1be1d5b10f080fc8d88d7ec8999d to your computer and use it in GitHub Desktop.
For extracting GOG Captain Blood Ogg audio files
#!/bin/bash
# Rough script for extracting Ogg/Vorbis audio files from *.ssb sound banks
# in Captain Blood found in <game_dir>/resource/sounds
#
# Usage: gog_captain_blood_extract_ogg.sh <bank_file>.ssb
#
# Uses ripgrep (rg)
# Notes:
#
# 1. Music themes are found in globals.ssb from index 057 to 127.
# Extracted example - main menu theme: globals_126.ogg
# Same theme is found in mini.ssb
#
# 2. without ripgrep, similar result can be achieved with grep like this (but it's much slower)
# grep --only-matching --byte-offset --binary --text --perl-regex <header> <source>
#
# 3. It's very basic and isn't trying to extract audio format according to the spec, it simply
# splits things when detecting the beginning of the Ogg header. So it mostly works for audio
# files placed back to back in the bank, but can produce incorrect data for some other cases.
source="$1"
source_size=$(stat -c %s "$source")
header='OggS\x00\x02'
offsets=( $(rg --no-line-number --only-matching --byte-offset --text "$header" "$source" | cut -d : -f 1) )
# setting the last offset to the size of the file
offsets[${#offsets[@]}]=$source_size
num_files=$(( ${#offsets[@]} - 1 ))
for ((i = 0; i < $num_files; i++)); do
left=${offsets[$i]}
right=${offsets[$((i+1))]}
idx=$(printf "%.${#num_files}u" $i) # nicely 0 prefixed index
dd if="$source" of="${source%.*}_${idx}.ogg" skip=${left}B count=$(($right - $left))B bs=64M
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment