Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
Shell
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111#!/bin/bash# prep-zoo-samples.sh — convert the 12 curated animal recordings at# ~/Desktop/notepat-samples/zoo/ into header-less float32 mono 48 kHz# .raw files at fedac/native/samples/zoo/<name>.raw for the C audio# engine to load at boot (audio.c: load_oneshot_bank).## Source files are a mix of .ogg/.oga/.wav/.mp3 and are NOT checked# into the repo. Output .raw files ARE checked into the repo so flash# builds work without network access (mirrors prep-piano-samples.sh).## Trims: snake → 3 s (15 s rattle source), whale → 7 s (53 s source),# lion → 3 s (multiple roars), owl → 4 s. Others < 4 s already, so# kept full length.## Loudness leveling: single-pass loudnorm so all 12 sit at similar# perceived volume. No analysis pass needed — single pass is fine for# 12 short files.## Idempotent: re-running just re-converts.## Requires: ffmpeg (brew install ffmpeg).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"NATIVE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"SRC_DIR="${HOME}/Desktop/notepat-samples/zoo"DST_DIR="${NATIVE_DIR}/samples/zoo"
if [ ! -d "${SRC_DIR}" ]; then echo "[prep-zoo] source directory not found: ${SRC_DIR}" >&2 exit 1fi
mkdir -p "${DST_DIR}"
# Name → (source-basename without ext, trim-seconds-or-empty)# Match the ZOO_NAMES table in pieces/notepat.mjs exactly.NAMES=(dog cat cow sheep bird pig lion owl frog horse snake whale)# Per-animal duration cap in seconds; "" = keep full length.trim_for() { case "$1" in lion) echo 3 ;; owl) echo 4 ;; snake) echo 3 ;; whale) echo 7 ;; *) echo "" ;; esac}
# Resolve source file for a name (accepts any of .ogg/.oga/.wav/.mp3/.flac).resolve_src() { local n="$1" for ext in ogg oga wav mp3 flac m4a; do if [ -f "${SRC_DIR}/${n}.${ext}" ]; then echo "${SRC_DIR}/${n}.${ext}" return 0 fi done return 1}
total_bytes=0total_samples=0
echo "[prep-zoo] converting ${#NAMES[@]} animals → ${DST_DIR}/<name>.raw"for name in "${NAMES[@]}"; do src="$(resolve_src "${name}" || true)" if [ -z "${src}" ]; then echo "[prep-zoo] WARNING: no source for ${name}, skipping" >&2 continue fi out="${DST_DIR}/${name}.raw" trim="$(trim_for "${name}")"
# ffmpeg pipeline: # -ss 0 -t N (optional duration trim — pre-decode) # -ac 1 -ar 48000 (mono, 48 kHz) # -af loudnorm=I=-16:LRA=11:TP=-1.5 (loudness leveling) # -f f32le (raw float32 little-endian) if [ -n "${trim}" ]; then ffmpeg -y -loglevel error -ss 0 -t "${trim}" -i "${src}" \ -ac 1 -ar 48000 \ -af "loudnorm=I=-16:LRA=11:TP=-1.5" \ -f f32le "${out}" else ffmpeg -y -loglevel error -i "${src}" \ -ac 1 -ar 48000 \ -af "loudnorm=I=-16:LRA=11:TP=-1.5" \ -f f32le "${out}" fi
# Verify output: must be divisible by 4 (float32) and non-empty. sz=$(wc -c < "${out}" | tr -d ' ') if [ "${sz}" -le 0 ] || [ $((sz % 4)) -ne 0 ]; then echo "[prep-zoo] ERROR: bad output ${out} (size=${sz})" >&2 exit 1 fi samples=$((sz / 4)) secs=$(awk -v s="${samples}" 'BEGIN { printf "%.2f", s / 48000.0 }') total_bytes=$((total_bytes + sz)) total_samples=$((total_samples + samples)) printf " %-6s %s → %s (%s samples, %ss)\n" \ "${name}" "$(basename "${src}")" "$(basename "${out}")" "${samples}" "${secs}"done
count=$(ls "${DST_DIR}"/*.raw 2>/dev/null | wc -l | tr -d ' ')total_secs=$(awk -v s="${total_samples}" 'BEGIN { printf "%.2f", s / 48000.0 }')size_h=$(du -sh "${DST_DIR}" | cut -f1)echo "[prep-zoo] done: ${count} files, ${total_bytes} bytes (${size_h}), ${total_secs}s total"