#!/bin/bash -
#===============================================================================
#
#         FILE: transcode
#
#        USAGE: ./transcode path_to_file
#
#  DESCRIPTION: Given an audio file generated for archive.org transcode it to
#               other audio formats: wav, opus, flac, mp3, ogg, spx. Having
#               done so propagate the tags from the first file to the others.
#
#      OPTIONS: ---
# REQUIREMENTS: ---
#         BUGS: ---
#        NOTES: ---
#       AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
#      VERSION: 0.0.2
#      CREATED: 2018-01-05 12:52:49
#     REVISION: 2021-04-23 20:27:35
#
#===============================================================================

set -o nounset                              # Treat unset variables as an error

SCRIPT=${0##*/}
# DIR=${0%/*}
VERSION="0.0.2"

STDOUT="/dev/fd/2"

#===  FUNCTION  ================================================================
#         NAME: _usage
#  DESCRIPTION: Reports usage; always exits the script after doing so
#   PARAMETERS: 1 - the integer to pass to the 'exit' command
#      RETURNS: Nothing
#===============================================================================
_usage () {
    local -i result=${1:-0}

    cat >$STDOUT <<-endusage
${SCRIPT} - version: ${VERSION}

Usage: ./${SCRIPT} [-h] [-v] path_to_file

Performs a "transcode" action on the given file.

This means a variety of audio types are generated from the 'wav' format. The
formats required are 'wav' 'opus' 'flac' 'mp3' 'ogg' 'spx'. If the file
presented is not 'wav' format then this format is generated from the file
using ffmpeg.

Options:
  -h                    Print this help
  -v                    Run in verbose mode where more information is reported

Arguments:
    path_to_file        The primary file to be processed. The replica files
                        generated from it are written to the same path. The
                        file is expected to be an HPR audio file with a name
                        such as 'hpr1234.mp3'.

endusage
    exit "$result"
}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#
# Options
#
while getopts :hv opt
do
    case "${opt}" in
        h) _usage 1;;
        v) VERBOSE=1;;
        *) _usage 1;;
    esac
done
shift $((OPTIND - 1))

VERBOSE=${VERBOSE:-0}

#
# Check for the presence of the required tools
#
for f in ffmpeg ffprobe opusenc sox speexenc transfer_tags; do
    TOOL=$(command -v $f)
    if [[ -z $TOOL ]]; then
        echo "$SCRIPT: Unable to find required audio tool '$f'; aborted"
        exit 1
    fi
done

#
# We need an audio file argument
#
if [[ $# -ne 1 ]]; then
    _usage 1
fi

PRIMARY=$1
WORKDIR=${PRIMARY%/*}
FILE=${PRIMARY##*/}

# echo "PRIMARY=$PRIMARY"
# echo "WORKDIR=$WORKDIR"
# echo "FILE=$FILE"

declare -a audiotypes
mapfile -t audiotypes < <(printf '%s\n' wav opus flac mp3 ogg spx)

#
# We expect an HPR-format filename and one of a list of audio formats.
# TODO: review the use of spx!
#
RE="${audiotypes[*]/%/|}"
RE="${RE// /}"
RE="${RE:0: -1}"
RE="^hpr([0-9]{1,4})\.($RE)$"

if [[ $FILE =~ $RE ]]; then
    ep_num=${BASH_REMATCH[1]}
    ext=${BASH_REMATCH[2]}
else
    echo "$SCRIPT: Expecting an HPR audio file, got $FILE"
    exit 1
fi

#
# Check the primary file exists
#
[ -e "$PRIMARY" ] || { echo "$SCRIPT: Unable to find the file: $PRIMARY"; exit 1; }

#
# Is the primary file a wav file? If not, convert it
# TODO: Can this be one with spx?
#
CHANNELS=1
WAV="$WORKDIR/hpr${ep_num}.wav"
if [[ ! -e $WAV ]]; then
    if [[ ! "$ext" == 'wav' ]]; then
        [[ $VERBOSE -eq 1 ]] && echo "Making a wav file from $ext"
        ffmpeg -i "${PRIMARY}" -ar 44100 -ac $CHANNELS "$WAV" > /dev/null 2>&1
    fi
fi

TEMP_DIR='/tmp'

#
# Make variables containing the audio variants
#
[[ $VERBOSE -eq 1 ]] && echo "Generating replica files..."
for fmt in "${audiotypes[@]}"; do
    target="$WORKDIR/hpr${ep_num}.${fmt}"
    case $fmt in
        wav)
            [[ $VERBOSE -eq 1 ]] && echo "** Nothing to do for $fmt"
            continue
            ;;
        opus)
            if [[ ! -e "$target" ]]; then
                if [[ $VERBOSE -eq 1 ]]; then
                    echo "Make format $fmt"
                    opusenc "$WAV" "$target"
                else
                    opusenc "$WAV" "$target" > /dev/null 2>&1
                fi
            else
                [[ $VERBOSE -eq 1 ]] && echo "** $target already exists"
            fi
            continue
            ;;
        flac|mp3|ogg)
            if [[ ! -e "$target" ]]; then
                if [[ $VERBOSE -eq 1 ]]; then
                    echo "Make format $fmt"
                    sox --temp "${TEMP_DIR}" -S "$WAV" "$target"
                else
                    sox --temp "${TEMP_DIR}" -S "$WAV" "$target" > /dev/null 2>&1
                fi
            else
                [[ $VERBOSE -eq 1 ]] && echo "** $target already exists"
            fi
            continue
            ;;
        spx)
            if [[ ! -e "$target" ]]; then
                if [[ $VERBOSE -eq 1 ]]; then
                    echo "Make format $fmt"
                    sox --temp "${TEMP_DIR}" -S "$WAV" -c 1 -r 16000 -t wav  - |\
                        speexenc - "$target"
                else
                    sox --temp "${TEMP_DIR}" -S "$WAV" -c 1 -r 16000 -t wav  - |\
                        speexenc - "$target" > /dev/null 2>&1
                fi
            else
                [[ $VERBOSE -eq 1 ]] && echo "** $target already exists"
            fi
            continue
            ;;
    esac
done

[[ $VERBOSE -eq 1 ]] && echo "transfer_tags $PRIMARY"
if [[ $VERBOSE -eq 1 ]]; then
    transfer_tags -verbose "$PRIMARY"
else
    transfer_tags -noverbose "$PRIMARY"
fi

exit

# vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21
