Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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.

share|improve this question
3  
have you seen this page? mmartins.com/mmartins/bpmdetection/bpmdetection.asp Seems exactly what you are looking for. –  DaveParillo Apr 9 '10 at 4:24
    
@DaveParillo that "mood of a track" link is a link to your hard disk, and as such useless to anyone but you –  Justin Smith Apr 11 '10 at 7:48
    
@Justin Smith, he meant a file in BpmDj docs :) Here's the online version: bpmdj.yellowcouch.org/clustering.html –  kolypto Apr 11 '10 at 11:50
    
@Justin - sorry - twitchy trigger finger, I guess. –  DaveParillo Apr 12 '10 at 4:28

8 Answers 8

up vote 13 down vote accepted

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! :)

share|improve this answer
    
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 Apr 9 '10 at 16:24
1  
Thanks, I'll try in a couple of days and post the results :) I wonder whether FLAC supports such thing: I'll have to check this out. –  kolypto Apr 9 '10 at 19:51
    
Nice work on step #2. Wish I could upvote twice! –  DaveParillo Apr 12 '10 at 4:31
1  
Thanks :) Alas, my Amarok didn't notice the new tag in FLACs which I like the most :)) bug submitted. –  kolypto Apr 12 '10 at 15:36
    
How did you install it? the rpm they provide doesn't seem to work in my computer and I am struggling with the compilation. –  pedrosaurio Jul 25 '12 at 18:56

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/

share|improve this answer
    
The latest version also handles mp3s and ogg vorbis. –  encoded Jan 10 '13 at 20:51
    
Ubuntu has bpm-tools packages available in saucy. –  naught101 Apr 5 at 6:44

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.

share|improve this answer

While it is not just a tool like you say you are looking for, Banshee media player can detect bpm.

I use Banshee for all my music playing, organisation and synchronizing to portable players. I'm not affiliated, but I like the program the best of all that I've tried. It can also generate "smart playlists" based on all sorts of properties of the tracks, including bpm.

There is an extension which analyses all sorts of things about the song, and will find similar songs to the one you're playing. It's called Mirage, and I used it for a while, but I don't any more, as I've created a number of playlists of ones that suit various moods (not necessarily similar according to Mirage).

I don't know if Banshee will save the bpm it detected back into the ID3v2 "bpm" tag of the file. If anyone knows how to easily check the bpm tag from outside the program I'll check.

share|improve this answer

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

share|improve this answer

It's not Linux but may well work in Wine - I use MixMeister BPM Analyzer

share|improve this answer

I found another tool for tagging MP3 files with the correct BPM value.

It's called BPMDetect. Open-source. QT libs so works fine under Gnome. Comes with a GUI but can be compiled as a console only version (run "scons console=1" as stated in the readme.txt).

Otherwise, in the end, i've too used the "bpmcount" from BpmDJ as i had difficulties to compile BPMDetect on a 64 bits Ubuntu host (due to the fmodex dependency). So i took the (very cool and well-written) shell script above (see below), the "bpmcount" binary extracted from the [x64 .rpm][3] available on the BpmDJ website (i've just extract the .rpm with

pm2cpio bpmdj-4.2.pl2-0.x86_64.rpm|cpio -idv

and it worked like a charm. I just had to modify the above script as, out of the box, it weren't working on my side (problem with stdout / stderr of the bpmcount binary). My modification is about file redirection :

local bpm=$(bpmcount "$file" 3>&1 1>/dev/null 2>&3 | grep '^[0-9]' | cut -f1)
share|improve this answer

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|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.