-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmake-random
executable file
·107 lines (89 loc) · 3.08 KB
/
make-random
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/bin/bash
set -e -o pipefail
shopt -s extglob
target_LUFS=-16
redo_all=
while getopts 'hrl:' opt; do
case "$opt" in
r) redo_all=yes ;;
l) target_LUFS=$OPTARG ;;
h|'?')
cat <<USAGE
Usage: $0 [ -r ] [ -l LUFS ]
$0 -h
-r: re-do all files, useful to change loudness target.
-l: loudness target, in LUFS. E.g., -16.
-h: help (this message)
USAGE
exit
;;
esac
done
target=i=$target_LUFS:tp=-2:lra=20:dual_mono=true
ffshutup=(-nostdin -hide_banner -nostats -loglevel info)
if [ -n "$TERM" ] && [ -t 2 ]; then
smso=$(tput smso)
rmso=$(tput rmso)
else
smso=
rmso=
fi
declare -A found_input
while IFS= read -r -d $'\0' -u 8 fin; do # fd 8 is "find" at end of loop; pipe would create subshell.
fshort="${fin#random.in/}"
fshort="${fshort%.????(?)}"
fout="random/$fshort.opus"
found_input[$fout]=y
if [ -z "$redo_all" ] && [ -f "$fout" ] && ! [ "$fout" -nt "$fin" ] && ! [ "$fout" -ot "$fin" ]; then
continue
fi
echo "Processing $fshort:" >&2
foutdir=$(dirname "$fout")
if [[ "$fout" == */* ]] && ! [ -d "$foutdir" ]; then
echo " Creating subdir $foutdir." >&2;
mkdir -p "$foutdir"
fi
# the following is vomit-worthy. Thank you, ffmpeg.
IFS=' ' read -u 9 -r I TP LRA THRESH OFFSET 9< <(
ffmpeg "${ffshutup[@]}" -i "$fin" -filter:a loudnorm=$target:print_format=json -f null - \
|& grep '^{$' -A99 \
| jq -r '.input_i, .input_tp, .input_lra, .input_thresh, .target_offset' \
| tr '\n' ' '
echo
)
echo " I=$I TP=$TP LRA=$LRA THRESH=$THRESH OFFSET=$OFFSET" >&2
# now, decide if we're going to use loudnorm or volume to apply the
# change. This is a workaround due to a stupid limitation in
# loudnorm (LRA is limited to 20). Because all music must be
# overcompressed pop!
#
# If we're amplifying, presume we need loudnorm to avoid clipping.
# Otherwise, use volume. And so we get to compare decimals in bash,
# always a fun thing!
if echo "$I $target_LUFS" | awk '{ exit !($1 < $2) }'; then
# still have to grep this because fuck you ffmpeg
filter="loudnorm=$target:linear=true:print_format=summary:measured_i=$I:measured_lra=$LRA:measured_tp=$TP:measured_thresh=$THRESH:offset=$OFFSET"
ffmpeg "${ffshutup[@]}" -i "$fin" -filter:a "$filter" -c:a libopus -ar 48000 -vbr on -b:a 128k -y "$fout" \
|& grep -E '^(Output (Integrated|True Peak|LRA|Threshold)|Normalization Type|Target Offset)' \
| sed -e "s/Dynamic/${smso}Dynamic${rmso}/; s/^/ /" \
>&2
else
adjust="$(echo "$I $target_LUFS" | awk '{ print($2 - $1) }')"
echo " Adjusting $adjust dB." >&2
filter="volume=replaygain=drop:volume=${adjust}dB"
ffmpeg "${ffshutup[@]}" -loglevel error -i "$fin" -filter:a "$filter" \
-c:a libopus -ar 48000 -vbr on -b:a 128k -y "$fout"
fi
touch -m -r "$fin" "$fout"
echo -e "done.\n" >&2
done 8< <(find -L random.in/ -type f -print0)
echo -n 'Cleaning non-matching opus files from random... ' >&2
deleted=0
while IFS= read -r -d $'\0' -u 9 f; do
if ! [ y = "${found_input[$f]}" ]; then
let ++deleted
rm "$f"
fi
done 9< <(find random/ -name '*.opus' -type f -print0)
find random/ -type d -empty -delete
echo "$deleted removed." >&2