Files
rustytorch/crates/models/rtx-csm/scripts/build_crema_d_manifest.sh
T
osobhandClaude Opus 4.7 9ebac71784 rtx-csm: scripts/build_crema_d_manifest.sh — CREMA-D corpus support
CREMA-D (7442 clips × 91 actors × 6 emotions × 12 sentences) — larger
and more naturalistic than RAVDESS (1440 × 24 × 8 × 2). Free, no
registration, sparse-cloneable from GitHub. Filename-encoded labels
parsed via case statement (bash 3.2 compatible — no associative
arrays).

Verified: 7442 rows balanced 1271 each of angry/disgust/fearful/
happy/sad + 1087 neutral.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-04-29 21:52:47 -07:00

92 lines
2.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Convert a CREMA-D AudioWAV directory into rtx-csm manifest.jsonl with
# proper emotion_tag, transcript, and speaker fields parsed from the
# filename encoding.
#
# CREMA-D download options:
# # 1. Sparse clone — only AudioWAV (470 MB):
# git clone --filter=blob:none --no-checkout --depth=1 \
# https://github.com/CheyneyComputerScience/CREMA-D.git /tmp/crema_d
# cd /tmp/crema_d
# git sparse-checkout init --cone && git sparse-checkout set AudioWAV
# git checkout
#
# # 2. HuggingFace mirror (needs Python `datasets` library)
#
# Filename convention: `1001_DFA_ANG_XX.wav`
# 1001 = actor ID (1001..1091)
# DFA = sentence ID (12 sentences total — see SENTENCE map below)
# ANG = emotion (ANG=anger, DIS=disgust, FEA=fear, HAP=happy,
# NEU=neutral, SAD=sad — 6 emotions, no surprised)
# XX = intensity (LO, MD, HI, XX=unspecified)
#
# Output:
# {"wav": "<abs path>", "transcript": "...", "emotion_tag": "[neutral]",
# "speaker": 0|1, "intensity": "HI", "sentence_id": "DFA"}
#
# Usage:
# scripts/build_crema_d_manifest.sh /tmp/crema_d/AudioWAV > /tmp/crema_d/manifest.jsonl
set -euo pipefail
ROOT="${1:?usage: $0 <crema_d_AudioWAV_dir>}"
if [[ ! -d "$ROOT" ]]; then
echo "not a directory: $ROOT" >&2
exit 1
fi
# zsh's `read` doesn't have -a, so spawn bash explicitly.
bash -c '
ROOT="$1"
sentence_for() {
case "$1" in
IEO) echo "It is eleven oclock." ;;
TIE) echo "That is exactly what happened." ;;
IOM) echo "I am on my way to the meeting." ;;
IWW) echo "I wonder what this is about." ;;
TAI) echo "The airplane is almost full." ;;
MTI) echo "Maybe tomorrow it will be cold." ;;
IWL) echo "I would like a new alarm clock." ;;
ITH) echo "I think I have a doctors appointment." ;;
DFA) echo "Dont forget a jacket." ;;
ITS) echo "I think I have seen this before." ;;
TSI) echo "The surface is slick." ;;
WSI) echo "We will stop in a couple of minutes." ;;
*) echo "" ;;
esac
}
for wav in "$ROOT"/*.wav; do
base=$(basename "$wav" .wav)
IFS="_" read -ra parts <<< "$base"
actor="${parts[0]}"
sent_id="${parts[1]}"
emo_code="${parts[2]}"
intensity="${parts[3]}"
case "$emo_code" in
ANG) e="angry" ;;
DIS) e="disgust" ;;
FEA) e="fearful" ;;
HAP) e="happy" ;;
NEU) e="neutral" ;;
SAD) e="sad" ;;
*) e="unknown" ;;
esac
text="$(sentence_for "$sent_id")"
if [[ -z "$text" ]]; then
echo "warn: unknown sentence_id $sent_id in $base" >&2
continue
fi
# Speaker parity: even-numbered actor → 0, odd → 1.
spk=$((10#$actor % 2))
jq -nc --arg w "$wav" --arg t "$text" --arg e "$e" \
--argjson s "$spk" --arg i "$intensity" --arg sid "$sent_id" \
"{wav: \$w, transcript: \$t, emotion_tag: (\"[\" + \$e + \"]\"), speaker: \$s, intensity: \$i, sentence_id: \$sid}"
done
' _ "$ROOT"