Skip to content

Instantly share code, notes, and snippets.

@jaggzh
Created July 21, 2024 10:27
Show Gist options
  • Save jaggzh/f687be9a23d267e641dc7ff7a1967b9a to your computer and use it in GitHub Desktop.
Save jaggzh/f687be9a23d267e641dc7ff7a1967b9a to your computer and use it in GitHub Desktop.
#!/bin/bash
# gist-paste -u https://gist.github.com/jaggzh/f687be9a23d267e641dc7ff7a1967b9a
tmpdel_s=$((60)) # 5 minutes
def_maxh=5
def_maxh_1=16 # Height for 1 file
def_maxh_2=10 # Height for each of 2 files
hw=$(stty size)
bin_chafa=$(which chafa)
if [[ -z $bin_chafa ]]; then
echo "You'll need to install chafa to generate the spectograms" >&2
exit 1
fi
if [[ -n $hw ]]; then
h=${hw% *}
[[ $h -gt $def_maxh ]] && h=$def_maxh
w=${hw#* }
else
w=140
h=20
echo "No term. Using default sizes: WxH ${w}x$h"
fi
# echo "Height: $h"
# echo "W: $w"
files=()
a=$1
opt_h=
while shift; do
case "$a" in
-h|--help) h=$1; opt_h=$1; shift ;;
*) files+=("$a")
esac
a=$1
done
if [[ ${#files[@]} -lt 1 ]]; then
echo "Display spectrogram in terminal"
echo "Usage: spect audio1.ext [..audioN.ext]"
exit
fi
if [[ -z $opt_h ]]; then
if [[ ${#files[@]} = 1 ]]; then
h=$def_maxh_1
elif [[ ${#files[@]} = 2 ]]; then
h=$def_maxh_2
fi
fi
clean_up() {
(
sleep "$tmpdel_s";
[[ -f $of ]] && rm -f "$of";
[[ -f $ofw ]] && rm -f "$ofw";
) & disown;
}
trap clean_up EXIT
umask 0177
of=$(mktemp "/tmp/imgspec-XXXXXX.png")
ofw=$(mktemp "/tmp/imgspec-XXXXXX.wav")
# ls -l "$of"
audiosecs=60
sw=$(((w*2)-1))
for f in "${files[@]}"; do
# echo "Working on: $f" >&2
fname=$f
if [[ $f = *.mp3 ]]; then
# Convert "$audiosecs" of $f and stores it in wav file named "$ofw"
# echo "Converting $f with ffmpeg..." >&2
ffmpeg -hide_banner -y -i "$f" -t "$audiosecs" "$ofw" &>/dev/null </dev/null
f="$ofw"
if [[ ! -f $ofw ]]; then
echo "No output audio created by ffmpeg in conversion of mp3" >&2
echo " Input: $f" >&2
echo " Output: $ofw (not found)" >&2
continue
fi
fi
samps=$(sox "$f" -n stat 2>&1 | grep 'Samples.read' | sed -e 's/^.*: *//')
if [[ $samps = 0 ]]; then
echo "Sox says file is 0 samples. Skipping: $fname"
else
sox "$f" \
-q \
-n trim 0 "$audiosecs" spectrogram \
-x "$sw" \
-y 64 \
-r \
-o "$of" &>/dev/null
soxrc=$?
if [[ $soxrc -ne 0 ]]; then
echo "Sox errored (rc: $soxrc) on file $f (it might be incomplete)" >&2
elif [[ ! -f $of ]]; then
echo "No spectrogram found at: $of" >&2
else
chafa -c full -f symbols \
--stretch \
-s ${w}x$h \
"$of"
echo -e '\033[A^'
fi
fi
printf '%s\n' "$fname"
done
echo "Done. Temp spectrogram ($of) will be deleted in $tmpdel_s seconds."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment