#!/usr/bin/env bash
# /usr/local/bin/speedup
# https://crystalfaeries.net/posix/bin/speedup
# celeste:crystalfaery SPEEDUP 2016-10-07 03:01:22+00:00
# http://hackerpublicradio.org/eps/hpr2135/full_shownotes.html
#===============================================================================
#
# FILE: speedup
#
# USAGE: ./speedup [-s ...] [-t ...] [-m] [-c] [-d] [-D] [-h] filename
#
# DESCRIPTION: A script to perform a speedup and silence removal on a given
# audio file
#
# OPTIONS: ---
# REQUIREMENTS: ---
# BUGS: ---
# NOTES: ---
# AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
# VERSION: 0.0.4
# CREATED: 2015-05-01 21:51:32
# REVISION: 2016-04-22 11:35:08
#
#===============================================================================
set -o nounset # Treat unset variables as an error
SCRIPT=${0##*/}
VERSION="0.0.4"
#=== FUNCTION ================================================================
# NAME: _usage
# DESCRIPTION: Report usage
# PARAMETERS: 1 - the exit value (so it can be used to return an error
# value)
# RETURNS: Nothing
#===============================================================================
_usage () {
local res="${1:-0}"
cat <<-endusage
Usage: ${SCRIPT} [-s ...] [-t ...] [-m] [-c] [-d] [-D] [-h] filename
Speeds up and truncates silence in an audio file
Options:
-s This option if present causes the audio to be sped up.
The option can be repeated and the speed up is increased for
every -s given
-t This option if present causes the audio to have silences
truncated. The option can be repeated to increase the
sensitivity of the truncation
-m Mix-down multiple (stereo) tracks to mono
-c Delete the original file leaving the modified file behind with
the same name as the original
-d Engage dry-run mode where the planned actions are reported
but nothing is actually done
-D Run in DEBUG mode where more information is reported
about what is going on
-h Print this help
Arguments:
filename The full path of the audio file containing the podcast episode.
Note:
Unless deleted with the -c option the script will rename the original file
and create the modified file with the same name as the original. The
original file will have the name 'NAME_.EXT' with an underscore added after
the original name.
Version: $VERSION
endusage
exit "$res"
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Default settings
#
CLEANUP=0
DEBUG=0
DRYRUN=0
SPEEDUP=0
TRUNCATE=0
MIXDOWN=0
#
# Process options
#
while getopts :cDdhmst opt
do
case "${opt}" in
c) CLEANUP=1;;
D) DEBUG=1;;
d) DRYRUN=1;;
s) ((SPEEDUP++));;
t) ((TRUNCATE++));;
m) MIXDOWN=1;;
h) _usage 1;;
*) _usage 1;;
esac
done
shift $((OPTIND - 1))
#
# Check there is one argument
#
if [[ $# -ne 1 ]]; then
echo "Error: filename missing"
_usage 1
fi
#
# Does the file given as an argument exist?
#
if [[ ! -e "$1" ]]; then
echo "File not found: $1"
exit 1
fi
if [[ $DRYRUN -eq 1 ]]; then
echo "Dry run: no changes will be made"
fi
#
# Work out the speed-up we want (if any) and generate the argument to sox
#
SPEEDS=( 1.05 1.1 1.2 1.3 1.4 1.5 1.6 1.7 )
if [[ $SPEEDUP -eq 0 ]]; then
TEMPO=
else
if [[ $SPEEDUP -gt ${#SPEEDS[@]} ]]; then
SPEEDUP=${#SPEEDS[@]}
fi
((SPEEDUP--))
speed=${SPEEDS[$SPEEDUP]}
TEMPO="tempo ${speed}"
fi
#
# Work out the silence truncation parameters (if any). The first set trims
# silence but ignores silences of 0.5 seconds in the middle (like pauses for
# breaths). The second set removes everything but can make a rather rushed
# result. See http://digitalcardboard.com/blog/2009/08/25/the-sox-of-silence/
# for some advice.
#
TRUNCS=( "1 0.1 1% -1 0.5 1%" "1 0.1 1% -1 0.1 1%" )
if [[ $TRUNCATE -eq 0 ]]; then
SILENCE=
else
if [[ $TRUNCATE -gt ${#TRUNCS[@]} ]]; then
TRUNCATE=${#TRUNCS[@]}
fi
((TRUNCATE--))
silence=${TRUNCS[$TRUNCATE]}
SILENCE="silence ${silence}"
fi
if [[ $MIXDOWN == 0 ]]; then
REMIX=
else
REMIX="remix -"
fi
#
# Report some internals in debug mode
#
if [[ $DEBUG -eq 1 ]]; then
echo "SPEEDUP = $SPEEDUP"
echo "TRUNCATE = $TRUNCATE"
echo "MIXDOWN = $MIXDOWN"
echo "speed = ${speed:-0}"
echo "silence = ${silence:-}"
echo "TEMPO = $TEMPO"
echo "SILENCE = $SILENCE"
echo "REMIX = $REMIX"
fi
#
# Is there anything to do?
#
if [[ -z $TEMPO && -z $SILENCE ]]; then
echo "Nothing to do; exiting"
exit 1
fi
#
# Divide up the path to the file
#
orig="$(realpath "$1")"
odir="${orig%/*}"
oname="${orig##*/}"
oext="${oname##*.}"
#
# The name of the original file will be changed to this
#
new="${odir}/${oname%.$oext}_.${oext}"
#
# Report the name of the input file
#
echo "Processing $orig"
#
# If the new name exists we already processed it
#
if [[ -e $new ]]; then
echo "Oops! Looks like this file has already been sped up"
exit 1
fi
#
# Rename the original file
#
if [[ $DRYRUN -eq 1 ]]; then
printf "Dry run: rename %s to %s\n" "$orig" "$new"
else
mv "$orig" "$new"
fi
#
# Speed up and remove long silences as requested
# -S requests a progress display
# -v2 adjusts the volume of the file that follows it on the command line by
# a factor of 2
# -V9 requests a very high (debug) level of verbosity (default -V2)
# remix - mixes all stereo to mono
#
#sox -S -v2 "${new}" "${orig}" -V9 ${TEMPO} remix - ${SILENCE}
if [[ $DRYRUN -eq 1 ]]; then
printf "Dry run: %s\n" \
"sox -S -v2 \"${new}\" \"${orig}\" ${TEMPO} ${REMIX} ${SILENCE}"
else
# [We want TEMP, REMIX and SILENCE to be word-split etc]
# shellcheck disable=SC2086
sox -S -v2 "${new}" "${orig}" ${TEMPO} ${REMIX} ${SILENCE}
fi
#
# Delete the original file if asked. Note that the script can't detect that
# the audio has been sped up if this file is missing.
#
if [[ $CLEANUP -eq 1 ]]; then
if [[ $DRYRUN -eq 1 ]]; then
printf "Dry run: delete %s\n" "$new"
else
rm -f "$new"
fi
fi
exit
# vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21
syntax highlighted by Code2HTML, v. 0.9.1