From e7f3e475a26b7a2aff38e2b97fdeee793f647871 Mon Sep 17 00:00:00 2001 From: ed Date: Fri, 31 Mar 2023 21:20:37 +0000 Subject: [PATCH] more accurate bpm detector --- bin/mtag/audio-bpm.py | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/bin/mtag/audio-bpm.py b/bin/mtag/audio-bpm.py index c9abec95..d7f2c1c5 100755 --- a/bin/mtag/audio-bpm.py +++ b/bin/mtag/audio-bpm.py @@ -16,6 +16,10 @@ dep: ffmpeg """ +# save beat timestamps to ".beats/filename.txt" +SAVE = False + + def det(tf): # fmt: off sp.check_call([ @@ -23,12 +27,11 @@ def det(tf): b"-nostdin", b"-hide_banner", b"-v", b"fatal", - b"-ss", b"13", b"-y", b"-i", fsenc(sys.argv[1]), b"-map", b"0:a:0", b"-ac", b"1", b"-ar", b"22050", - b"-t", b"300", + b"-t", b"360", b"-f", b"f32le", fsenc(tf) ]) @@ -47,10 +50,29 @@ def det(tf): print(c["list"][0]["label"].split(" ")[0]) return - # throws if detection failed: - bpm = float(cl[-1]["timestamp"] - cl[1]["timestamp"]) - bpm = round(60 * ((len(cl) - 1) / bpm), 2) - print(f"{bpm:.2f}") + # throws if detection failed: + beats = [float(x["timestamp"]) for x in cl] + bds = [b - a for a, b in zip(beats, beats[1:])] + bds.sort() + n0 = int(len(bds) * 0.2) + n1 = int(len(bds) * 0.75) + 1 + bds = bds[n0:n1] + bpm = sum(bds) + bpm = round(60 * (len(bds) / bpm), 2) + print(f"{bpm:.2f}") + + if SAVE: + fdir, fname = os.path.split(sys.argv[1]) + bdir = os.path.join(fdir, ".beats") + try: + os.mkdir(fsenc(bdir)) + except: + pass + + fp = os.path.join(bdir, fname) + ".txt" + with open(fsenc(fp), "wb") as f: + txt = "\n".join([f"{x:.2f}" for x in beats]) + f.write(txt.encode("utf-8")) def main():