用一个笨脚本把动机录音按 BPM 归档,我踩到的坑

我写歌的方式很土:脑子里先冒出来一个八小节左右的东西,用手机录下来,之后堆在 ~/motif/ 里。攒到 180 多个 m4a 之后,问题来了——想找「大概 90 BPM 左右、偏小调的那种」,只能一个个点开听。我试过按日期排、按调性排,都不对路,因为我找动机的时候脑子里第一个浮现的往往是速度感,不是调。

于是写了个脚本,把每个文件前 20 秒丢给 aubio 估 BPM,按 10 BPM 一档归进子目录:

#!/usr/bin/env bash
# deps: ffmpeg, aubio (aubio-tools)
for f in *.m4a; do
  tmp=$(mktemp --suffix=.wav)
  ffmpeg -loglevel error -y -i "$f" -t 20 -ac 1 -ar 22050 "$tmp"
  bpm=$(aubio tempo "$tmp" 2>/dev/null | awk '/^[0-9.]+ bpm/ {printf "%d", $1}')
  rm -f "$tmp"
  [ -z "$bpm" ] && bpm=0
  bucket=$(( (bpm / 10) * 10 ))
  mkdir -p "bpm_$bucket"
  mv -- "$f" "bpm_$bucket/"
done

注意 aubio tempo 的输出格式是 120.00 bpm,得用 awk 把数字抠出来,我第一次直接把整行塞进算术表达式,脚本安静地把所有文件都扔进了 bpm_0,还以为是 aubio 坏了。

为什么只取前 20 秒:动机往往一上来就进节奏,而 aubio 对长音频的估计反而会被中段变化带跑。代价是——如果前奏是散板或者纯人声哼唱,估出来的值基本是垃圾,我有一批 60 左右的都被归到了 bpm_0 或 bpm_50。所以我把 bpm_0 当成「待人工听」的筐,反而成了个意外好用的收件箱。

另一个坑是速度翻倍:aubio 分不清 85 和 170,我的慢速动机经常被判成两倍。脚本里我没法自动修,只能接受——我按 10 BPM 分档,本来就是为了容忍这点误差,翻倍的情况会落到相邻两档,翻的时候耳朵能立刻听出来。真正失效的场景是复合拍和自由速度的段落,那种东西任何估速工具都不该信。

现在我的 motif/ 长这样:bpm_80/、bpm_90/、bpm_0/,文件名不动。找动机时先按速度进目录,再凭记忆挑,比全库乱翻快很多。

你们处理自己那些没命名的动机录音时,是按速度、调性还是按录音时的情绪分?我一直想找一个不用听就能分「情绪」的办法,但感觉这事本质上没法自动化。

0
赞同度 100% · 0 条评论 · 6 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。