Any beat detection software for Linux?

19,266

Solution 1

At the site DaveParillo suggested I've found BpmDj project. It has a bpmcount executable that calculates the bpm very nice: it handles mp3 as well as flac:

161.135 Metallica/2008 - Death Magnetic/01-That Was Just Your Life.flac
63.5645 Doom3.mp3

The only thing that's left is to retag the collection. I'll update this answer whenever I succeed. Thanks! :)


Step 1

Run bpmcount against the entire collection and store the results into a textfile. The problem is that bpmcount crashes from time to time and tries to eat up to 2GB of memory when it processes several files so we should feed it with filenames one by one. Like this:

musicdir='/home/ootync/music'
find "$musicdir" -iregex ".*\.\(mp3\|ogg\|flac\|ape\)" -exec bpmcount {} \; \
    | fgrep "$musicdir" > "$musicdir/BPMs.txt"

Step 2

We'll need some additional packages: apt-get install vorbis-tools flac python-mutagen. Now have a look at how the 'bpm' tag can be added:

mid3v2 --TBPM 100 doom3.mp3
vorbiscomment -a -t "BPM=100" mother.ogg
metaflac --set-tag="BPM=100" metallica.flac

Alas, I have no *.ape tracks

Now we have the BPMs and the entire collection should be retagged. Here's the script:

cat "$musicdir/BPMs.txt" | while read bpm file ; do
    bpm=`printf "%.0f" "$bpm"` ;
    case "$file" in 
        *.mp3) mid3v2 --TBPM "$bpm" "$file" > /dev/null ;; 
        *.ogg) vorbiscomment -a -t "BPM=$bpm" "$file" ;; 
        *.flac) metaflac --set-tag="BPM=$bpm" "$file" ;; 
        esac
    done

Step 2.1 Revisited Here's a script that will add BPM tags to your collection.

It runs one process per CPU Core to make the process faster. Additionally, it uses no temporary files and it capable of detecting whether a file is already tagged.

Additionally, I've discovered that FLAC sometimes has both ID3 and VorbisComment inside. This script updates both.

#!/bin/bash

function display_help() {
    cat <<-HELP
            Recursive BPM-writer for multicore CPUs.
            It analyzes BPMs of every media file and writes a correct tag there.
            Usage: $(basename "$0") path [...]
            HELP
    exit 0
    }

[ $# -lt 1 ] && display_help

#=== Requirements
requires="bpmcount mid3v2 vorbiscomment metaflac"
which $requires > /dev/null || { echo "E: These binaries are required: $requires" >&2 ; exit 1; }

#=== Functions

function bpm_read(){
    local file="$1"
    local ext="${file##*.}"
    declare -l ext
    # Detect
    { case "$ext" in
        'mp3')  mid3v2 -l "$file" ;;
        'ogg')  vorbiscomment -l "$file" ;;
        'flac') metaflac --export-tags-to=- "$file" ;;
        esac ; } | fgrep 'BPM=' | cut -d'=' -f2
    }
function bpm_write(){
    local file="$1"
    local bpm="${2%%.*}"
    local ext="${file##*.}"
    declare -l ext
    echo "BPM=$bpm @$file"
    # Write
    case "$ext" in
        'mp3')  mid3v2 --TBPM "$bpm" "$file" ;;
        'ogg')  vorbiscomment -a -t "BPM=$bpm" "$file" ;;
        'flac') metaflac --set-tag="BPM=$bpm" "$file"
                mid3v2 --TBPM "$bpm" "$file" # Need to store to ID3 as well :(
                ;;
        esac
    }

#=== Process
function oneThread(){
    local file="$1"
    #=== Check whether there's an existing BPM
        local bpm=$(bpm_read "$file")
        [ "$bpm" != '' ] && return 0 # there's a nonempty BPM tag
    #=== Detect a new BPM
    # Detect a new bpm
    local bpm=$(bpmcount "$file" | grep '^[0-9]' | cut -f1)
    [ "$bpm" == '' ] && { echo "W: Invalid BPM '$bpm' detected @ $file" >&2 ; return 0 ; } # problems
    # Write it
    bpm_write "$file" "${bpm%%.*}" >/dev/null
    }

NUMCPU="$(grep ^processor /proc/cpuinfo | wc -l)"
find $@ -type f -regextype posix-awk -iregex '.*\.(mp3|ogg|flac)' \
    | while read file ; do
        [ `jobs -p | wc -l` -ge $NUMCPU ] && wait
        echo "$file"
        oneThread "$file" &
        done

Enjoy! :)

Solution 2

This is a command-line tool to detect the BPM and put it in the FLAC file tags:

