#!/bin/bash # === some global setting & configurations for the script === umask 000 # create files with all right for anyone shopt -s nullglob # expand patterns which match no file to a null string shopt -s extdebug # -------------------------------------------------------------- # das Verzeichnis in dem dieses script liegt herausfinden scriptDir=${0%/*} scriptDir="${scriptDir/#\./${PWD}}" case "${scriptDir}" in /*);; *) scriptDir="${PWD}/${scriptDir}";; esac # -------------------------------------------------------------- # include helpers . ${scriptDir}/shellUtils.sh # -------------------------------------------------------------- # string definitions enhUsage=$"usage: $0 [-t(m|f|o|w)] [-p path] [-e encoder] [-c cddbitem] [-h] [-I interface] [-D device] [-v[v|0]] [-q] [--help] [--encoding=(m|f|o|w)] [--encoder=(lame|bladeenc)] [--path=] [--interface=(cooked_ioctl|generic_scsi)] [--device=] options: -h | --help: gives this help -v: set verbosity level. -v0 disable all output -v be more verbose -vv enables debug -q: make the script silent. Equivalent to -v0 -t | --encoding: you can specify either m for encoding to mp3 using lame, or f for making lossless encoding using flac, or o for making ogg/vorbis, or w for uncompressed wav. Omitting this results in encoding to flac. mp3s will be placed under a subfolder mp3 and flacs under a subfolder flac -p | --path: specifies the path to save the encoded data. Defaults to the users home directory. -e | --encoder: specifies the mp3 encoder to use. valid encoders are actually: lame,bladeenc Defaults to lame. -c: specifies the CDDB-Entry to use. sometimes there is more than 1 entry for a cd in cddb. Then you can specify wich one to use by this option. You can checkout all entries using cddb.pl. -I | --interface: specifies cdda2wav interface to use. Valid interfaces are generic_scsi and cooked_ioctl. Please note that cooked_ioctl is not available on all systems. Defaults to cooked_ioctl if device begins with /dev else to generic_scsi -D | --device: specifies device to use with cdda2wav. All values that are valid for cdda2wav are valid here. Defaults to /dev/cdrom This script uses cdda2wav, cddb and various encoders to rip an audio CD." usage=$"usage: $0 [-t(m|f|o|w)] [-p path] [-e encoder] [-c cddbitem] [-h] [-I interface] [-D device] [-v[v|0]] [-q] options: -h: this help -v: set verbosity level. -v0 disable all output -v be more verbose -vv enables debug -q: make the script silent. Equivalent to -v0 -t: you can specify either m for encoding to mp3 using lame, or f for making lossless encoding using flac, or o for making ogg/vorbis, or w for uncompressed wav. Omitting this results in encoding to flac. mp3s will be placed under a subfolder mp3 and flacs under a subfolder flac -p: specifies the path to save the encoded data. Defaults to the users home directory. -e: specifies the mp3 encoder to use. valid encoders are actually: lame,bladeenc Defaults to lame. -c: specifies the CDDB-Entry to use. sometimes there is more than 1 entry for a cd in cddb. Then you can specify wich one to use by this option. You can checkout all entries using cddb.pl. -I: specifies cdda2wav interface to use. Valid interfaces are generic_scsi and cooked_ioctl. Please note that cooked_ioctl is not available on all systems. Defaults to cooked_ioctl if device begins with /dev else to generic_scsi -D: specifies device to use with cdda2wav. All values that are valid for cdda2wav are valid here. Defaults to /dev/cdrom This script uses cdda2wav, cddb and various encoders to rip an audio CD." ready=$"done" # level 1 messages getCDInfoMsg=$"getting cd info..." outputDirMsg=$"output to: \$encodingDir" createXmlMsg=$"create xml file..." startRipMsg1=$"start ripping cd audio data..." # level 2 messages encodeMp3Msg=$"Encode to mp3" encodeFlacMsg=$"Encode to flac" encodeOggMsg=$"Encode to ogg" encodeWavMsg=$"Encode to wav" startRipMsg2=$"start ripping cd audio data:" cdInfoMsg=$"DISK: ===== Tracks: \$dTracks Length: \$dLength Index: \$dIndex Artist: \$dArtist Title: \$dTitle Year: \$dYear Genre: \$dGenre CDDB: \$cddbId Text: \$dText Extra: \$dExtra TRACKS: =======" # -------------------------------------------------------------- # -------------------------------------------------------------- # Optionen auswerten (im Moment nur angabe einer alternativen # Konfigurationsdatei, und vebose). Vorher default-werte setzen. # Irgendwie hab ich noch Probleme mit -? das scheint nicht zu funzen. $GETOPT -T >/dev/null 2>&1 if [ $? -eq 4 ] then # enhanced getopt usage="${enhUsage}" TEMP="`$GETOPT -o "?hv::qt:p:e:c:I:D:" -l "help,encoding:,encoder:,path:,interface:,device:" -- "$@"`" else # old getopt TEMP="`$GETOPT "?hv::qt:p:e:c:I:D:" "$@"`" fi test $? -ne 0 && { echo -e "${usage}"; exit 1; } # on error eval set -- "$TEMP" # set $1,$2,... taOrder="t" encodingDir=$HOME encodingType="f" encoder="lame" cddbEntry=1 cddaIf="" cddaDev="/dev/cdrom" verbose=1 while true do case "$1" in --) shift; break;; -v) # v has an optional argument. As we are in quoted mode, # an empty parameter will be generated if its optional # argument is not found. if [ -z "$2" ] then verbose=2 else case "$2" in v) verbose=3; shift 2;; *) verbose="$2"; shift 2;; esac fi shift 2 ;; -q) verbose=0 shift ;; -t|--encoding) if [ "$2" != "m" -a "$2" != "f" -a \ "$2" != "o" -a "$2" != "w" ] then echo -e "$usage" exit 1 fi encodingType=$2 shift 2 ;; -p|--path) if [ ! \( -d $2 \) ] then echo -e "$usage" exit 1 fi encodingDir=$2 shift 2 ;; -e|--encoder) if [ -z $2 ] then echo -e "$usage" exit 1 fi encoder=$2 shift 2 ;; -c) if [ $2 -lt 1 ] then echo -e "$usage" exit 1 fi cddbEntry=$2 shift 2 ;; -I) if [ "$2" != "generic_scsi" -a \ "$2" != "cooked_ioctl" ] then echo -e "$usage" exit 1 fi cddaIf=$2 shift 2 ;; -D) if [ $2 -lt 1 ] then echo -e "$usage" exit 1 fi cddaDev=$2 shift 2 ;; -h|--help|*) echo "${usage}" exit 1 ;; esac done # -------------------------------------------------------------- if [ -z "${cddaIf}" ] then test "${cddaDev%/*}" = "/dev" &&\ cddaIf="cooked_ioctl" ||\ cddaIf="generic_scsi" fi # ---------------------------------------------------------------- # ---------------------------------------------------------------- # set encodingDir for used encodingType case ${encodingType} in m) encodingDir="$encodingDir/mp3" test ${verbose} -ge 2 && echo ${encodeMp3Msg} ;; f) encodingDir="$encodingDir/flac" test ${verbose} -ge 2 && echo ${encodeFlacMsg} ;; o) encodingDir="$encodingDir/ogg" test ${verbose} -ge 2 && echo ${encodeOggMsg} ;; w) encodingDir="$encodingDir/wav" test ${verbose} -ge 2 && echo ${encodeWavMsg} ;; esac # ---------------------------------------------------------------- test ${verbose} -ge 1 && echo -n ${getCDInfoMsg} getCDInfo # gets all info about the CD. Look in shellUtils for more info. test ${verbose} -ge 1 && echo ${ready} if [ ${verbose} -ge 2 ] then eval "cdInfo=\"$cdInfoMsg\"" cat <<-EOF $cdInfo EOF i=0 while [ $i -lt ${#tTitle[@]} ] do echo -n "${tArtist[$i]} - ${tTitle[$i]} " echo "([${tStartSec[$i]}-${tEndSec[$i]}] ${tLength[$i]})" i=$((i+1)) done fi encodingDir="${encodingDir}/${dArtist}/${dTitle}" mkdir -p "${encodingDir}" test ${verbose} -ge 1 && eval "echo ${outputDirMsg}" # ---------------------------------------------------------------- # fill xml file with data test ${verbose} -ge 1 && echo -n "${createXmlMsg}" xmlFile="${encodingDir}/cdinfo.xml" xml_dText="`echo "${dText}" | recode utf8..h0`" xml_dExtra="`echo "${dExtra}" | recode utf8..h0`" xml_dArtist="`echo "${dArtist}" | recode utf8..h0`" xml_dTitle="`echo "${dTitle}" | recode utf8..h0`" cat >"${xmlFile}" < ${dIndex} ${cddbId} ${xml_dText} ${xml_dExtra} ${xml_dArtist} ${xml_dTitle} ${dYear} ${dGenre} ${dLength} ${dTracks} EOF i=0 while [ $i -lt ${#tTitle[@]} ] do trackNr="`printf %02d $((i+1))`" xml_tTitle="`echo ${tTitle[$i]} | recode utf8..h0`" xml_tArtist="`echo ${tArtist[$i]} | recode utf8..h0`" trackEnd=${tEndSec[$i]} trackStart=${tStartSec[$i]} trackLen=$((trackEnd-$trackStart)) cat >>"${xmlFile}" < $trackNr ${tLength[$i]} ${tStartSec[$i]} ${trackLen} $xml_tArtist $xml_tTitle EOF i=$((i+1)) done echo "" >>"${xmlFile}" test ${verbose} -ge 1 && echo "${ready}" # ---------------------------------------------------------------- # ---------------------------------------------------------------- # now do the ripping test ${verbose} -eq 1 && echo -n "${startRipMsg1}" test ${verbose} -ge 2 && echo "${startRipMsg2}" i=0 while [ $i -lt ${#tTitle[@]} ] do trackNr=$((i+1)) # now that i don't forget it again. I use tr to translate \r to \n # because sed does't recognise a line with only \r at its end as a line. # Therefor sed reads until output of cdda2wav ends and does all the # processing at once, so the percentage is not shown correctly if [ ${verbose} -ge 2 ] then outStream="/dev/stdout" else outStream="/dev/null" fi case ${encodingType} in f) outFile="`printf %02d ${trackNr}`-${tTitle[$i]}.flac" outStr="track-$trackNr => ${outFile}: " ( exec 2>&1 cdda2wav -H -D/dev/cdrom -I${cddaIf} -t${trackNr} - |\ flac -c -f \ -T artist="${tArtist[$i]}" -T album="${dTitle}" \ -T genre="${dGenre}" -T title="${tTitle[$i]}" \ -T tracknumber="${trackNr}" -T tracknum="${trackNr}" \ -T date="${dYear}" -T comment="" \ -o "${encodingDir}/${outFile}" - #2>/dev/null ) | tr '\r' '\n' |\ sed '/^ [0-9]/!d;s/^.* \([0-9]*%\).*$/\r'"${outStr}"'\1/' |\ tr -d '\n' >$outStream ;; m) outFile="`printf %02d ${trackNr}`-${tTitle[$i]}.mp3" outStr="track-$trackNr => ${outFile}: " case ${encoder} in lame) ( exec 2>&1 cdda2wav -H -D/dev/cdrom -I${cddaIf} -t${trackNr} - |\ lame -V2 \ --ta "${tArtist[$i]}" --tl "${dTitle}" \ --tg "${dGenre}" --tt "${tTitle[$i]}" \ --tn "${trackNr}" --ty "${dYear}" \ --tc "" \ - "${encodingDir}/${outFile}" 2>/dev/null ) | tr '\r' '\n' |\ sed '/^ [0-9]/!d;s/^.* \([0-9]*%\).*$/\r'"${outStr}"'\1/' |\ tr -d '\n' >$outStream ;; bladeenc) ( exec 2>&1 cdda2wav -H -D/dev/cdrom -I${cddaIf} -t${trackNr} - |\ bladeenc -progress=0 STDIN \ "${encodingDir}/${outFile}" 2>/dev/null ) | tr '\r' '\n' |\ sed '/^ [0-9]/!d;s/^.* \([0-9]*%\).*$/\r'"${outStr}"'\1/' |\ tr -d '\n' >$outStream ;; esac ;; o) outFile="`printf %02d ${trackNr}`-${tTitle[$i]}.ogg" outStr="track-$trackNr => ${outFile}: " ( exec 2>&1 cdda2wav -H -D/dev/cdrom -I${cddaIf} -t${trackNr} - |\ oggenc -a "${tArtist[$i]}" -l "${dTitle}" \ -G "${dGenre}" -t "${tTitle[$i]}" \ -N "${trackNr}" -d "${dYear}" \ -c "" \ -o "${encodingDir}/${outFile}" - 2>/dev/null ) | tr '\r' '\n' |\ sed '/^ [0-9]/!d;s/^.* \([0-9]*%\).*$/\r'"${outStr}"'\1/' |\ tr -d '\n' >$outStream ;; w) outFile="`printf %02d ${trackNr}`-${tTitle[$i]}.wav" outStr="track-$trackNr => ${outFile}: " ( exec 2>&1 cdda2wav -H -D/dev/cdrom -I${cddaIf} -t${trackNr} - >\ "${encodingDir}/${outFile}" ) | tr '\r' '\n' |\ sed '/^ [0-9]/!d;s/^.* \([0-9]*%\).*$/\r'"${outStr}"'\1/' |\ tr -d '\n' >$outStream ;; esac test ${verbose} -ge 2 && echo # do a newline after each file i=$((i+1)) done test ${verbose} -eq 1 && echo "${ready}" # ----------------------------------------------------------------