#!/bin/sh - # # This is a simple wrapper script for lame. # Syntax: lamewrap [ --] # [-o ] [-n] [-d] [-q] # [...] # # Any options are passed to LAME and can be used to # modify the default settings of the wrapper script. # However, you shoudl know exactly what you're doing. # If you specify any LAME options, you have to end # them with a double-dash ("--"), in order to separate # them from input file arguments and/or wrapper script # options (if any). # # Input files may be in WAV format (filename extension # .wav), or raw PCM format in native byteorder (.raw or # .pcm). All other filename extensions are rejected, # because it is important to recognize them. Otherwise, # If you try to encode a WAV file (or any other file with # a header) as raw PCM, you'll get a small "click" at the # beginning of the resulting mp3 file. # # You can specify as many input files as you want. You # can also specify directory names, in which case the # script will look for files named *.{wav,raw,pcm} in # thos directories. The output files will be named with # an .mp3 extension, which replaces the other extension. # By default, the mp3 files will be in the same directory # as the input files. You can use the -o option (after # any LAME options, separated by "--", if any) to specify # a different output directory. # # When the -n option is used, encoding will be done at # a priority of "nice 20" (i.e. lowest). When the -d # option is used, each input file will be deleted after # encoding. The -q option makes LAME and lamewrap quiet. # # If you have an SMP system (i.e. multiple processors), # you can savely run multiple instances of this script on # the same set of files. You can also interrupt the # script anytime and restart it. It will recognise which # files have already completed and skip them. However, # it will have to restart any incompletely encoded file # from scratch. # # In the simplest case, you can just type: # # lamewrap . # # to encode all files in the current directory. If you # have two processors (SMP), just type that command a # second time in another session or window. # # Note: During encoding, a lockfile *.lock is created. # Actually it's a symlink which points to the PID of the # script which is (or was) responsible for encoding this # particular file. This ensures that multiple instances # of the script won't interfere with each other, and that # an interrupted encoding can be recognized. # # The default is to use variable bitrate (VBR) with # VBR-quality "4" (which ends up to roughly 160 kbps with # average music, but that can vary depending on the type # of music), algorith-quality 0 (slow, but best possible # quality) and "joint stereo" encoding with automatic # LR/MS selection (best possible choice for music). This # results in CD-quality, in general. You don't have to # give any further options. # # Note: LAME 3.91 is required. Any newer version might # work, too, but that has not been tested. # ### The default is "CD quality" (roughly 160 kbps): VBRQ=4 # 0...9 (0 = best quality, but large files) QUAL=0 # 0...2 (0 = best quality, but slow) MODE=j # s, j, f, d, m (stereo, joint-stereo, forced, dual, mono) ### Do not change the script -- you can change the defaults ### by overriding them on the commandline, e.g.: ### lamewrap -V 2 -q 2 -- track01.pcm ### will encode much faster, but result in larger files. ME=`basename "$0"` LAME=/usr/local/bin/lame WAVFLAGS="-k -m $MODE -h -q $QUAL -v -V $VBRQ -B 320 -t" PCMFLAGS="-r -x -s 44.1 $WAVFLAGS" Usage() { echo "Usage: $ME [ ... --] [ ...] ..." >&2 echo "Known wrapper options:" >&2 echo " -n run at \"nice 20\" priority" >&2 echo " -d delete input files after encoding" >&2 echo " -q make LAME and $ME quiet" >&2 echo " -o output directory" >&2 echo "See the script for more documentation: $0" >&2 exit 1 } OUTDIR="" USEROPTS="" DELINPUT=false QUIET=false # # User-specified LAME options: # Look if there's an argument "--" somewhere. # If so, then take everything up to that point # as additional LAME options. # for i in "$@"; do if [ "x$i" = "x--" ]; then DONEOPTS=false while [ $# -gt 0 ]; do case "$1" in --) DONEOPTS=true shift break ;; esac USEROPTS="$USEROPTS $1" shift done if ! $DONEOPTS; then Usage fi break fi done # # Now check for our own wrapper script options. # while :; do case "$1" in -o) if [ $# -le 0 ]; then Usage fi OUTDIR="$2" if [ ! -d "$OUTDIR" ]; then echo "${ME}: Output directory \"$OUTDIR\" does not exist." >&2 exit 1 fi shift 2 ;; -n) renice 20 $$ shift ;; -d) DELINPUT=true shift ;; -q) QUIET=true USEROPTS="$USEROPTS --quiet" shift ;; -H|--*[Hh][Ee][Ll][Pp]|-\?) $LAME "$1" exit 1 ;; --) shift break ;; -*) Usage ;; *) break ;; esac done if [ $# -le 0 ]; then Usage fi BOLD_ON=`tput md` BOLD_OFF=`tput me` Print() { if ! $QUIET; then echo "${BOLD_ON}$*${BOLD_OFF}" >&2 fi } Print_Line() { Print `jot -b '=' -s '' 79` Print "$*" } Encode_File() { Print_Line "Encoding: $1" case "$1" in *.[Ww][Aa][Vv]) FLAGS="${WAVFLAGS}${USEROPTS}" ;; *.[Rr][Aa][Ww]|*.[Pp][Cc][Mm]) FLAGS="-r -x -s 44.1 -k -m $MODE -h -v -V $VBRQ -B 320 -t" ;; *) echo "Unknown filename extension, must be .wav, .raw or .pcm." >&2 exit 1 ;; esac BASE=`expr "x$1" : 'x\(.*\)\.[^.]*$'` LOCK="${BASE}.lock" DEST="${BASE}.mp3" if [ -n "$OUTDIR" ]; then DEST="${OUTDIR}/"`basename "$DEST"` fi if [ -e "$DEST" ]; then if [ -L "$LOCK" ]; then PID=`readlink "$LOCK"` if ! ps -p "$PID" >/dev/null; then Print "Restarting aborted encoding of this file." if mv "$LOCK" "${LOCK}.$$" 2>/dev/null; then if [ `readlink "${LOCK}.$$"` != "$PID" ]; then mv "${LOCK}.$$" "$LOCK" else rm -f "${LOCK}.$$" fi fi fi else Print "Already done, skipping." return fi fi if ! ln -s $$ "$LOCK" 2>/dev/null; then Print "Already in progress by another instance of this script, skipping." return fi if ! $QUIET; then echo "LAME flags: $FLAGS" >&2 fi if $LAME $FLAGS "$1" "$DEST"; then if $DELINPUT; then rm "$1" fi fi rm -f "$LOCK" } for i in "$@"; do if [ -d "$i" ]; then ls -L $i \ | egrep -i '\.(wav|raw|pcm)$' \ | while read f; do Encode_File "$f" done else Encode_File "$i" fi done Print_Line "All done." #--