Simple audio CD burning on the command-line.

Filed under linux

Normally I despise all optical media for various reasons, but recently a family member of mine asked me to make them a few audio CDs.   I didn’t like this idea too much, but I’m sure they wouldn’t grasp exactly why optical media is bad and they didn’t have the necessary simple hardware to replace it.  In the long run my sanity would hold over a bit longer if I just went ahead and burned the CDs.

Oh my god, burning a CD takes a long damn time not including the time it takes to find the MP3s and a decent audio cd burning app.  As my only windows machine, my laptop chugged away on the first disc as I stared at the progress bar in utter awe.  Then I had an idea.

There’s got to be a better way.  Hell, I have two other linux machines sitting here, with burners!  So I broke down and wrote a simple bash script that converts a dir of MP3s to WAVs, burns the CD, ejects it, and then removes the WAVs.  I even had it store the WAVs in RAM if there was enough room.

Below is the script in all it’s simplistic glory.  I’m sure it has a flaw or two, but I’ll fix it and update it here. :)

#!/bin/bash
log="$0.log"
lame=$(which lame)
wodim=$(which wodim)

if [ ! -x $lame ]; then
  echo "-->  lame not found."
  exit
fi
if [ ! -x $wodim ]; then
  echo "-->  wodim not found."
  exit
fi
if [ $(df | grep shm | tr -s [:blank:] | cut -d" " -f4) -ge 800000 ]; then
  path="/dev/shm/tmpwav"
else
  path="wav"
fi

# spinner stuff
spinner(){
  PROC=$1
  while [ -d /proc/$PROC ];do
    echo -[/]' ; sleep 0.05
    echo -[-]' ; sleep 0.05
    echo -[\]' ; sleep 0.05
    echo -[|]' ; sleep 0.05
  done
  echo -   "
  return 0
}

# width:

STAT_COL=80
if [ ! -t 1 ]; then
  USECOLOR=""

# stty will fail when stdin isn't a terminal
elif [ -t 0 ]; then
  STAT_COL="$(/bin/stty size)"
  # stty gives "rows cols"; strip the rows number, we just want columns
  STAT_COL="${STAT_COL##* }"

else
  # is /usr/share/terminfo already mounted, and TERM recognized?
  /bin/tput cols &>/dev/null
  if [ $? -eq 0 ]; then
    STAT_COL=$(/bin/tput cols)
  fi
fi
if [ "0$STAT_COL" -eq 0 ]; then
  # if output was 0 (serial console), set default width to 80
  STAT_COL=80
  USECOLOR=""
fi

# we use 13 characters for our own stuff
STAT_COL=$(($STAT_COL - 13))

# disable colors on broken terminals
TERM_COLORS="$(/bin/tput colors 2>/dev/null)"
if [ $? = 3 ]; then
	TERM_COLORS=8
elif [ -n "${TERM_COLORS}" ]; then
	case "${TERM_COLORS}" in
		*[!0-9]*)
			USECOLOR=""
			;;
		*)
			[ "${TERM_COLORS}" -lt 8 ] && USECOLOR=""
			;;
	esac
else
	USECOLOR=""
fi
unset TERM_COLORS

# clear the TZ envvar, so daemons always respect /etc/localtime
unset TZ

# colors:
if [ "$USECOLOR" = "YES" -o "$USECOLOR" = "yes" ]; then
	C_MAIN="\033[1;37;40m"      # main text
	C_OTHER="\033[1;34;40m"     # prefix & brackets
	C_SEPARATOR="\033[1;30;40m" # separator

	C_BUSY="\033[0;36;40m"      # busy
	C_FAIL="\033[1;31;40m"      # failed
	C_DONE="\033[1;37;40m"      # completed
	C_BKGD="\033[1;35;40m"      # backgrounded

	C_H1="\033[1;37;40m"        # highlight text 1
	C_H2="\033[1;36;40m"        # highlight text 2

	C_CLEAR="\033[1;0m"
fi

if [ -t 1 ]; then
	SAVE_POSITION="\033[s"
	RESTORE_POSITION="\033[u"
	DEL_TEXT="\033[$(($STAT_COL+4))G"
else
	SAVE_POSITION=""
	RESTORE_POSITION=""
	DEL_TEXT=""
fi

# status
pdone(){
  printf "${DEL_TEXT}"
  printf "   ${C_OTHER}[${C_DONE}DONE${C_OTHER}]${C_CLEAR} \n"
}

# do it
echo -n "Creating temporary directory ...    "
mkdir $path
pdone
echo "Convering MP3s to WAVs ...     "
lamecounter=1
for file in *.mp3 ; do
  echo -n "--> Converting track ${lamecounter} to WAV ...     "
  $lame --decode "$file" $path"/$file.wav" > $log 2>&1 &
  spinner $!
  pdone
  let "lamecounter++"
done

if (shopt -s nullglob dotglob; f=($path/*.wav); ((! ${#f[@]}))); then
  echo -e "For some reason we don't have WAVs to burn.\nCheck the log and try again.\Halting."
  exit
fi

echo -n "Burning audio disc ...     "
$wodim -v -pad speed=1 dev=/dev/cdrw -dao -swab $path/*.wav > $log 2>&1 &
spinner $!
pdone
if [ -x $(which eject) ]; then
  echo -n "Ejecting the disc ...     "
  eject
  pdone
fi
echo -n "Deleting temp dir and WAVs ...     "
rm $path/*
rmdir $path
pdone
echo -e "\nEnjoy your CD.  :) \n"

Note: I’m still trying to figure out a way to have the script detect if the current disc is audio, data, or blank.  Any tips?

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*