Initial commit: akai-fetch - AKAI sampler ISO downloader & extractor

- fetch: Go CLI tool for searching, downloading, and extracting
  AKAI sampler ISOs from archive.org
- scripts/extract_wavs.sh: Shell script driving akaiutil to
  convert samples to WAV
- Dockerfile: Multi-stage build packaging akaiutil + fetch
- third_party/akaiutil: Vendored akaiutil v4.6.7 source (GPLv2)
- docs/akaiutil.md: Full akaiutil reference
This commit is contained in:
2026-06-15 22:33:53 -07:00
commit 9f107b5f80
29 changed files with 24620 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env bash
# Extract all AKAI samples as WAV from all volumes in an AKAI disk image.
# Usage: ./extract_wavs.sh <iso-file> [output-dir]
# Uses a single akaiutil session to avoid repeated disk rescans.
set -euo pipefail
AKAIUTIL="${AKAIUTIL:-akaiutil}"
ISO="${1:?Usage: $0 <iso-file> [output-dir]}"
OUTPUT="${2:-wavs}"
# Derive ISO basename without extension, sanitized for filesystem use
isobase=$(basename "$ISO")
isobase="${isobase%.*}"
isobase=$(echo "$isobase" | sed 's/ /_/g' | sed 's/[^A-Za-z0-9_.-]/_/g' | sed 's/__*/_/g' | sed 's/^[_.]//; s/[_.]$//')
OUTPUT="$OUTPUT/$isobase"
TMPFILE=$(mktemp /tmp/akai_cmds.XXXXXX)
trap 'rm -f "$TMPFILE"' EXIT
mkdir -p "$OUTPUT"
# Phase 1: enumerate partitions from df output
echo "Enumerating partitions and volumes..."
DF_OUTPUT=$("$AKAIUTIL" -r "$ISO" 2>/dev/null <<< $'df\nq')
# Parse partition letters from the partition table in df output
PARTITIONS=()
while IFS= read -r line; do
if [[ "$line" =~ ^[[:space:]]+([A-Z])[[:space:]]+ ]]; then
PARTITIONS+=("${BASH_REMATCH[1]}")
fi
done <<< "$DF_OUTPUT"
if [[ ${#PARTITIONS[@]} -eq 0 ]]; then
echo "No partitions found in ISO. Trying single-partition layout..."
PARTITIONS=("A")
fi
echo "Found partitions: ${PARTITIONS[*]}"
# Scan each partition for volumes
VOLUME_LIST=$(
{
for p in "${PARTITIONS[@]}"; do
echo "cd /disk0/$p"
echo "dir"
done
echo "q"
} | "$AKAIUTIL" -r "$ISO" 2>/dev/null
)
# Parse partition-letter:volume-name pairs
VOLUMES=()
CURRENT_PART=""
while IFS= read -r line; do
for p in "${PARTITIONS[@]}"; do
if [[ "$line" == *"/disk0/$p >"* ]]; then
CURRENT_PART="$p"
fi
done
if [[ "$line" =~ ^[[:space:]]+[0-9]+[[:space:]]+(.+)[[:space:]]+-[[:space:]]+ ]]; then
name="${BASH_REMATCH[1]}"
name="${name%% -*}"
name="$(echo "$name" | sed 's/ *$//')"
if [[ -n "$CURRENT_PART" && -n "$name" ]]; then
VOLUMES+=("$CURRENT_PART|$name")
fi
fi
done <<< "$VOLUME_LIST"
echo "Found ${#VOLUMES[@]} volumes"
# Phase 2: build command file and create output dirs
> "$TMPFILE"
for entry in "${VOLUMES[@]}"; do
IFS='|' read -r part vol_name <<< "$entry"
safe_name=$(echo "$vol_name" | sed 's/ /_/g' | sed 's/[^A-Za-z0-9_.-]/_/g' | sed 's/__*/_/g' | sed 's/^[_.]//; s/[_.]$//')
[[ -z "$safe_name" ]] && safe_name="volume"
vol_dir="$OUTPUT/$safe_name"
mkdir -p "$vol_dir"
nav_name="${vol_name// /_}"
echo "lcd $vol_dir" >> "$TMPFILE"
echo "cd /disk0/$part/$nav_name" >> "$TMPFILE"
echo "sample2wavall" >> "$TMPFILE"
done
echo "lcd /" >> "$TMPFILE"
echo "q" >> "$TMPFILE"
# Phase 3: run extraction
echo "Starting extraction..."
START=$SECONDS
"$AKAIUTIL" -r "$ISO" < "$TMPFILE" 2>/dev/null > /tmp/akai_output.txt
DURATION=$((SECONDS - START))
total=0
while IFS= read -r line; do
if [[ "$line" =~ exported[[:space:]]+([0-9]+)[[:space:]]+file ]]; then
count="${BASH_REMATCH[1]}"
total=$((total + count))
echo " -> $count WAVs"
fi
done < /tmp/akai_output.txt
echo ""
echo "--- Done in ${DURATION}s ---"
echo "Total WAV files: $total"
echo ""
echo "WAVs are in: $OUTPUT/"