http://www.pogo.org.uk/~mark/bpm-tools/

Solution 3

I used kolypto's original script using bpmcount and rewrote it for bpm-tag (utility of bpm-tools) which I had better luck with installing. I also made some improvements of my own.

You can find it on GitHub https://github.com/meridius/bpmwrap

Solution 4

I don't know of a tool that does exactly what you are looking for, but I have played around with MusicIP.

Used the linux / java version - it takes a long time to completely analyze a music library, but it really does work. You can find songs that are similar to other songs. You can right click on the playlist generated and select option to select more or fewer songs like the one selected. You can also choose to eliminate certain genre's. It's kind of cool, but after the wow factor wore off, I stopped using it.

The free version exports playlists up to 75 songs in (at least) m3u format.

It's currently unsupported, but I think they have tried to take it commercial as Predexis.

Solution 5

There is another tool recommended in this question on stackoverflow: aubio, which comes along with python modules.

I haven't tried it because I was kinda busy taking care of compiling BpmDj. Just in case anybody else finds themselves struggling similar troubles while trying, I'd like to strongly recommend to make absolutely sure:

  1. having downloaded the latest release of the BpmDj sources
  2. having the appropriate boost libraries installed

With the latest g++ compiler upgrades, some issues seem to have arisen especially concerning recent debian and ubuntu releases. As soon as he became aware of these problems, the author had the kindness to fix the emerged incompatibilities and put together a new release which now compiles like a charm. So anybody who have been close to falling into despair over relentless compile errors lately: you are save now.

@mmx, your tools look good too, but they rely on SoX, which by default has no mp3 features. So they require compiling SoX with Lame/MAD support first, which unfortunately is too much effort for people as lazy as me.

Share:
19,266

Related videos on Youtube

Murshid Ahmed
Author by

Murshid Ahmed

Updated on September 17, 2022

Comments

  • Murshid Ahmed
    Murshid Ahmed almost 2 years

    Amarok 2 can search through music collection using ID3v2 tag's 'bpm' field. That would be very nice to retag the entire music collection so I can find the 'mood' of the track I like.

    However I've not found any beat-detection software that could have helped me. Have you ever used one? CLI, preferably. Also I'm interested if there's anything alike for tagging FLACs with the same 'bpm' field.

    Thanks! :)

    P.S. I'm aware there's a nice moodbar feature, however it's useless for searching.

    • DaveParillo
      DaveParillo about 14 years
      have you seen this page? mmartins.com/mmartins/bpmdetection/bpmdetection.asp Seems exactly what you are looking for.
    • Justin Smith
      Justin Smith about 14 years
      @DaveParillo that "mood of a track" link is a link to your hard disk, and as such useless to anyone but you
    • Murshid Ahmed
      Murshid Ahmed about 14 years
      @Justin Smith, he meant a file in BpmDj docs :) Here's the online version: bpmdj.yellowcouch.org/clustering.html
    • DaveParillo
      DaveParillo about 14 years
      @Justin - sorry - twitchy trigger finger, I guess.
  • DaveParillo
    DaveParillo about 14 years
    Excellent! I hadn't gotten around to trying this last night. As far as command line tagging, try mid3v2: linux.die.net/man/1/mid3v2, serviceable at least until Ex Falso supports command line editing. The id3v2 tad id is TBPM
  • DaveParillo
    DaveParillo about 14 years
    Nice work on step #2. Wish I could upvote twice!
  • Murshid Ahmed
    Murshid Ahmed about 14 years
    Thanks :) Alas, my Amarok didn't notice the new tag in FLACs which I like the most :)) bug submitted.
  • pedrosaurio
    pedrosaurio almost 12 years
    How did you install it? the rpm they provide doesn't seem to work in my computer and I am struggling with the compilation.
  • Murshid Ahmed
    Murshid Ahmed almost 12 years
    @pedrosaurio, I compiled it :) Just look carefully at the errors you get during make and install the mentioned packages
  • encoded
    encoded over 11 years
    The latest version also handles mp3s and ogg vorbis.
  • naught101
    naught101 about 10 years
    Ubuntu has bpm-tools packages available in saucy.
  • Benubird
    Benubird over 9 years
    Apparently bpmdj is an android app; how did you extract the bpmcount function from it? Is it available seperately free or do we need to buy the app?
  • max pleaner
    max pleaner over 7 years
    @kolypto the link is not working anymore to the source code. Is it the same thing as this?
  • Adrian
    Adrian over 7 years
    This required a few modifications to work on a Mac, which I have included in my own answer below (because it is too long for a comment)