You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rosegarden/src/helpers/rosegarden-audiofile-importer

271 lines
7.9 KiB

#!/bin/bash
#
# Helper application to convert and import audio files for Rosegarden.
# Copyright 2005-2008 Chris Cannam. Distributed under the GNU General
# Public License.
#
# Can take audio files of various kinds as input, always produces WAV
# files that are compatible with Rosegarden as output.
#
# Not actually specific to Rosegarden in any way, except that
# Rosegarden needs to know it can rely on its presence and calling
# interface.
#
# Usage:
#
# rosegarden-audiofile-importer -t [<version>]
# rosegarden-audiofile-importer --conftest [<version>]
# -- Exit successfully if the importer is available and working
# [and is of at least version <version>]. If some of the
# required helper applications are missing, also print to
# stdout a line saying "Required: application1, application2",
# listing the missing programs.
#
# rosegarden-audiofile-importer -l [<version>]
# -- List known file extensions (e.g. ogg wav flac). Return code
# is same as for -t (so can combine two calls into one)
#
# rosegarden-audiofile-importer [-r <rate>] -w <inputfile>
# -- Test whether any work is needed to convert <inputfile>, either
# because it isn't in a Rosegarden-compatible format or because
# its samplerate differs from <rate>. Exit successfully if no
# work is required; return error code 2 if conversion required,
# 3 if resampling required, 4 if both required, 1 for other error.
#
# rosegarden-audiofile-importer [-r <rate>] -c <inputfile> <outputfile>
# -- Convert <inputfile> [and resample if necessary] and write to
# <outputfile> as a WAV file
#
# N.B. <outputfile> must not already exist -- this program will not
# overwrite it, but will fail instead if it does
version=1
OTHER_ERROR=1
CONVERSION_REQD=2
RESAMPLE_REQD=3
BOTH_REQD=4
echo "rosegarden-audiofile-importer: $@" 1>&2
conftest() {
# ssrc is our favourite resampler, but it only works for certain
# samplerates, so we have to have at least one other just in case
if [ -x "`type -path sndfile-resample`" ]; then
return 0
fi
if [ -x "`type -path sox`" ] && sox -h 2>&1 | grep -q polyphase; then
return 0
fi
echo "Required: sox OR sndfile-resample"
echo "rosegarden-audiofile-importer: ERROR: No resampler available, failing configuration test" 1>&2
return 1
}
[ -x "`type -path oggdec`" ] && have_oggdec=1
[ -x "`type -path flac`" ] && have_flac=1
[ -x "`type -path mpg321`" ] && have_mpg321=1
[ -x "`type -path sndfile-convert`" -a -x "`type -path sndfile-info`" ] && have_sndfile=1
if [ -n "$have_mpg321" ]; then
if ! mpg321 --help 2>&1 | grep -q 'wav N'; then
have_mpg321=
fi
fi
case "$1" in
-t|--conftest) conftest; exit $?;;
-l) conftest || exit $?
{
[ -n "$have_oggdec" ] && echo ogg
[ -n "$have_flac" ] && echo flac
[ -n "$have_mpg321" ] && echo mp3
[ -n "$have_sndfile" ] && sndfile-convert --help 2>&1 | \
grep '^ *[a-z][a-z]* *: ' | awk '{ print $1; }'
} | sort | uniq | fmt -1000
exit 0;;
-r) rate="$2"; shift; shift;;
esac
case "$1" in
-w) test_work=1;;
-c) convert=1;;
*) exit 2;;
esac
conftest || exit $OTHER_ERROR
infile="$2"
if [ ! -r "$infile" ]; then
echo "rosegarden-audiofile-importer: ERROR: input file \"$infile\" cannot be opened" 1>&2
exit $OTHER_ERROR
fi
if [ -n "$convert" ]; then
outfile="$3"
if [ -z "$outfile" ]; then
echo "rosegarden-audiofile-importer: ERROR: output file not specified" 1>&2
exit $OTHER_ERROR
fi
if [ -f "$outfile" ]; then
echo "rosegarden-audiofile-importer: ERROR: output file \"$outfile\" already exists, not overwriting" 1>&2
exit $OTHER_ERROR
fi
fi
base=`basename "$infile"`
stem=${base%.*}
extension=${base##*.}
extension=`echo $extension | tr '[A-Z]' '[a-z]'`
# If the file ends in ogg, mp3, wav or flac, we believe it. Otherwise
# use file to see whether it's actually something else
case "$extension" in
ogg|mp3|wav|flac) ;;
*) case "`file $infile`" in
*Ogg*Vorbis*) extension=ogg;;
*MP3*) extension=mp3;;
*FLAC*) extension=flac;;
esac;;
esac
case "$extension" in
ogg) converter=oggdec
[ -x "`type -path ogginfo`" ] && filerate=`ogginfo "$infile" | grep '^Rate: ' | awk '{ print $2; }'`;;
mp3) converter=mpg321
# don't have a helper program to work out rate
;;
*) filerate=`sndfile-info "$infile" | grep '^Sample Rate :' | awk '{ print $4; }'`;;
esac
case "$extension" in
wav) ;;
flac) converter=flac; convert_reqd=1;;
ogg|mp3) convert_reqd=1;;
*) converter=sndfile-convert; convert_reqd=1;;
esac
echo "Extension is $extension, converter is $converter, reqd is $convert_reqd"
case "$filerate" in [0-9]*);; *) filerate=; intermediate=1;; esac
[ -n "$filerate" ] && echo "File samplerate is $filerate (requested: $rate)"
[ -n "$filerate" -a -n "$rate" ] && [ "$filerate" -ne "$rate" ] && resample_reqd=1
[ -n "$resample_reqd" -a -n "$convert_reqd" ] && intermediate=1
[ -n "$intermediate" ] && echo "Using intermediate file"
if [ -z "$convert" ]; then # -w option
if [ -n "$convert_reqd" ]; then
[ -n "$intermediate" -o -n "$resample_reqd" ] && exit $BOTH_REQD
exit $CONVERSION_REQD;
else
[ -n "$intermediate" -o -n "$resample_reqd" ] && exit $RESAMPLE_REQD
exit 0;
fi
fi
target="$outfile"
if [ -n "$intermediate" ]; then
target="$outfile.tmp.wav"
if [ -f "$target" ]; then
echo "rosegarden-audiofile-importer: ERROR: intermediate file \"$target\" already exists, not overwriting" 1>&2
exit $OTHER_ERROR
fi
trap "rm -f \"$target\"" 0
trap "rm -f \"$target\" \"$outfile\"" 1 2 9 11 15
else
trap "rm -f \"$outfile\"" 1 2 9 11 15
fi
resample() {
_source=$1; shift
_target=$1; shift
simple=""
case "$filerate" in
192000|176400|96000|88200|48000|44100|24000|22050|12000|11025)
case "$rate" in
192000|176400|96000|88200|48000|44100|24000|22050|12000|11025)
simple=1;;
esac
esac
done=""
if [ -x "`type -path ssrc`" -a -n "$simple" ]; then
echo "Resampling using ssrc..." 1>&2
ssrc --rate "$rate" --twopass --dither 4 --profile standard "$_source" "$_target" && done=1
fi
if [ -z "$done" ]; then
if [ -x "`type -path sndfile-resample`" ]; then
echo "Resampling using sndfile-resample..." 1>&2
sndfile-resample -to "$rate" -c 0 "$_source" "$_target" || return 4
else
echo "Resampling using sox..." 1>&2
sox "$_source" -r "$rate" "$_target" polyphase || return 4
fi
fi
return 0
}
if [ -n "$convert_reqd" ]; then
case "$converter" in
flac) [ -z "$have_flac" -a -n "$have_sndfile" ] && converter=sndfile-convert;;
esac
case "$converter" in
oggdec)
[ -n "$have_oggdec" ] || exit $OTHER_ERROR
oggdec --output "$target" "$infile" || exit $OTHER_ERROR
;;
mpg321)
[ -n "$have_mpg321" ] || exit $OTHER_ERROR
mpg321 --wav "$target" "$infile" || exit $OTHER_ERROR
;;
flac)
[ -n "$have_flac" ] || exit $OTHER_ERROR
flac --decode --output-name="$target" "$infile" || exit $OTHER_ERROR
;;
*)
[ -n "$have_sndfile" ] || exit $OTHER_ERROR
sndfile-convert -pcm16 "$infile" "$target" || exit $OTHER_ERROR
;;
esac
elif [ -n "$resample_reqd" ]; then
resample "$infile" "$target" || exit $OTHER_ERROR
resample_reqd=
fi
if [ ! -f "$target" ]; then
echo "rosegarden-audiofile-importer: ERROR: target file not found" 1>&2
exit $OTHER_ERROR
fi
if [ -z "$intermediate" ]; then
echo "rosegarden-audiofile-importer: Done" 1>&2
exit 0
fi
if [ -n "$intermediate" -a -n "$rate" -a -z "$filerate" ]; then
filerate=`sndfile-info "$target" | grep '^Sample Rate :' | awk '{ print $4; }'`
case "$filerate" in
[0-9]*) if [ "$filerate" -ne "$rate" ]; then
resample_reqd=1
fi;;
*) echo "rosegarden-audiofile-importer: ERROR: failed to extract samplerate of intermediate file" 1>&2
rm "$target"
exit $OTHER_ERROR
;;
esac
fi
if [ -n "$resample_reqd" ]; then
resample "$target" "$outfile" || exit $OTHER_ERROR
rm "$target"
else
mv "$target" "$outfile"
fi
echo "rosegarden-audiofile-importer: Done" 1>&2
exit 0