#!/bin/sh VERSION="0.4d" ########################################################################### # makeflac-0.4d # Jason Kaufman # 2003.08.24 # # Well so far a lot of stuff is hardcoded and can't be removed. This is is # due to the fact that this started out as a quick hack to rip 50 CDs in one # day. Nowadays, it can do much more (tagging-wise) and has better (but # far from perfect) error-checking. It does almost everything I want a # ripper to do, but it probably doesn't do everything YOU want it to do. # You have been warned. # # REQUIRES: cdda2wav, cdparanoia, flac, metaflac # # BEGIN CONFIGURABLE OPTIONS # These must be properly set or makeflac will break # CD-ROM device to rip from DEVICE="/dev/cdrom" # Options to use with flac FLAC_OPTS="-V -8 --delete-input-file --replay-gain -s" # The file in each album directory where track names are stored TRACKNAMES=".tracknames" # END CONFIGURABLE OPTIONS # Usage: cd Artist_Name/Album_Title; vim ${TRACKNAMES}; makeflac ALBUM_DATE # e.g., cd Cult,_The/Electric; vim .tracknames; makeflac --date 1987 # ELABORATION OF USAGE # #1. Artist_Name/Album_Title # # makeflac at this point assumes an underscore-delimited, non-escaped- # punctuation-containing directory structure. You must execute makeflac # from within this directory # # e.g. Cult,_The/Electric is legal. # e.g. Foobar/('My_Super-133t Mix') is probably not. # Don't cry if your illogical scheme doesn't work with makeflac # #2. vim ${TRACKNAMES} # # Place the name of each track, one to a line in this file. Do not # leave blank lines in the file. Punctuation is OK, a filter will sanitize # it when it names the flac, while retaining the original form for tagging. # NOTE: If your album has multiple discs, specify the tracks in different # ${TRACKNAMES} like ${TRACKNAMES}1 (the first disc), ${TRACKNAMES}2 # (the second disc), and so on. # #3. makeflac --date ALBUM_DATE # At this point all you need is the date of the album release. # # SUMMARY # 1. mkdir and cd to Artist_Name/Album_Title # 2. edit a ${TRACKNAMES} for each disc # 3. insert CD # 4. makeflac ALBUM_DATE # # Screwing with anything after this will probably break makeflac ############################################################################ export INFOFILE=".info" export LOGFILE=".log" rm -f ${LOGFILE} export ALBUM=`basename ${PWD} | sed -e 's/_/\\ /g'` export ARTIST=`basename \`eval "dirname ${PWD}"\` | sed -e 's/_/\\ /g'` export ESYMB="*** Error:" export MSYMB="---" ############################################################################### ############################################################################## # Args: number_of_seconds # Reqs: expr compute_time () { QTIME=${1} # Compute hours (better not take days) QHOURS=`expr ${QTIME} / 3600` Q1=`expr ${QHOURS} \* 3600` QTIME=`expr ${QTIME} - ${Q1}` # Compute minutes QMIN=`expr ${QTIME} / 60` Q1=`expr ${QMIN} \* 60` QTIME=`expr ${QTIME} - ${Q1}` # Compute seconds QSEC=${QTIME} if test ${QHOURS} -gt 0; then echo -n "${QHOURS}h" fi if test ${QMIN} -gt 0; then echo -n "${QMIN}m" fi echo -n "${QSEC}s" } ############################################################################### ############################################################################### version_info () { echo "makeflac-${VERSION}"; echo "Jason Kaufman " echo "" } ############################################################################### ############################################################################### encode_track () { trap 'exit 1;' 1 2 3 15 if test -z "${1}"; then echo "${ESYMB} Not enough options passed to encode_track" exit 1; fi COUNT=${1} if test ${COUNT} -lt 10; then TRACKNUMBER=0${COUNT} else TRACKNUMBER=${COUNT} fi TMP_LOG=".${COUNT}.log" # ISRC for this track if test -f ${INFOFILE}; then ISRC=`grep -m 1 "${COUNT} ISRC" ${INFOFILE} | cut -d: -f4 | sed -e 's/ //g' -e 's/\^M//g'` fi # Setting up some comments for encoding TITLE=`sed -n ${COUNT}p < ${TRACKNAMES}` STITLE=`echo ${TITLE} | sed -e 's/ /_/g' -e 's/_(.*//' -e 's/#//g' -e "s/'//g" -e 's/\!//g' -e 's%/%_-_%g' -e 's/\.//g' -e 's/\?//g'` DESCRIPTION=`date +%Y.%m.%d-%H%M` echo "${MSYMB} Encoding Track ${COUNT} as ${TRACKNUMBER}-${STITLE}.flac with info:" >> ${TMP_LOG} echo "ALBUM: ${ALBUM}" >> ${TMP_LOG} echo "ARTIST: ${ARTIST}" >> ${TMP_LOG} if test -n "${CDINDEX_ID}"; then echo "CDINDEX: ${CDINDEX_ID}" >> ${TMP_LOG} CDINDEX_ID_OPT="--tag=CDINDEX=${CDINDEX_ID}" fi if test -n "${CDDB_ID}"; then echo "CDDB: ${CDDB_ID}" >> ${TMP_LOG} CDDB_ID_OPT="--tag=CDDB=${CDDB_ID}" fi if test -n "${DATE}"; then echo "DATE: ${DATE}" >> ${TMP_LOG} DATE_OPT="--tag=DATE=${DATE}" fi echo "DESCRIPTION: ${DESCRIPTION}" >> ${TMP_LOG} if test -n "${ISRC}"; then echo "ISRC: ${ISRC}" >> ${TMP_LOG} ISRC_OPT="--tag=ISRC=${ISRC}" fi if test -n "${MCN}"; then echo "MCN: ${MCN}" >> ${TMP_LOG} MCN_OPT="--tag=MCN=${MCN}" fi echo "TITLE: ${TITLE}" >> ${TMP_LOG} echo "TRACKNUMBER: ${TRACKNUMBER}" >> ${TMP_LOG} if test "${FILE_EXT}" = "wav"; then if test -n "`whereis trm | cut -d: -f2 | sed -e 's/ //g'`"; then if test "`uname -a | cut -d' ' -f11`" != "ppc"; then TRM=`trm -w track${TRACKNUMBER}.cdda.wav` echo "TRM: ${TRM}" >> ${TMP_LOG} TRM_OPT="--tag=TRM=${TRM}" fi fi fi # if test -n "`whereis findalbum | cut -d: -f2 | sed -e 's/ //g'`"; then # findalbum ${ALBUM} | grep "'${ALBUM}'" -A 2 > .findalbum.log # ALBUM_ID=`grep "AlbumId" .findalbum.log | cut -d: -f2 | sed -e "s/'//g" -e 's/ //g'` # if test -n "${ALBUM_ID}"; then # echo "ALBUM_ID: ${ALBUM_ID}" >> ${TMP_LOG} # ALBUM_ID_OPT='--tag=ALBUM_ID="${ALBUM_ID}"' # fi # ARTIST_ID=`grep "ArtistId" .findalbum.log | cut -d: -f2 | sed -e "s/'//g" -e 's/ //g'` # if test -n "${ARTIST_ID}"; then # echo "ARTIST_ID: ${ARTIST_ID}" >> ${TMP_LOG} # ARTIST_ID_OPT='--tag=ARTIST_ID="${ARTIST_ID}"' # fi # fi echo "" >> ${TMP_LOG} flac ${FLAC_OPTS} --tag=ALBUM="${ALBUM}" ${ALBUM_ID_OPT} --tag=ARTIST="${ARTIST}" ${ARTIST_ID_OPT} ${CDINDEX_ID_OPT} ${CDDB_ID_OPT} ${DATE_OPT} --tag=DESCRIPTION="${DESCRIPTION}" ${ISRC_OPT} ${MCN_OPT} --tag=TITLE="${TITLE}" --tag=TRACKNUMBER="${TRACKNUMBER}" ${TRM_OPT} -o ${TRACKNUMBER}-${STITLE}.flac track${TRACKNUMBER}.cdda.${FILE_EXT} } ############################################################################### ############################################################################### clear version_info # Before we even parse arguments, make sure we have the required apps APPS_LIST="cdda2wav cdparanoia flac" for AN_APP in ${APPS_LIST}; do whereis ${AN_APP} | cut -d: -f2 | grep "${AN_APP}" 2>&1>/dev/null if test ${?} -eq 1; then echo "${ESYMB} Could not find '${AN_APP}'" MISSING_APP="yes" fi done if test -n "${MISSING_APP}"; then echo "${ESYMB} One or more programs missing ... exiting" exit 1 fi # Parse arguments while test ${#} -gt 0; do case "${1}" in --album ) ALBUM=${2}; shift; shift ;; --artist ) ARTIST=${2}; shift; shift ;; --cddb ) CDDB_ID=${2}; shift; shift ;; --cdindex ) CDINDEX_ID=${2}; shift; shift ;; --date ) DATE=${2}; shift; shift ;; --device ) DEVICE=${2}; shift; shift ;; --discs ) NUM_DISCS=${2}; shift; shift ;; -h | --help ) cat << EEOOFF makeflac-${VERSION} Jason Kaufman --album <> Specify an album name here to override the directory structure --artist <> Specify an artist name here to override the directory structure --cddb <> Specify a CDDB-ID, e.g. "c10bc80e" --cdindex <> Specify a CDINDEX, e.g. "3DS3cxoLgbTkdMA4UvTz7ArVuFc-" --date <> Release date of album, most often this is the release year --device <> CD-ROM device to use for ripping --discs <> Number of discs in the album -h --help Display this help --mcn <> Specify an MCN, e.g. "0075678356728" --skip-rip Use this if you ran makeflac to rip your disc(s), but you still need to encode them --tracks <> Specify ranges of tracks to rip or encode (use cdparanoia-style ranges) - NOTE: Make sure your .tracknames reflects the ranges you have specified, e.g. if you have a 10-track disc and use --tracks -9: then you must have ONLY 9 names in .tracknames. Use a ':' (colon) to specify track ranges for each album e.g. --tracks 2-9:-10: Means do tracks 1-9 and 11-14 on disc 1, 1-10 on disc 2, ALL tracks on disc 3. --use-smp Encode two flac files simultaneously if you have a dual-processor system -v --version Show release information EEOOFF exit 1 ;; --mcn ) MCN=${2}; shift; shift ;; --skip-rip ) SKIP_RIP="true"; shift ;; --tracks ) CDPARANOIA_OPTS="${2}"; DO_RANGE="true"; shift; shift ;; --use-smp ) export USE_SMP="true"; shift ;; -v | --version ) version_info exit 1 ;; * ) break ;; esac done # Error-check some arguments if test -n "${NUM_DISCS}"; then if test ${NUM_DISCS} -lt 1; then echo "${ESYMB} \"${NUM_DISCS}\" is an invalid number of discs" exit 0 fi else NUM_DISCS=1 fi ### Start the big loop DISCS_DONE=0 FINAL_TOTAL=0 while test ${DISCS_DONE} -lt ${NUM_DISCS}; do let DISCS_DONE+=1 RIP_TIME1=`date +%s` ### If already have all the WAVs, then we can skip all of this if test x"${SKIP_RIP}" != "xtrue"; then # We don't need a subdir if there's only one disc if test ${NUM_DISCS} -gt 1; then mkdir d${DISCS_DONE} && cd d${DISCS_DONE} cp ../${TRACKNAMES}${DISCS_DONE} ${TRACKNAMES} fi ### BEGIN Need the Audio CD Section ### echo -n "${MSYMB} cdda2wav is retrieving info ... " cdda2wav -D ${DEVICE} -g -J -N -v catalog,trackid,sectors 2>${INFOFILE} echo "done" fi ### END of Need the Audio CD section ### ### BEGIN ${INFOFILE}-specific code ### if test -f ${INFOFILE}; then # MCN detection if test -z "${MCN}"; then MCN=`grep -m 1 "catalog number" ${INFOFILE} | cut -d: -f2 | sed -e 's/ //g'` if ! test `echo ${MCN} | grep -e [0-9]`; then MCN= fi fi # CDDB detection if test -z "${CDDB_ID}"; then CDDB_ID=`grep -m 1 "CDDB" ${INFOFILE} | cut -d: -f2 | sed -e 's/ //g' -e 's/0x//'` fi # CDINDEX detection if test -z "${CDINDEX_ID}"; then CDINDEX_ID=`grep -m 1 "CDINDEX" ${INFOFILE} | cut -d: -f2 | sed -e 's/ //g'` fi # LEADOUT LEADOUT=`grep -m 1 "Leadout" ${INFOFILE} | cut -d: -f2 | sed -e 's/ //g'` fi ### END ${INFOFILE}-specific code ### if test -f ${TRACKNAMES}; then NUM_TRACKS=`cat ${TRACKNAMES} | wc -l` else echo "${ESYMB} ${TRACKNAMES} containing tracknames does not exist"; exit 1; fi # Making WAVs if test -z ${SKIP_RIP}; then if test -n ${DO_RANGE}; then THESE_OPTS="-- `echo ${CDPARANOIA_OPTS} | cut -d':' -f${DISCS_DONE}`" fi echo "${MSYMB} Ripping Disc ${DISCS_DONE} of ${NUM_DISCS}" cdparanoia -d ${DEVICE} -z -B ${THESE_OPTS} unset THESE_OPTS fi # Moving tracks if necessary if test -n "${DO_RANGE}"; then if test -z "${SKIP_RIP}"; then TMP_COUNT=1 for A_FILE in `ls *.wav`; do if test ${TMP_COUNT} -lt 10; then mv ${A_FILE} track0${TMP_COUNT}.cdda.wav else mv ${A_FILE} track${TMP_COUNT}.cdda.wav fi let TMP_COUNT+=1 done fi fi unset TMP_COUNT # Removing stupid silent track (if any) rm -f track00* # Detect what kind of lossless files we're compressing if test -n "${SKIP_RIP}"; then FILE_LIST=`ls *.wav` FILE_EXT="wav" if test -z "${FILE_LIST}"; then FILE_LIST=`ls *.aiff` FILE_EXT='aiff' if test -z "${FILE_LIST}"; then echo "${ESYMB} Could not find any WAVs or AIFFs to encode" exit 1 fi fi else FILE_EXT="wav" fi RIP_TIME2=`date +%s` RIP_TIME=`expr ${RIP_TIME2} - ${RIP_TIME1}` let FINAL_TOTAL+=${RIP_TIME} COUNT=1 while test ${COUNT} -le ${NUM_TRACKS}; do DATE1=`date +%s` if test -n "${USE_SMP}"; then if test ${COUNT} -eq ${NUM_TRACKS}; then echo -n "${MSYMB} Encoding Track ${COUNT} ... " encode_track ${COUNT} echo -n "done" printf "\t" else echo -n "${MSYMB} Encoding Tracks ${COUNT} and " encode_track ${COUNT} & let COUNT+=1 echo -n "${COUNT} ... " # sleep 1 encode_track ${COUNT} echo -n "done" fi else echo -n "${MSYMB} Encoding Track ${COUNT} ... " encode_track ${COUNT} echo -n "done" printf "\t" fi DATE2=`date +%s` TMP_TOTAL=`expr ${DATE2} - ${DATE1}` printf "\t[" compute_time ${TMP_TOTAL} let FINAL_TOTAL+=${TMP_TOTAL} echo "]" let COUNT+=1 done if test ${NUM_DISCS} -gt 1; then if test ${DISCS_DONE} -lt ${NUM_DISCS}; then cd ../ echo "${MSYMB} Done with Disk ${DISCS_DONE}, insert the next disk" echo "${MSYMB} and press any key to continue" read JUNK && unset ${JUNK} fi fi done NEW_COUNT=1 while test ${NEW_COUNT} -le ${NUM_TRACKS}; do cat .${NEW_COUNT}.log >> ${LOGFILE} rm .${NEW_COUNT}.log let NEW_COUNT+=1 done echo -n "${MSYMB} Total Elapsed Time: " printf "\t\t[" echo "`compute_time ${FINAL_TOTAL}`]" unset INFOFILE ARTIST ALBUM ESYMB MSYMB