Finally, there's another little script here that can be used to fix up issues like inconsistent artist naming. It only does "The X" -> "X, The" at the moment, but it's easy enough to extend.
Read on if you're happy with shell scripting (and a Linux or advanced Mac OS X user).
The following shell snippet will scan the target directory, in this case
$HOME/flac
, and calculate ReplayGain for all .flac
files within it. It assumes that each directory containing any flac
files may be treated as an album for purposes of ReplayGain tagging.
None of the other track metadata is touched and the audio stream is not
altered in any way.You'll need the flac tools installed since
metaflac
is what we'll use to calculate and apply replaygain tags. On an Ubuntu system the flac tools are in the (surprise!) flac
package.Copy this to
gain.sh
:#!/bin/bash if test $# -lt 1 ; then echo "Usage: $0 target-dir [target-dir [target-dir [ ... ] ] ]" exit 1 fi find "$@" -type d -execdir \ bash -c 'echo Scanning `pwd`/{}; if ls "{}"/*.flac >&/dev/null ; then metaflac --add-replay-gain "{}"/*.flac; fi' \ \;Then invoke as
sh gain.sh $HOME/flac
(assuming $HOME/flac
is the directory you want to recursively retag). You may specify more than one target directory to scan.Once you've tagged your flac files with track and album level ReplayGain information you can play music from different publishers, in different styles, and of different ages without some of it being almost inaudible and other tracks mind blowingly loud. Your player must support ReplayGain, of course.
Rhythmbox (if you use it) doesn't apply ReplayGain by default, but does support it. To enable:
gconftool-2 --type bool --set /apps/rhythmbox/use_replaygain 1No idea about iTunes and friends - can they even play flac?
Handily, you can also bulk convert your flac formatted collection to other formats (say, mid-quality MP3 or vorbis) for something like a portable player or a laptop with a small disk and in the process "burn in" the volume bias indicated by the ReplayGain tagging. That way players that don't understand per-track preamp, replaygain, etc will still produce reasonable volume levels without you having to re-encode your tracks from a lossy source and get the usual horrid results.
The
lame
mp3 encoder automatically calculates
replaygain, but it doesn't handle per-album gain. You can instruct it
not to apply replaygain and instead apply the preamp recorded in the
flac metadata with the undocumented flac decoder option --apply-replaygain-which-is-not-lossless
. There may be better ways; ideally you could specify an encoding preamp to the mp3 encoder.This script will scan the directory
flac
in the current directory, and write mp3 files to the mp3
directory under the current directory. Output will be medium/high
quality VBR MP3 with gain burned in to the audio stream and proper ID3
tags included. You can run one instance of the script per CPU core for
best performance, as the instances will communicate and make sure not
to step on each others' toes or duplicate work. You will need the lame
MP3 encoder installed to use this script. The script will skip files
that already exist in the target directory, so you can re-run it after
ripping your latest CD acquisitions and it'll only encode the new files.Of course, only a crazy person would run this without first making backups of their music collection. Then again, you'd have backups already, right? Right? Sigh.
Save to
flac2mp3.sh
and chmod a+x flac2mp3.sh
:#!/bin/bash if test "$#" -lt 1 ; then echo "Usage: $0 target-directory" exit 1 fi function gettag() { awk -F = /^${1}=/' { print $2; }' /tmp/tags-$$ } function rmlock() { trap '' EXIT rm -f "${lockfn}" exit 2 } if test "$1" = "convert" ; then # Called by self to convert a track. $2 is source track name, # $3 is source dir prefix, and $4 is target dir prefix. # # The track metadata is extracted, then the track is decoded with replaygain # bias applied during decoding. High quality VBR MP3 encoding is then done # on the adjusted audio stream. The end result is a decent quality MP3 # that will play at a sane volume even on players that don't understand # ReplayGain MP3 headers/tags. ifn="$2" ofn="${2/.flac/.mp3}" ofn="${ofn/$3/$4}" if ! test -a "${ofn}" || test "${ifn}" -nt "${ofn}" ; then # The file is either absent in the target directory or is older # then the source file. # # Check to see if another instance of the script is currently encoding # this file, and if not, start encoding it ourselves. There's a race here, # in that another instance may start work on the file between when we check # and when we start work, but we don't actually care as the worst outcome # is a little wasted CPU time. # # We'll use a lock file in the target directory to indicate activity. # odir="`dirname "${ofn}"`" lockfn="${odir}/.`basename "${ofn}"`.lock" if test -e "${lockfn}" 2>/dev/null ; then # Appears locked by another instance. Is it still alive? if kill -0 $(cat "${lockfn}"); then echo "Skipping ${ifn} - locked by another instance" exit 1 else echo "Clearing stale lock file for ${ofn}" rm "${lockfn}" fi fi # Notify any concurrent instances that we're working on this file trap rmlock EXIT SIGTERM SIGINT SIGQUIT SIGHUP mkdir -p "${odir}" touch "${lockfn}" # then process it echo "$$" > "${lockfn}" metaflac --export-tags-to=/tmp/tags-$$ "${ifn}" echo -n "Converting: ${ifn} ..." flac -d "$2" -c -s --apply-replaygain-which-is-not-lossless 2>/dev/null \ | nice lame -S -h -V 3 --noreplaygain \ --tt "$(gettag TITLE)" --ta "$(gettag ARTIST)" --tl "$(gettag ALBUM)" \ --ty "$(gettag DATE)" --tn "$(gettag TRACKNUMBER)" --tg "$(gettag GENRE)" \ --ignore-tag-errors \ - "/tmp/working-$$.mp3" if [ $? ] ; then mv /tmp/working-$$.mp3 "${ofn}" fi echo " done" else echo "Skipping ${ifn} - destination exists and is up to date" fi exit 0 fi # For each flac file in the source tree test to see if an MP3 must # be created and if so, make one. find "$1" -name \*.flac \ -exec "$0" convert "{}" flac mp3 \;Here's another script that goes through the collection and changes FLAC metadata to rename, eg, "The Cure" to "Cure, The". It's easily adapted to do other things too.
#!/bin/bash # # Fix some common metadata issues on my flac collection, including rewriting # artist names from "The X" to "X, The". # # Typical usage: # find flac -type f -name \*.flac -exec bin/cleanup_flac "{}" \; if test $# -lt 1 ; then echo "Usage: $0 target-file.flac" exit 1 fi function gettag() { awk -F = /^${1}=/' { print $2; }' /tmp/tags-$$ } metaflac --export-tags-to=/tmp/tags-$$ "$1" artist="$(gettag ARTIST)" # Convert "The X" -> "X, The" echo -n "Testing \"$1\": " if test "${artist:0:4}" = "The "; then artist="${artist:4}, The" metaflac --remove-tag="ARTIST" --set-tag="ARTIST=${artist}" "$1" echo "artist changed to ${artist}" else echo "ok" fi
Exactly what i was looking for, thanks!
ReplyDelete