#! /bin/sh ############################################################################# # dekagen - a frontend to rip, convert, and name MP3 / Ogg # Written by Martin Bayer # http://userpage.fu-berlin.de/~mbayer/tools/ # Portions based on ripenc-0.7 by Michael J. Parmeley #---------------------------------------------------------------------------- # This is VERSION='dekagen 1.0.2' # created Di Jun 15 18:30:49 CEST 2004 #============================================================================ # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #============================================================================ # Be sure you have already installed on your system: # 1. cdda2wav, cdparanoia, dagrab, or tosha, # 2. 8hz-mp3, bladeenc, l3enc, lame, mp3enc, or notlame, # or oggenc. # You might also wish to install: # 3. xmcd, # 4. id3ed, id3tag, id3tool, or mp3info. # See the file README for details. ############################################################################# # # Pre-set defaults: # RCDIR="${HOME}/.dekagen" # per-user configuration directory TEMPDIR=${RCDIR} # per-user temporary data directory SAVETO=${HOME} # per-user file storage directory ENCODER='oggenc' # MP3/Ogg converter tool (command name or 'none') RIPPER='cdparanoia' # CDDA ripping tool (command name or 'none') ID3TOOL='built-in' # ID3 tagging tool (command name or 'built-in' or 'none') BITRATE='128' # MP3/Ogg nominal encoding bitrate (KBits) METHOD='manual' # 'manual' or 'cddb' XMCDLIB='' # $XMCD_LIBDIR # Adapted DEVICE to a reasonabe FreeBSD default. Martin Kraft. DEVICE='/dev/acd0c' # device used for ripping NCONVENT='artist-name_of_song.mp3' SELEC='1' # MP3/Ogg naming convention WHOLE='no' # rip whole CD ('yes' or 'no') SMALL='no' # small HD ('yes' or 'no') # ############################################################################# if [ $# -ne 0 ] ; then echo "This is ${VERSION}" echo "Usage: $0" echo exit fi dialog 2>&1 | grep 'backtitle' >/dev/null && alias dialog="dialog --backtitle '${VERSION}'" ; trap forcequit INT trap forcequit TERM trap forcequit QUIT trap forcequit HUP forcequit () { # when aborting on ^c or "cancel", kill background encoding processes test -f ${TEMPDIR}/lock.encode && killbgjob cleantemp saverc echo 'Dekagen terminated on user request.' ; exit 1 } killbgjob () { rm ${TEMPDIR}/convers BCKGRNDP=$(cat ${TEMPDIR}/lock.encode 2>/dev/null) ; ps -o ppid,pid | awk '$1 == '"${BCKGRNDP}"' { print $2 }' >>${TEMPDIR}/lock.encode 2>/dev/null ; kill $(echo $(cat ${TEMPDIR}/lock.encode)) ; echo 'Background encoding processes aborted.' ; rm ${TEMPDIR}/lock.encode } cleantemp () { # remove temp data rm ${TEMPDIR}/ripname 2>/dev/null rm ${TEMPDIR}/cdnames 2>/dev/null rm ${TEMPDIR}/toc1 2>/dev/null rm ${TEMPDIR}/toc2 2>/dev/null rm ${TEMPDIR}/tracks 2>/dev/null rm ${TEMPDIR}/tmprip 2>/dev/null rm ${TEMPDIR}/tracknrs1 2>/dev/null rm ${TEMPDIR}/tracknrs2 2>/dev/null rm ${TEMPDIR}/msgs 2>/dev/null } saverc () { # save settings on disk echo SAVETO="'"${SAVETO}"'" > ${RCDIR}/dekagenrc echo RIPPER="'"${RIPPER}"'" >> ${RCDIR}/dekagenrc echo ENCODER="'"${ENCODER}"'" >> ${RCDIR}/dekagenrc echo ID3TOOL="'"${ID3TOOL}"'" >> ${RCDIR}/dekagenrc echo METHOD="'"${METHOD}"'" >> ${RCDIR}/dekagenrc echo XMCDLIB="'"${XMCDLIB}"'" >> ${RCDIR}/dekagenrc echo SELEC="'"${SELEC}"'" >> ${RCDIR}/dekagenrc echo NCONVENT="'"${NCONVENT}"'" >> ${RCDIR}/dekagenrc echo WHOLE="'"${WHOLE}"'" >> ${RCDIR}/dekagenrc echo SMALL="'"${SMALL}"'" >> ${RCDIR}/dekagenrc echo DEVICE="'"${DEVICE}"'" >> ${RCDIR}/dekagenrc echo BITRATE="'"${BITRATE}"'" >> ${RCDIR}/dekagenrc } findripper () { # don't forget to update this array when extending features for FNDRIP in ${RIPPER} cdparanoia cdda2wav dagrab tosha none do if [ "${FNDRIP}" = 'none' ] ; then RIPPER='none' elif (which ${FNDRIP} >/dev/null && test -x $(which ${FNDRIP})) then RIPPER=${FNDRIP} break fi done } findencoder () { # don't forget to update this array when extending features for FNDENC in ${ENCODER} oggenc lame bladeenc notlame mp3enc 8hz-mp3 l3enc none do if [ "${FNDENC}" = 'none' ] ; then ENCODER='none' elif (which ${FNDENC} >/dev/null && test -x $(which ${FNDENC})) then ENCODER=${FNDENC} break fi done } findid3tool () { # don't forget to update this array when extending features for FNDID3 in ${ID3TOOL} id3ed id3tag mp3info id3tool none do if [ "${FNDID3}" = 'none' ] ; then ID3TOOL='none' elif (which ${FNDID3} >/dev/null && test -x $(which ${FNDID3})) then ID3TOOL=${FNDID3} break fi done } checkoldrc () { # Make the .dekagen directory to store all the files used by dekagen if [ ! -d ${RCDIR} ] && [ -d ${HOME}/.dekagen ] ; then cp -r ${HOME}/.dekagen ${RCDIR} rm ${RCDIR}/dekagensed 2>/dev/null elif [ ! -d ${RCDIR} ] ; then mkdir -p ${RCDIR} fi } checkforsed () { # make file with sed rules echo '/^$/d' > ${RCDIR}/dekagensed echo "s/'//g" >> ${RCDIR}/dekagensed echo 's/"//g' >> ${RCDIR}/dekagensed echo 's/\*//g' >> ${RCDIR}/dekagensed echo 's/,//g' >> ${RCDIR}/dekagensed echo 's/)//g' >> ${RCDIR}/dekagensed echo 's/(//g' >> ${RCDIR}/dekagensed echo 's/\.//g' >> ${RCDIR}/dekagensed echo 's/\$//g' >> ${RCDIR}/dekagensed echo 's/&/and/g' >> ${RCDIR}/dekagensed echo 's/://g' >> ${RCDIR}/dekagensed echo 's/_*-_*/__/g' >> ${RCDIR}/dekagensed echo 's/\?//g' >> ${RCDIR}/dekagensed echo 's/^\ *//' >> ${RCDIR}/dekagensed echo 's/ /_/g' >> ${RCDIR}/dekagensed echo 's/^_*//' >> ${RCDIR}/dekagensed echo 's/_*$//' >> ${RCDIR}/dekagensed } checksaveto () { # check whether working directory already exists and is writable, fallback: $HOME if [ "${SAVETO}" != '' ] && [ ! -d ${SAVETO} ] ; then if dialog --title 'Question'\ --yesno "${SAVETO} does not exist.\nDo you wish to create it?" 19 70 ; then mkdir -p ${SAVETO} && return dialog --title 'Error'\ --msgbox "Cannot create ${SAVETO}." 19 70 ; SAVETO='' else SAVETO='' fi elif [ "${SAVETO}" != '' ] && [ ! -w ${SAVETO} ] ; then dialog --title 'Error'\ --msgbox "You have no write access to ${SAVETO}." 19 70 ; SAVETO='' fi if [ "${SAVETO}" = '' ] && [ "${OLDSAVETO}" != '' ] ; then SAVETO=${OLDSAVETO} fi if [ "${SAVETO}" = '' ] || [ ! -d ${SAVETO} ] || [ ! -w ${SAVETO} ] ; then SAVETO=${HOME} fi } checkdevice () { # check whether $DEVICE is pointing to a device, fallback: /dev/cdrom if [ ! -e ${DEVICE} ] ; then dialog --title 'Error' \ --msgbox "Device ${DEVICE} does not seem to exist." 19 70 ; DEVICE='' fi if [ "${DEVICE}" = '' ] && [ "${TEMPDEVICE}" != '' ] ; then DEVICE=${TEMPDEVICE} elif [ "${DEVICE}" = '' ] ; then DEVICE='/dev/cdrom' fi } checkripper () { # check whether $RIPPER is installed and executable if [ "${RIPPER}" != 'none' ] && ! (which ${RIPPER} >/dev/null && test -x $(which ${RIPPER})) then dialog --title 'Error' --msgbox \ "${RIPPER} is not installed or not executable." 19 70 ; CHR='' fi if [ "${CHR}" = '' ] && [ "${TEMPRIPPER}" != '' ] ; then RIPPER=${TEMPRIPPER} elif [ "${CHR}" = '' ] && [ "${RIPPER}" != 'none' ] ; then # try to find a ripper automatically findripper fi } checkencoder () { # check whether $ENCODER is installed and executable if [ "${ENCODER}" != 'none' ] && ! (which ${ENCODER} >/dev/null && test -x $(which ${ENCODER})) then dialog --title 'Error' --msgbox \ "${ENCODER} is not installed or not executable." 19 70 ; OPT='' fi if [ "${OPT}" = '' ] && [ "${TEMPENCODER}" != '' ] ; then ENCODER=${TEMPENCODER} elif [ "${OPT}" = '' ] && [ "${ENCODER}" != 'none' ] ; then # try to find an encoder automatically findencoder fi if [ "${ENCODER}" != 'l3enc' ] && [ ${BITRATE} -gt 999 ] ; then BITRATE=$(expr ${BITRATE} / 1000) elif [ "${ENCODER}" = 'l3enc' ] && [ ${BITRATE} -le 999 ] ; then BITRATE=$(expr ${BITRATE} \* 1000) fi # $ID3TOOL might need to be adjusted TEMPID3TOOL='' ID3UTIL='0' checkid3tool } checkid3tool () { # check whether $ID3TOOL is installed and executable if [ "${ENCODER}" = 'none' ] ; then ID3TOOL='none' fi if [ "${ID3TOOL}" != 'none' ] && [ "${ID3TOOL}" != 'built-in' ] && [ "${ENCODER}" = 'oggenc' ] ; then dialog --title 'Error' --msgbox \ 'ID3 tags cannot be used with oggenc, only Built-In tagging.' 19 70 ; ID3TOOL='built-in' fi if [ "${ID3TOOL}" = 'built-in' ] && ! ([ "${ENCODER}" = 'lame' ] || [ "${ENCODER}" = 'notlame' ] || [ "${ENCODER}" = 'oggenc' ]) ; then dialog --title 'Error' --msgbox \ 'The Built-In tagging function can only be used with either lame, notlame, or oggenc.' 19 70 ; ID3UTIL='' fi if [ "${ID3TOOL}" != 'built-in' ] && [ "${ID3TOOL}" != 'none' ] && ! (which ${ID3TOOL} >/dev/null && test -x $(which ${ID3TOOL})) then dialog --title 'Error' --msgbox \ "${ID3TOOL} is not installed or not executable." 19 70 ; ID3UTIL='' fi if [ "${ID3UTIL}" = '' ] && [ "${TEMPID3TOOL}" != '' ] ; then ID3TOOL=${TEMPID3TOOL} elif [ "${ID3UTIL}" = '' ] ; then if [ "${ENCODER}" = 'lame' ] || [ "${ENCODER}" = 'notlame' ] || [ "${ENCODER}" = 'oggenc' ] ; then ID3TOOL='built-in' else # try to find an ID3 tagging utility automatically findid3tool fi fi } getcddb () { # try to access CDDB... if [ "${XMCDLIB}" != '' ] ; then export XMCD_LIBDIR=${XMCDLIB} fi cda -batch -dev ${DEVICE} on cda -dev ${DEVICE} toc > ${TEMPDIR}/toc1 grep '(unknown.*title)' ${TEMPDIR}/toc1 >/dev/null && cda -batch -offline -dev ${DEVICE} toc >${TEMPDIR}/toc1 2>/dev/null ; cda -batch -dev ${DEVICE} off if ! (grep '(unknown.*title)' ${TEMPDIR}/toc1 >/dev/null) && [ -s ${TEMPDIR}/toc1 ] ; then sed -e '/Total Time/d' -e '/Disc ID/d' -e '/Accessing CDDB/d' -e '/^Genre:.*$/d' -e '/^$/d' -e 's/\.//g' -e 's/\[//g' -e 's/\]//g' ${TEMPDIR}/toc1 > ${TEMPDIR}/toc2 CHECKVARIOUS=$(sed -ne '1p' ${TEMPDIR}/toc2 | cut -d "/" -f1 | tr A-Z a-z | sed -e 's/ //g') if [ "${CHECKVARIOUS}" = 'variousartists' -o "${CHECKVARIOUS}" = 'soundtrack' -o "${CHECKVARIOUS}" = 'various' ] ; then ALBUM=$(sed -ne '1p' ${TEMPDIR}/toc2 | cut -d "/" -f2- | tr a-z A-Z) sed -e '1d' ${TEMPDIR}/toc2 | cut -d ' ' -f5- | tr A-Z a-z | sed -e 's/\//-/g' -e 's/ - /-/g' -e 's/ -- /-/g' -f ${RCDIR}/dekagensed > ${TEMPDIR}/cdnames else ARTIST=$(sed -ne '1p' ${TEMPDIR}/toc2 | cut -d "/" -f1) ALBUM=$(sed -ne '1p' ${TEMPDIR}/toc2 | cut -d "/" -f2-) sed -e '1d' ${TEMPDIR}/toc2 | cut -d ' ' -f5- | sed -e 's/\///g' -f ${RCDIR}/dekagensed > ${TEMPDIR}/cdnames fi rm ${TEMPDIR}/toc[1-2] test -s ${TEMPDIR}/cdnames || return ; if [ "${WHOLE}" = 'yes' ] ; then if [ "${ID3TOOL}" != 'none' ] ; then YEAR=$(dialog --inputbox 'Please enter the publishing year:' \ 19 70 3>&1 1>&2 2>&3) || return ; fi sed -e '=' ${TEMPDIR}/cdnames | sed -e 'N' -e 's/\n/ /g' >${TEMPDIR}/ripname confirm else newmenu fi else # ...or fall back to 'manual' method METHOD='manual' if [ "${WHOLE}" = 'yes' ] ; then WHOLE='no' manual WHOLE='yes' else manual fi METHOD='cddb' fi } newmenu () { # select songs from CDDB list test -f ${TEMPDIR}/ripname && rm ${TEMPDIR}/ripname sed -e /^$/d ${TEMPDIR}/cdnames | sed -e '=' | sed -e 'N' -e 's/\n/ /g' -e 's/$/ off/g' >${TEMPDIR}/tracks dialog --checklist 'Please select the song(s) you wish to rip/encode:' \ 19 70 12 $(cat ${TEMPDIR}/tracks) 2>${TEMPDIR}/tracknrs1 || return ; sed -e 's/\"//g' -e 's/$/\ /' ${TEMPDIR}/tracknrs1 | tr " " "\n" | sed -e '/^$/d' >${TEMPDIR}/tracknrs2 cat ${TEMPDIR}/tracknrs2 | while read SONGNRS do sed -ne "${SONGNRS}"'P' ${TEMPDIR}/tracks | sed -e 's/ off$//' >>${TEMPDIR}/ripname done rm ${TEMPDIR}/tracknrs[1-2] test -s ${TEMPDIR}/ripname || return ; if [ "${ID3TOOL}" != 'none' ] ; then YEAR=$(dialog --inputbox 'Please enter the publishing year:' \ 19 70 3>&1 1>&2 2>&3) || return ; fi confirm } manual () { # let user enter song title etc. manually test -f ${TEMPDIR}/ripname && rm ${TEMPDIR}/ripname ARTIST=$(dialog --inputbox 'Please enter the name of the artist or composer:' \ 19 70 3>&1 1>&2 2>&3) || return ; ALBUM=$(dialog --inputbox 'Please enter the title of the album:' \ 19 70 3>&1 1>&2 2>&3) || return ; if [ "${ID3TOOL}" != 'none' ] ; then YEAR=$(dialog --inputbox 'Please enter the publishing year:' \ 19 70 3>&1 1>&2 2>&3) || return ; fi SNUM='0' while [ "${SNUM}" != '' ] ; do SNUM=$(dialog --inputbox 'Please enter the track number of the song you wish to rip\n(leave it blank and hit return to continue):' \ 19 70 3>&1 1>&2 2>&3) || return ; if [ "${SNUM}" = '' ] ; then continue fi SNAME=$(dialog --inputbox "Please enter the name of the song number ${SNUM}:" \ 19 70 3>&1 1>&2 2>&3) || return ; SNAME=$(echo "${SNAME}" | sed -e 's/\//-/g' -f ${RCDIR}/dekagensed) ; echo "${SNUM} ${SNAME}" >>${TEMPDIR}/ripname done confirm } confirm () { # let user check his selection CONFMENU='' ; while [ "${CONFMENU}" != 'd' ] && [ "${CONFMENU}" != 'b' ] ; do test -s ${TEMPDIR}/ripname || return ; CONFMENU=$(dialog --menu 'You are going to start ripping/encoding NOW!' 19 70 5 \ 'd' 'Do it!' \ 'l' 'Show me what I have chosen' \ 's' 'Change selection (discard current selection)' \ 'b' 'Back to the main menu (nothing will be done)' 3>&1 1>&2 2>&3) || return ; case ${CONFMENU} in b) return ;; s) if [ "${METHOD}" = 'manual' ] ; then manual else newmenu fi ;; l) dialog --title 'These songs are going to be ripped/encoded:' \ --textbox ${TEMPDIR}/ripname 19 70 ; ;; d) rip ;; esac done } rip() { # lets do it :-) TEMPSAVETO=${SAVETO} ARTIST=$(echo "${ARTIST}" | sed -e 's/\//-/g' -f ${RCDIR}/dekagensed) ; ALBUM=$(echo "${ALBUM}" | sed -e 's/\//-/g' -f ${RCDIR}/dekagensed) ; YEAR=$(printf '%04d' ${YEAR} 2>/dev/null) ; cat ${TEMPDIR}/ripname | while read NUM TITLE do FORMATNUM=$(printf '%02d' ${NUM}) if [ "${CHECKVARIOUS}" = 'variousartists' -o "${CHECKVARIOUS}" = 'soundtrack' -o "${CHECKVARIOUS}" = 'various' ] ; then ARTIST='VARIOUS_ARTIST_CD' case ${SELEC} in 1) NAME=$(echo "${TITLE}" | tr A-Z a-z) ;; 2) NAME=$(echo "${FORMATNUM}-${TITLE}" | tr A-Z a-z) ;; 3) NAME="${TITLE}" ;; 4) NAME="${FORMATNUM}-${TITLE}" ;; *) NAME=$(echo "${TITLE}" | tr A-Z a-z) ;; esac else case ${SELEC} in 1) NAME=$(echo "${ARTIST}-${TITLE}" | tr A-Z a-z) ;; 2) NAME=$(echo "${FORMATNUM}-${ARTIST}-${TITLE}" | tr A-Z a-z) ;; 3) NAME="${ARTIST}-${TITLE}" ;; 4) NAME="${FORMATNUM}-${ARTIST}-${TITLE}" ;; 5) NAME=$(echo "${FORMATNUM}-${TITLE}" | tr A-Z a-z) mkdir -p "${SAVETO}/"$(echo "${ARTIST}--${ALBUM}" | tr A-Z a-z) SAVETO="${SAVETO}/"$(echo "${ARTIST}--${ALBUM}" | tr A-Z a-z) ;; 6) NAME=$(echo "${FORMATNUM}-${TITLE}" | tr A-Z a-z) mkdir -p "${SAVETO}/"$(echo "${ARTIST}/${ALBUM}" | tr A-Z a-z) SAVETO="${SAVETO}/"$(echo "${ARTIST}/${ALBUM}" | tr A-Z a-z) ;; 7) NAME=$(echo "${ARTIST}-${ALBUM}-${FORMATNUM}-${TITLE}" | tr A-Z a-z) ;; 8) NAME="${TITLE}" mkdir -p "${SAVETO}/${ARTIST}--${ALBUM}" SAVETO="${SAVETO}/${ARTIST}--${ALBUM}" ;; *) NAME=$(echo "${ARTIST}-${TITLE}" | tr A-Z a-z) esac fi echo echo "Now ripping the song ${TITLE} by ${ARTIST} from the album ${ALBUM}." ; echo case ${RIPPER} in cdparanoia) cdparanoia -d ${DEVICE} -w ${NUM} "${SAVETO}/${NAME}.wav" ;; cdda2wav) cdda2wav -H -Q -D ${DEVICE} -t ${NUM} "${SAVETO}/${NAME}.wav" ;; dagrab) dagrab -d ${DEVICE} -f "${SAVETO}/${NAME}.wav" ${NUM} ;; tosha) tosha -q -f wav -d ${DEVICE} -t ${NUM} -o "${SAVETO}/${NAME}.wav" ;; none) echo 'Not ripping.' ;; *) echo 'Cannot rip from CD.' ;; esac echo "${SAVETO}/${NAME}.wav*${ALBUM}*${ARTIST}*${TITLE}*${NUM}*${YEAR}" >> ${TEMPDIR}/convers ; if [ "${ENCODER}" != 'none' ] && [ "${SMALL}" = 'yes' ] ; then echo "Currently converting the song ${TITLE} by ${ARTIST} from the album ${ALBUM}." ; encodeit elif [ "${ENCODER}" != 'none' ] && [ "${SMALL}" != 'yes' ] && [ ! -f ${TEMPDIR}/lock.encode ] ; then encodeit >> ${TEMPDIR}/encode.log 2>&1 & echo $! > ${TEMPDIR}/lock.encode fi SAVETO=${TEMPSAVETO} done } encodeit () { # generate mp3 / ogg and label it with name (id3) tag AIO='0' while [ "${AIO}" != '' ] ; do AIO=$(head -n1 ${TEMPDIR}/convers) ; EIN=$(echo "${AIO}" | cut -s -d '*' -f1) ; ENEW=$(echo "${EIN}" | sed -e 's/\.wav$/\.mp3/') ; if [ "${ID3TOOL}" != 'none' ] && [ "${ENCODER}" != 'none' ] ; then ID3ALBUM=$(echo "${AIO}" | cut -s -d '*' -f2 | sed -e 's/_/ /g' -e 's/-/ /g') ; ID3ARTIST=$(echo "${AIO}" | cut -s -d '*' -f3 | sed -e 's/_/ /g' -e 's/-/ /g') ; ID3TITLE=$(echo "${AIO}" | cut -s -d '*' -f4 | sed -e 's/_/ /g' -e 's/-/ /g') ; ID3NUM=$(echo "${AIO}" | cut -s -d '*' -f5) ; ID3YEAR=$(echo "${AIO}" | cut -s -d '*' -f6) ; case ${ENCODER} in bladeenc) bladeenc -delete -quit -quiet -br "${BITRATE}" "${EIN}" >${TEMPDIR}/converstemp mv ${TEMPDIR}/converstemp ${TEMPDIR}/convers AIO=$(head -n1 ${TEMPDIR}/convers) ; done rm -f ${TEMPDIR}/lock.encode } main () { # main menu MENU='' ; while [ "${MENU}" != 'q' ] ; do if [ -f ${TEMPDIR}/lock.encode ] ; then echo 'There is currently an encoding process running in the background.' >${TEMPDIR}/msgs else echo 'There is no encoding process running in the background.' >${TEMPDIR}/msgs fi if [ -s ${TEMPDIR}/encode.log ] ; then SIZE=$(ls -sh ${TEMPDIR}/encode.log | awk '{ print $1 }') echo "Your encode log file is ${SIZE} bytes long." >>${TEMPDIR}/msgs else echo 'There is no encode log file.' >>${TEMPDIR}/msgs fi MENU=$(dialog --menu "$(cat ${TEMPDIR}/msgs)" 19 70 10 \ 's' 'Start' \ 'e' 'Show details of encoding process' \ 'v' 'Show the encode log' \ 'd' 'Delete the encode log' \ 'l' 'List the files in the working directory' \ 'p' 'Preferences' \ 'h' 'Help (show manual page)' \ 'a' 'About dekagen' \ 'q' 'Quit (safe exit)' 3>&1 1>&2 2>&3) || forcequit ; rm ${TEMPDIR}/msgs case ${MENU} in v) # view encolde log if [ -s ${TEMPDIR}/encode.log ] ; then dialog --title 'Content of your encode log:' \ --textbox ${TEMPDIR}/encode.log 19 70 ; else dialog --title 'Message' \ --msgbox 'There is no encode log file to view.' 19 70 ; fi ;; e) # show details of encoding process if [ ! -f ${TEMPDIR}/lock.encode ] ; then dialog --title 'Message' \ --msgbox 'There is no encoding process running.' 19 70 ; else echo >${TEMPDIR}/tmprip echo 'Encoder PID CPU Usage CPU Time Elapsed Time' >>${TEMPDIR}/tmprip BCKGRNDP=$(cat ${TEMPDIR}/lock.encode 2>/dev/null) ; ps -o comm,pid,pcpu,time,etime,ppid | awk '$6 == '"${BCKGRNDP}"' \ { print $1" "$2" "$3" "$4" "$5 }' >>${TEMPDIR}/tmprip 2>/dev/null ; STATUSINC=$(wc -l ${TEMPDIR}/convers | awk '{ print $1 }') ; STATUS=$(expr ${STATUSINC} - 1) ; CURRENT=$(sed -ne '1p' ${TEMPDIR}/convers | cut -s -d '*' -f1) ; echo >>${TEMPDIR}/tmprip echo 'File currently being encoded:' >>${TEMPDIR}/tmprip echo "${CURRENT}" >>${TEMPDIR}/tmprip echo >>${TEMPDIR}/tmprip case ${STATUS} in 0) echo 'There are no more songs in the queue.' >>${TEMPDIR}/tmprip ;; 1) echo 'This song still needs to be encoded:' >>${TEMPDIR}/tmprip ;; *) echo "These ${STATUS} songs still need to be encoded:" >>${TEMPDIR}/tmprip ;; esac sed -ne '2,$p' ${TEMPDIR}/convers | cut -s -d '*' -f1 >>${TEMPDIR}/tmprip ; dialog --title 'Currently running encoding processes:' \ --textbox ${TEMPDIR}/tmprip 19 70 ; rm ${TEMPDIR}/tmprip fi ;; d) # delete encode log if [ ! -f ${TEMPDIR}/encode.log ] ; then dialog --title 'Message' \ --msgbox 'There is no encode log file.' 19 70 ; elif [ -f ${TEMPDIR}/lock.encode ] ; then dialog --title 'Question'\ --yesno 'Deleting the encode log while an encoding process is running will disable writing any more information to the log file until encoding processes for all files currently in the queue and for files that are added to the queue while the current encoding is running are completed. Are you sure you want to do this?' 19 70 \ && rm -f ${TEMPDIR}/encode.log ; else rm ${TEMPDIR}/encode.log fi ;; p) # setup preferences if [ -f ${TEMPDIR}/lock.encode ] ; then dialog --title 'Message' \ --msgbox 'Preferences cannot be changed while an encoding process is running.' 19 70 ; else setup saverc fi ;; l) # list ls -lF ${SAVETO}/ >${TEMPDIR}/tmprip dialog --title "Content of ${SAVETO}:" --textbox ${TEMPDIR}/tmprip 19 70 ; rm ${TEMPDIR}/tmprip ;; s) # start if [ "${METHOD}" = 'cddb' ] ; then getcddb else manual fi ;; h) # show manual page man dekagen 2>&1 | col -bx >${TEMPDIR}/tmprip dialog --title 'dekagen manual page' --textbox ${TEMPDIR}/tmprip 19 70 ; rm ${TEMPDIR}/tmprip ;; a) # about cat >${TEMPDIR}/tmprip <<- %% Dekagen written by Martin Bayer The latest version can be found at http://userpage.fu-berlin.de/~mbayer/tools/dekagen.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. %% dialog --title "About ${VERSION}" --textbox ${TEMPDIR}/tmprip 19 70 ; rm ${TEMPDIR}/tmprip ;; q) # quit if [ -f ${TEMPDIR}/lock.encode ] ; then dialog --title 'Question'\ --yesno 'You are going to leave dekagen, but there are still encoding processes running in the background. Leave them as well? Answering Yes will cause these processes to be terminated and the encoding queue to be deleted. There is no way to resume these operations. Answering No will let these processes running in the background. It is safe to restart dekagen later to view the log file, or to add other songs to the queue. Do you wish these processes to be terminated?' 19 70 \ && (killbgjob ; cleantemp ; saverc) ; else clear cleantemp saverc fi ;; esac done } setup () { # setup options screen SETMENU='' ; while [ "${SETMENU}" != '1' ] ; do SETMENU=$(dialog --menu 'dekagen preferences' 19 70 12 \ '1' 'Save settings and return to main menu' \ '2' "Change working directory: ${SAVETO}" \ '3' "Choose ripper: ${RIPPER}" \ '4' "Choose encoder: ${ENCODER}" \ '5' "Choose ID3 tag tool: ${ID3TOOL}" \ '6' "Toggle between manual or CDDB naming: ${METHOD}" \ '7' "Set XMCD_LIBDIR variable for cda: ${XMCDLIB}" \ '8' "Set file naming convention: ${NCONVENT}" \ '9' "Rip whole CD? ${WHOLE}" \ '10' "Set small hard disk option? ${SMALL}" \ '11' "Select your CD-ROM device: ${DEVICE}" \ '12' "Set nominal bitrate for the encoded MP3/Ogg: ${BITRATE}" 3>&1 1>&2 2>&3) || return ; case ${SETMENU} in 1) # leave preferences screen saverc ;; 2) # setup working directory OLDSAVETO=${SAVETO} SAVETO=$(dialog --inputbox "Please enter the full path to the directory in which all ripping and encoding will be done (currently ${SAVETO}):" 19 70 3>&1 1>&2 2>&3 | sed -e 's/\/$//' -f ${RCDIR}/dekagensed) ; checksaveto ;; 3) # choose ripper TEMPRIPPER=${RIPPER} CHR=$(dialog --menu "Please choose your CD ripping tool\n(currently ${RIPPER}):" 19 70 6 \ '1' 'cdparanoia' \ '2' 'cdda2wav' \ '3' 'tosha' \ '4' 'dagrab' \ '5' 'none (in case wav file exists and needs only to be encoded)' \ 3>&1 1>&2 2>&3) ; case ${CHR} in 1) RIPPER='cdparanoia' ;; 2) RIPPER='cdda2wav' ;; 3) RIPPER='tosha' ;; 4) RIPPER='dagrab' ;; 5) RIPPER='none' ;; *) CHR='' ;; esac checkripper ;; 4) # choose encoder TEMPENCODER=${ENCODER} OPT=$(dialog --menu "Please choose your MP3/Ogg encoder\n(currently ${ENCODER}):" 19 70 9 \ '1' 'bladeenc' \ '2' '8hz-mp3' \ '3' 'l3enc' \ '4' 'lame' \ '5' 'notlame' \ '6' 'mp3enc' \ '7' 'oggenc' \ '8' 'none (do not start encoding automatically)' \ 3>&1 1>&2 2>&3) ; case ${OPT} in 1) ENCODER='bladeenc' ;; 2) ENCODER='8hz-mp3' ;; 3) ENCODER='l3enc' ;; 4) ENCODER='lame' ;; 5) ENCODER='notlame' ;; 6) ENCODER='mp3enc' ;; 7) ENCODER='oggenc' ;; 8) ENCODER='none' ;; *) OPT='' ;; esac checkencoder ;; 5) # choose id3 tag tool if [ "${ENCODER}" = 'none' ] ; then dialog --title 'Message' --msgbox \ 'An ID3 tagging tool can only be chosen after an encoder utility (option 4) was chosen.' 19 70 ; else TEMPID3TOOL=${ID3TOOL} ID3UTIL=$(dialog --menu "Please choose your ID3 tag tool. The Built-In option will work only if you use an encoder with a built-in ID3 engine (lame, notlame). For Ogg-Vorbis, please use either None or Built-In. (Current value: ${ID3TOOL}.)" 19 70 7 \ '1' 'id3ed' \ '2' 'id3tool' \ '3' 'id3tag' \ '4' 'mp3info' \ '5' 'built-in (use tagging capability of your encoder)' \ '6' 'none (do not name MP3 file with ID3 tag)' \ 3>&1 1>&2 2>&3) ; case ${ID3UTIL} in 1) ID3TOOL='id3ed' ;; 2) ID3TOOL='id3tool' ;; 3) ID3TOOL='id3tag' ;; 4) ID3TOOL='mp3info' ;; 5) ID3TOOL='built-in' ;; 6) ID3TOOL='none' ;; *) ID3UTIL='' ;; esac checkid3tool fi ;; 6) # toggle cddb lookup if [ "${METHOD}" = 'cddb' ] ; then METHOD='manual' WHOLE='no' else METHOD='cddb' dialog --title 'Message' --msgbox \ 'Setting this option will work only if xmcd/cda is installed and configured on your system. To use xmcd/cda, you will need either a permanent connection to the internet for access to the remote CDDB, or an already existing entry in your local CDDB for the CD you are going to rip.' 19 70 ; fi ;; 7) # set xmcd path XMCDTEMP=${XMCDLIB} XMCDLIB=$(dialog --inputbox "Please enter the complete path to your xmcd library directory\n(currently ${XMCDLIB}):" \ 19 70 3>&1 1>&2 2>&3) || XMCDLIB=${XMCDTEMP} ; if [ ! -d ${XMCDLIB} ] ; then dialog --title 'Error' --msgbox "Directory ${XMCDLIB} does not seem to exist." 19 70 ; XMCDLIB=${XMCDTEMP} fi ;; 8) # set file naming convention TEMPSELEC=${SELEC} SELEC=$(dialog --menu "Please choose your preferred file naming convention. Options 5, 6, 7, and 8 cannot be used with various artist CDs. (Current value: ${SELEC}, ${NCONVENT}.)" 19 70 9 \ '1' 'artist-name_of_song.mp3' \ '2' 'track-artist-name_of_song.mp3' \ '3' 'Artist-Name_Of_Song.mp3 (Capitalized)' \ '4' 'track-Artist-Name_Of_Song.mp3 (Capitalized)' \ '5' 'artist--album/track-name_of_song.mp3 (creates a directory)' \ '6' 'artist/album/track-name_of_song.mp3 (creates directories)' \ '7' 'artist-album-track-name_of_song.mp3' \ '8' 'Artist--Album/Name_Of_Song.mp3 (directory and Capitalized)' \ 3>&1 1>&2 2>&3) ; if [ "${SELEC}" = '' ] && [ "${TEMPSELEC}" != '' ] ; then SELEC=${TEMPSELEC} elif [ "${SELEC}" = '' ] ; then SELEC='1' fi case ${SELEC} in 1) NCONVENT='artist-name_of_song.mp3' ;; 2) NCONVENT='track-artist-name_of_song.mp3' ;; 3) NCONVENT='Artist-Name_Of_Song.mp3' ;; 4) NCONVENT='track-Artist-Name_Of_Song.mp3' ;; 5) NCONVENT='artist--album/track-name_of_song.mp3' ;; 6) NCONVENT='artist/album/track-name_of_song.mp3' ;; 7) NCONVENT='artist-album-track-name_of_song.mp3' ;; 8) NCONVENT='Artist--Album/Name_Of_Song.mp3' ;; *) NCONVENT='artist-name_of_song.mp3' SELEC='1' ;; esac ;; 9) # toggle ripping whole CD if [ "${METHOD}" = 'manual' ] && [ "${WHOLE}" = 'no' ] ; then dialog --title 'Message' \ --msgbox 'Setting this option has no effect because you are using manual naming.' 19 70 ; elif [ "${METHOD}" = 'manual' ] ; then WHOLE='no' else if [ "${WHOLE}" = 'no' ] ; then WHOLE='yes' else WHOLE='no' fi fi ;; 10) # toggle small HD option if [ "${SMALL}" = "no" ] ; then SMALL='yes' dialog --title 'Message' --msgbox \ 'Setting this option makes dekagen rip one song and then encode that song, before ripping another one. This is useful if you have only a small hard disk with not the space for a whole CD on it. This will also cause background encoding to be disabled.' 19 70 ; else SMALL='no' fi ;; 11) # set CD device TEMPDEVICE=${DEVICE} DEVICE=$(dialog --inputbox "Please enter the complete path of your CD device\n(currently ${DEVICE}):" \ 19 70 3>&1 1>&2 2>&3 | sed -e 's/\/$//' ) ; checkdevice ;; 12) # mp3 encoding bitrate TEMPBITRATE=${BITRATE} BITRATE=$(dialog --menu "Please choose your MP3/Ogg nominal encoding bitrate\n(currently ${BITRATE} KBits):" 19 70 11 \ '64' '64 KBits' \ '80' '80 KBits' \ '96' '96 KBits' \ '112' '112 KBits' \ '128' '128 KBits' \ '160' '160 KBits' \ '192' '192 KBits' \ '224' '224 KBits' \ '256' '256 KBits' \ '320' '320 KBits' \ 3>&1 1>&2 2>&3) ; if [ "${BITRATE}" = '' ] && [ "${TEMPBITRATE}" != '' ] ; then BITRATE=${TEMPBITRATE} elif [ "${BITRATE}" = '' ] ; then BITRATE='128' fi if [ "${ENCODER}" = 'l3enc' ] ; then BITRATE="${BITRATE}000" fi ;; esac done return } # finished defining functions, program follows checkoldrc checkforsed test -f ${RCDIR}/dekagenrc && . ${RCDIR}/dekagenrc checksaveto checkdevice checkripper checkencoder test -f ${RCDIR}/dekagenrc || saverc main #EOF