#!/bin/bash setupDestination() { cat <<-EODesc Format: vorbis, opus or mp3. Other formats may appear in the future. EODesc comeagain() { read \ -e \ ${destinationformat["$destination"]+-i"${destinationformat["$destination"]}"}\ -p 'Format: ' \ value case "$value" in 'mp3') destinationformat["$destination"]=mp3 lameneeded=1 ;; 'opus') destinationformat["$destination"]=opus opusencneeded=1 ;; 'vorbis'|'ogg') destinationformat["$destination"]=vorbis oggencneeded=1 ;; *) echo "Unsupported destination format: $value" >&2 comeagain ;; esac } comeagain cat <<-EODesc Path (path): Where to store transcoded files (will be created if it does not exist). EODesc read \ -e \ -p'Path: ' \ ${destinationpath["$destination"]+-i"${destinationpath["$destination"]}"}\ destinationpath["$destination"] case ${destinationformat["$destination"]} in vorbis) cat <<-EODesc Quality (integer): The quality parameter of oggenc. See man oggenc for more info. EODesc expr='^[0-9]*$' comeagain() { read \ -p'Quality: ' \ -e \ -i \ ${destinationquality["$destination"]:-3}\ value if ! [[ $value =~ $expr ]] then echo "Invalid quality value: $value" >&2 comeagain fi } comeagain if [ -n "${destinationquality["$destination"]}" ] \ && (( value != ${destinationquality["$destination"]} )) then setupRegen quality fi destinationquality["$destination"]=$value ;; opus) cat <<-EODesc Bitrate (kbps, integer): Set (VBR) bitrate to . Note that while Opus allows for decimal values, AtOM does not. The reason for this is simple: we do numeric comparisons, and Bash only manipulates integers. EODesc expr='^[0-9]*$' comeagain() { read \ -e \ -i \ ${destinationquality["$destination"]:-128}\ -p 'Bitrate: ' \ value if ! [[ $value =~ $expr ]] then echo "Invalid bitrate value: $value" >&2 comeagain fi } comeagain if [ -n "${destinationquality["$destination"]}" ] \ && (( value != ${destinationquality["$destination"]} )) then setupRegen bitrate fi destinationquality["$destination"]=$value cat <<-EODesc Loss (percent, integer): If you intend to stream the resulting files over an unreliable protocol, you may want to make use of Opus' Forward Error Correction algorythm. See the Opus-codec.org website for details. EODesc comeagain() { read \ -e \ -i \ ${destinationloss["$destination"]:-0}\ -p 'Loss: ' \ value if ! [[ $value =~ $expr ]] then echo "Invalid loss value: $value" >&2 comeagain fi } comeagain if [ -n "${destinationloss["$destination"]}" ] \ && (( value != ${destinationloss["$destination"]} )) then setupRegen loss fi destinationloss["$destination"]=$value ;; mp3) cat <<-EODesc Bitrate (kbps, integer): Set (ABR) bitrate to . EODesc expr='^[0-9]*$' comeagain() { read \ -e \ -i \ ${destinationquality["$destination"]:-128}\ -p 'Bitrate: ' \ value if ! [[ $value =~ $expr ]] then echo "Invalid bitrate value: $value" >&2 comeagain fi } comeagain if [ -n "${destinationquality["$destination"]}" ] \ && (( value != ${destinationquality["$destination"]} )) then setupRegen bitrate fi destinationquality["$destination"]=$value cat <<-EODesc Prevent resampling (boolean): LAME may decide to encode your file to a lower sampling-rate if you use a low bitrate. Setting this to yes will append --resample , preventing any resampling from happening. EODesc case ${destinationnoresample["$destination"]} in 0) initialvalue=n ;; 1) initialvalue=y ;; *) unset initialvalue ;; esac comeagain() { read \ -e \ ${initialvalue+-i $initialvalue}\ -p'Prevent resampling (y/N): ' \ value case $value in [yY]) [[ $initialvalue == n ]]\ && setupRegen noresample destinationnoresample["$destination"]=1 ;; ''|[nN]) [[ $initialvalue == y ]]\ && setupRegen noresample destinationnoresample["$destination"]=0 ;; *) comeagain ;; esac } comeagain ;; esac cat <<-EODesc [Optional parameters] Now you will have the opportunity to configure "advanced" parameters for $destination. You may leave any of these fields blank. EODesc cat <<-EODesc Normalize (boolean): Normalize output files. EODesc case ${destinationnormalize["$destination"]} in 0) initialvalue=n ;; 1) initialvalue=y ;; *) unset initialvalue ;; esac comeagain() { read \ -e \ ${initialvalue+-i $initialvalue}\ -p'Normalize (y/N): ' \ value case $value in [yY]) [[ $initialvalue == n ]] \ && setupRegen normalize destinationnormalize["$destination"]=1 ;; ''|[nN]) [[ $initialvalue == y ]] \ && setupRegen normalize destinationnormalize["$destination"]=0 ;; *) comeagain ;; esac } comeagain cat <<-EODesc Rename (string): Destination files will be named according to , after expansion of special strings: %{album}, %{albumartist}, %{artist}, %{disc}, %{genre}, %{title}, %{track}, %{year}. Untagged files or files in unrecognized formats will not be changed. Leave blank if you don't want file renaming. EODesc initialvalue="${destinationrenamepath["$destination"]}" initialvalue+=/ [[ $initialvalue == / ]] && unset initialvalue initialvalue+="${destinationrename["$destination"]}" [ -z "$initialvalue" ] && unset initialvalue read \ -e \ ${initialvalue+-i"$initialvalue"} \ -p'Rename pattern: ' \ value if [[ $value =~ / ]] then destinationrenamepath["$destination"]="${value%/*}" fi destinationrename["$destination"]="${value##*/}" cat <<-EODesc FAT32 Compatibility (boolean): Rename files for compatibility with FAT32 filesystems. EODesc case ${destinationfat32compat["$destination"]} in 0) initialvalue=n ;; 1) initialvalue=y ;; *) unset initialvalue ;; esac comeagain() { read \ -e \ ${initialvalue+-i $initialvalue}\ -p'FAT32 Compatibility (y/N): ' \ value case $value in [yY]) destinationfat32compat["$destination"]=1 ;; ''|[nN]) destinationfat32compat["$destination"]=0 ;; *) comeagain ;; esac } comeagain cat <<-EODesc Skip mime-type (mime-type, string): Files with mime-type will not be included in that destination. The '*' character is a wildcard. This prompt will loop until an empty string is encountered. EODesc while [[ ${destinationskipmime["$destination"]} =~ \| ]] do skippedmimes+=("${destinationskipmime["$destination"]%%|*}") destinationskipmime["$destination"]="${destinationskipmime["$destination"]#*|}" done [ -n "${destinationskipmime["$destination"]}" ] \ && skippedmimes+=("${destinationskipmime["$destination"]}") count=${#skippedmimes[@]} unset destinationskipmime["$destination"] for (( i=0 ; 1 ; i++ )) do read \ -e \ ${skippedmimes[i]+-i"${skippedmimes[i]}"} \ -p 'Skip mime-type: ' \ value if [ -n "$value" ] then destinationskipmime[$destination]="${destinationskipmime[$destination]:+${destinationskipmime[$destination]}|}$value" elif (( i < count )) then continue else break fi done unset skippedmimes cat <<-EODesc Copy mime-type (mime-type, string): Files with mime-type will be copied as-is to the destination. E.g. image/* will copy covers and other images to the destination. The '*' character is a wildcard. This prompt will loop until an empty string is encountered. EODesc while [[ ${destinationcopymime["$destination"]} =~ \| ]] do copiedmimes+=("${destinationcopymime["$destination"]%%|*}") destinationcopymime["$destination"]="${destinationcopymime["$destination"]#*|}" done [ -n "${destinationcopymime["$destination"]}" ] \ && copiedmimes+=("${destinationcopymime["$destination"]}") count=${#copiedmimes[@]} unset destinationcopymime["$destination"] for (( i=0 ; 1 ; i++ )) do read \ -e \ ${copiedmimes[i]+-i"${copiedmimes[i]}"} \ -p 'Copy mime-type: ' \ value if [ -n "$value" ] then destinationcopymime[$destination]="${destinationcopymime[$destination]:+${destinationcopymime[$destination]}|}$value" elif (( i < count )) then continue else break fi done unset copiedmimes cat <<-EODesc Channels (integer): Produced files should have this many channels, no more, no less. EODesc expr='^[0-9]*$' comeagain() { read \ -e \ ${destinationchannels["$destination"]+-i${destinationchannels["$destination"]}}\ -p'Channel count: ' \ value if ! [[ $value =~ $expr ]] then echo "Invalid channel count: $value" >&2 comeagain fi } comeagain if [ -n "${destinationchannels["$destination"]}" ] \ && (( value != ${destinationchannels["$destination"]} )) then setupRegen channels fi destinationchannels["$destination"]=$value cat <<-EODesc Sampling rate (Hertz, integer): Files will be resampled as needed to the specified sampling-rate. Shoutcast/Icecast streams require a constant sampling-rate. Telephony systems often require a sampling-rate of 8000Hz. EODesc if [[ ${destinationformat["$destination"]} == opus ]] then cat <<-EODesc Please note that Opus supports only the following sample-rates: 8000, 12000, 16000, 24000, and 48000 Hz. So don't set resampling on an Opus destination to any other value or files will be resampled twice. EODesc fi comeagain() { read \ -e \ ${destinationfrequency["$destination"]+-i${destinationfrequency["$destination"]}}\ -p'Sampling-rate: ' \ value if ! [[ $value =~ $expr ]] then echo "Invalid frequency value: $value" >&2 comeagain fi unset expr } comeagain if [ -n "${destinationfrequency["$destination"]}" ] \ && (( value != ${destinationfrequency["$destination"]} )) then setupRegen frequency fi destinationfrequency["$destination"]=$value cat <<-EODesc Higher-Than (bitrate, integer): Only reencode files with bitrates higher then kbps. This only applies if sample-rate, channel count and of course format are equal. If unset, only files with bitrates equal to that of the target will be copied (actually, hardlinking will be attempted first). As Ogg Vorbis target quality is not defined by its bitrate, Ogg Vorbis files will always be reencoded if unset. EODesc comeagain() { read \ -e \ ${destinationmaxbps["$destination"]+-i${destinationmaxbps["$destination"]}}\ -p'Higher-Than: ' \ value if ! [[ $value =~ $expr ]] then echo "Invalid higher-than bitrate value: $value" >&2 comeagain fi } comeagain if [ -n "${destinationmaxbps["$destination"]}" ] \ && (( value != ${destinationmaxbps["$destination"]} )) then setupRegen maxbps fi destinationmaxbps[$destination]="$value" unset regen }