#!/bin/csh -f #H# This program transcodes various sound formats into the 3 formats that I use #H# for different purposes. It can make mp3 or ogg files at 3 different quality #H# levels each and it can make flac files. #H# The script also does peak normilization on files before encoding them. #H# #H# Syntax (order of params matters): #H# % tcode [-k] #H# is the format to encode to. Choices are: flac, mp3, ogg, m4a, mpc, or spx #H# is the encoding quality. Choices are: high, medium, or low #H# Synonyms are: music, tv, or talk #H# is the existing audio file to be transcoded #H# if "all" is used in place of a filename all files in the current directory #H# with the following extensions will be transcoded: #H# wav, dts, ac3, mpa, mp2, mpc (in that order) #H# This option probably shouldn't be used with -k #H# -k is an optional parameter to tell the script to keep both the original #H# file and the unencoded .wav file #H# #H# example: #H# % tcode ogg tv file.ac3 #H# This will turn file.ac3 into file.ogg at medium quality with no leftovers. #H# #H# Note that transcoding flac>flac will simply normalize and ensure max compression. #H# However, the script will not allow an ogg>ogg transcode. #H# # print usage info if needed if ("$1" == "-h" || "$1" == "--help" || "$1" == "help" || "$1" == "") exec sed -n -e '/^\#H\#/s/^....//p' $0 # set defaults and failsafes set NewFormat="error" set Quality="error" set Keep="N" # interpret cli params set NewFormatParam="$1" set QualityParam="$2" set OldFileName="$3" if ("$4" == "-k") set Keep="Y" # allow for the "all" case. Just run self for each file that needs encoding. if ("$OldFileName" == "all") then #foreach File (*.wav *.dts *.ac3 *.mpa *.mp2 *.mpc) # time $0 $1 $2 "$File" $4 $5 #end setenv TERM "vt100" parallel --will-cite --eta -j+0 $0 $1 $2 {} $4 $5 ::: *.wav *.dts *.ac3 *.mpa *.mp2 *.mpc exit endif # figure out what format we are starting with set OldFormat=`echo "$OldFileName" | awk -F. '{print $NF}'` # handle the quality synonyms if ($QualityParam == "high" || $QualityParam == "music") set Quality="high" if ($QualityParam == "medium" || $QualityParam == "tv") set Quality="medium" if ($QualityParam == "low" || $QualityParam == "talk") set Quality="low" # determine which encoder to use and what cli params based to the tcode params if ($NewFormatParam == "flac") then set NewFormat="flac" set Quality="high" set EncoderParams="-8" endif if ($NewFormatParam == "mp3") then set NewFormat="mp3" if ($Quality == "high") set EncoderParams="--preset standard -V1 -q 1 -b 32 -B 320" if ($Quality == "medium") set EncoderParams="--preset medium -q 1 -b 32 -B 320" if ($Quality == "low") set EncoderParams="--preset medium -Y -q 1 -b 32 -B 192" endif if ($NewFormatParam == "ac3") then set NewFormat="ac3" if ($OldFormat != "dts") then if ($OldFormat != "aac") then if ($OldFormat != "flac") then if ($OldFormat != "wav") then exec echo "ERROR: AC3 files must start out as DTS, AAC, or FLAC files." endif endif endif endif if ($Quality == "high") set EncoderParams="-b:a 640k" if ($Quality == "medium") set EncoderParams="-b:a 448k" if ($Quality == "low") set EncoderParams="-b:a 192k" set FN=`basename "$OldFileName" .${OldFormat}` ffmpeg -i "$OldFileName" $EncoderParams "${FN}.ac3" || exec echo "Error transcoding with ffmpeg." if ($Keep == "N") rm -v "$OldFileName" exit endif if ($NewFormatParam == "m4a") then set NewFormat="m4a" if ($Quality == "high") set EncoderParams="-q 150" if ($Quality == "medium") set EncoderParams="-q 100" if ($Quality == "low") set EncoderParams="-q 32" endif if ($NewFormatParam == "aac") then set NewFormat="aac" if ($Quality == "high") set EncoderParams="-q 150" if ($Quality == "medium") set EncoderParams="-q 100" if ($Quality == "low") set EncoderParams="-q 32" endif if ($NewFormatParam == "spx") then set NewFormat="spx" if ($Quality == "high") set EncoderParams="--vbr --quality 8" if ($Quality == "medium") set EncoderParams="--vbr --quality 5" if ($Quality == "low") set EncoderParams="--vbr --quality 3" endif if ($NewFormatParam == "opus") then set NewFormat="opus" if ($Quality == "high") set EncoderParams="--vbr --bitrate 128" if ($Quality == "medium") set EncoderParams="--vbr --bitrate 70" if ($Quality == "low") set EncoderParams="--vbr --bitrate 50" endif if ($NewFormatParam == "mpc") then set NewFormat="mpc" if ($Quality == "high") set EncoderParams="--standard" if ($Quality == "medium") set EncoderParams="--radio" if ($Quality == "low") set EncoderParams="--thumb" endif if ($NewFormatParam == "o" || $NewFormatParam == "ogg") then set NewFormat="ogg" if ($Quality == "high") set EncoderParams="-q 6" if ($Quality == "mh") set EncoderParams="-q 5" if ($Quality == "medium") set EncoderParams="-q 4" if ($Quality == "low") set EncoderParams="-q 3" endif if ($NewFormatParam == "wav") then set NewFormat="wav" set Quality="high" set EncoderParams="" endif # make sure the CLI params were good if ($NewFormat == "error" || $Quality == "error") exec $0 --help # Grab the file name without the extention so we can change it later. set FN=`basename "$OldFileName" .${OldFormat}` # Decode compressed audio formats into .wav files so they can be re-encoded. # Delete the original after the decode is done. set Decoded="N" switch ($OldFormat) case "wav": # don't have to decode .wav files set Decoded="Y" # make sure wav file isn't 32 bit as mplayer likes to make them... set WavBits=`mediainfo "${FN}.wav" | grep ^Bit.depth | awk '{print $(NF-1)}'` if ("$WavBits" == "32") then echo "32bit wav detected. Converting to 16bit..." ionice -c3 sox -S "${FN}.wav" -b16 "${FN}.fixed.wav" && mv -fv "${FN}.fixed.wav" "${FN}.wav" || set Decoded="N" endif breaksw case "ac3": # use a52dec to decode ac3 files to wav files a52dec -o wav "${FN}.ac3" > "${FN}.wav" && set Decoded="Y" breaksw case "dts": if ($NewFormat == "ac3") then # use dcadec to make a 6 channel wav file dcadec -o wavall "${FN}.dts" > "${FN}.wav" && sox -S "${FN}.wav" -b 16 "${FN}.16.wav" && /bin/mv -fv "${FN}.16.wav" "${FN}.wav" && set Decoded="Y" else # use dtsdec from libdts to decode dts files to stereo wav files dtsdec -o wav "${FN}.dts" > "${FN}.wav" && sox -S "${FN}.wav" -b 16 "${FN}.16.wav" && /bin/mv -fv "${FN}.16.wav" "${FN}.wav" && set Decoded="Y" endif breaksw case "mpa": # use madplay to decode mpeg audio to wav # mpg123 or mpg321 can also be used but madplay is better madplay "${FN}.mpa" -o "wave:${FN}.wav" && set Decoded="Y" breaksw case "mpc": # use mppdec from musepack-tools to decode mpc files to wav mppdec "${FN}.mpc" "${FN}.wav" && set Decoded="Y" breaksw case "ogg": if ($NewFormat == "ogg") exec echo "ERROR: File is already an ogg." # use oggdec from vorbis-tools to decode ogg to wav oggdec "${FN}.ogg" && set Decoded="Y" breaksw case "mp2": # use madplay to decode mpeg audio to wav # mpg123 or mpg321 can also be used but madplay is better madplay "${FN}.mp2" -o "wave:${FN}.wav" && set Decoded="Y" breaksw case "flac": # use flac to decode flac files to wav flac -d "${FN}.flac" && set Decoded="Y" breaksw case "aac": # use faad to decode AAC files to wav... faad "${FN}.aac" && set Decoded="Y" breaksw case "mpa": # use faad to decode MPA files to wav... faad -d -w "${FN}.mpa" > "${FN}.wav" && set Decoded="Y" breaksw case "m4a": # use faad to decode M4A files to wav... faad -d -w "${FN}.m4a" > "${FN}.wav" && set Decoded="Y" breaksw case "spx": # use speexdec to decode speex files to wav... speexdec -d -w "${FN}.spx" -o "${FN}.wav" && set Decoded="Y" breaksw case "opus": # use speexdec to decode speex files to wav... opusdec -d -w "${FN}.opus" -o "${FN}.wav" && set Decoded="Y" breaksw case "mp3": # use madplay to decode mp3 files to wav... madplay "${FN}.mp3" -o "wave:${FN}.wav" && set Decoded="Y" breaksw endsw # make sure that the file was actually decoded and blow up if not. if ($Decoded == "N") exec echo "ERROR: File was not decoded." # delete the original file unless it was specificly requested that it be kept. if ($Keep == "N") if ($OldFormat != "wav") rm -v "${FN}.$OldFormat" # Normalize the volume level of the wav file. This does not change the file name # This is the good kind of normalizing that doesn't destroy the dynamic range. # Do not normalize wav files if making an AC3 stream because it may be more than 2 channels. if ($NewFormat != "ac3") then ionice -c3 normalize --peak "${FN}.wav" || exec echo "Something went wrong in the normalizing." endif # Actually encode the wav file into an mp3 file and delete it when done. if ($NewFormat == "flac") flac $EncoderParams -o "${FN}.flac" "${FN}.wav" || exec echo "Problem encoding." if ($NewFormat == "mp3") lame $EncoderParams "${FN}.wav" "${FN}.mp3" || exec echo "Problem encoding." if ($NewFormat == "ogg") oggenc $EncoderParams -o "${FN}.ogg" "${FN}.wav" || exec echo "Problem encoding." if ($NewFormat == "m4a") faac $EncoderParams -o "${FN}.m4a" "${FN}.wav" || exec echo "Problem encoding." if ($NewFormat == "aac") faac $EncoderParams -o "${FN}.aac" "${FN}.wav" || exec echo "Problem encoding." if ($NewFormat == "mpc") mppenc $EncoderParams "${FN}.wav" "${FN}.mpc" || exec echo "Problem encoding." if ($NewFormat == "spx") speexenc $EncoderParams "${FN}.wav" "${FN}.spx" || exec echo "Problem encoding." if ($NewFormat == "opus") opusenc $EncoderParams "${FN}.wav" "${FN}.opus" || exec echo "Problem encoding." if ($NewFormat == "ac3") aften $EncoderParams "${FN}.wav" "${FN}.ac3" || exec echo "Problem encoding." if ($NewFormat == "wav") exec echo "No need to encode a wav file." # delete the .wav file unless it was specificly requested that it be kept. if ($Keep == "N") rm -v "${FN}.wav" # make all my audio files have the same ownership and permissions if ($Quality == "high" ) then chown kmk:music "${FN}.$NewFormat" >& /dev/null else #chown kmk:tv "${FN}.$NewFormat" >& /dev/null endif chmod 644 "${FN}.$NewFormat" >& /dev/null