#!/bin/bash
#set -n		# read but do not execute commands (check on syntax errors)
#
# File: /usr/local/bin/audiofilter-treble.
#
# Apply the treble filter.
#
#    Copyright (c) 2023  Juergen Kaesmann (JK)
#
##############################################################################
# GPL NOTICE
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
##############################################################################
# FIND SAMPLES
#
##############################################################################
# FILTER SAMPLES
#
# To avoid spaces (shell) surround filter and arguments with ""
# There are two filter types:
# a) Simple filter
#	-filter:a|-filter:v "<filter>=<arguments_list>"
#	or
#	-af|-vf "<filter>=<arguments_list>"
# b) Complex filter
#	-filter_complex "[<arguments_list>]<filter>=<arguments_list>"
#
#-----------------------------------------------------------------------------
# SETPTS filter explanation:
# setpts	Set timestamps.
#
# generate video timestamps from zero:
# -filter:v "trim" -filter:v "setpts=PTS-STARTPTS"
#
# generate audio timestamps from zero:
# -filter:a "atrim" -filter:a "asetpts=PTS-STARTPTS"
#
#-----------------------------------------------------------------------------
# VOLUME filter explanation:
# volume	Adjust the volume. Do not set the volume.
#
# increase volume by 150%:
# -filter:a "volume=1.5"
#
# increase volume by 10dB:
# -filter:a "volume=10dB"
#
# reduce volume by 5dB, use a negative value:
# -filter:a "volume=-5dB"
#
#-----------------------------------------------------------------------------
# PEAK and RMS Normalization:
# volume	Adjust the volume to a peak or RMS level.
#
# To normalize the volume to a given peak or RMS level, the file first has to
# be analyzed with filter a) or b):
# a) -filter:a volumedetect
# b) -filter_complex [0:a]ebur128=peak=sample
#
# Read the output values from the command line log (relative to max value)
# and calculate the required offset to adjust max_volume/PEAK to 0.
# Then change the volume with the filter:
# -filter:a "volume=<offset>dB"
#
# or normalize the file with:
# -af "dynaudnorm=<...>"
#
#-----------------------------------------------------------------------------
# COMPANDER explanation:
# compand	Compress or expand the audio's dynamic range.
#
# Show compand params - separate every PART with ':'
# PARTS		DEFAULTS		MODE "s"
# attack lst	0.3 0.3			0 0
# decay lst	0.8 0.8			1 1
# points lst	-70/-70 -60/-60 1/0	-90/-900 -70/-70 -30/-9 0/-3
# soft-knee	0.01			6
# gain		0			0
# volume	0			0
# delay		0			0
#
# Using simple audiofilter:
# -af "aformat=channel_layouts=stereo, compand=0 0:1 1:-90/-900 -70/-70 -30/-9 0/-3:6:0:0:0"
#
# Using complex audiofilter:
# -filter_complex "compand=0 0:1 1:-90/-900 -70/-70 -30/-9 0/-3:6:0:0:0"
#
# same as above but avoid SPACES:
# -filter_complex compand=0|0:1|1:-90/-900|-70/-70|-30/-9|0/-3:6:0:0:0
#
#-----------------------------------------------------------------------------
# EQUALIZER explanation:
# equalizer	Apply a two-pole peaking equalisation (EQ) filter.
#
# With this filter, the signal-level at and around a selected frequency can
# be increased or decreased, whilst (unlike bandpass and bandreject filters)
# that at all other frequencies signal is unchanged.
#
# In order to produce complex equalisation curves, this filter can be
# given several times, each with a different central frequency and separated
# with a comma.
#
# The filter accepts the following options:
# frequency, f	Set the filter's central frequency in Hz.
# width_type	Set method to specify band-width of filter.
# 	h	Hz
# 	q	Q-Factor
# 	o	octave
# 	s	slope
# width, w	Specify the band-width of a filter in width_type units.
#		Have in mind that the frequency is limited to 999 Hz.
# gain, g	Set the required gain or attenuation in dB.
# 		Beware of clipping when using a positive gain.
#
# Examples:
# Attenuate 10 dB at 1000 Hz, with a bandwidth of 200 Hz:
# -af equalizer=f=1000:width_type=h:width=200:g=-10
#
# Apply 2 dB gain at 1000 Hz with Q 1 and attenuate 5 dB at 100 Hz with Q 2:
# -af equalizer=f=1000:width_type=q:width=1:g=2,equalizer=f=100:wid
#
# Apply 6 dB gain at 200 Hz and width 300 Hz:
# -af equalizer=f=200:width_type=h:w=300:g=6
#
# Sound Distribution:
# BAND		TYPE
# 16-100	Sub Bass
# 50-250	Bass
# --------------------------
# 250-2k	Low Midd
# 2k-4k		High Midd
# --------------------------
# 4k-6k		Präsenz
# 6k-16k	Brillanz
#
# Template EQ with 18 bands non-overlaping
# BAND		f	w
# 50-100	75	50
# 100-250	175	150
# 250-1k	625	750
# 1k-2k		1500	999
# 2k-3k		2500	999
# 3k-4k		3500	999
# 4k-5k		4500	999
# 5k-6k		5500	999
# 6k-7k		6500	999
# 7k-8k		7500	999
# 8k-9k		8500	999
# 9k-10k	9500	999
# 10k-11k	10500	999
# 11k-12k	11500	999
# 12k-13k	12500	999
# 13k-14k	13500	999
# 14k-15k	14500	999
# 15k-16k	15500	999
# -af equalizer=f=75:width_type=h:w=50:g=0,equalizer=f=175:width_type=h:w=150:g=0,equalizer=f=625:width_type=h:w=750:g=0,equalizer=f=1500:width_type=h:w=999:g=0,equalizer=f=2500:width_type=h:w=999:g=0,equalizer=f=3500:width_type=h:w=999:g=0,equalizer=f=4500:width_type=h:w=999:g=0,equalizer=f=5500:width_type=h:w=999:g=0,equalizer=f=6500:width_type=h:w=999:g=0,equalizer=f=7500:width_type=h:w=999:g=0,equalizer=f=8500:width_type=h:w=999:g=0,equalizer=f=9500:width_type=h:w=999:g=0,equalizer=f=10500:width_type=h:w=999:g=0,equalizer=f=11500:width_type=h:w=999:g=0,equalizer=f=12500:width_type=h:w=999:g=0,equalizer=f=13500:width_type=h:w=999:g=0,equalizer=f=14500:width_type=h:w=999:g=0,equalizer=f=15500:width_type=h:w=999:g=0
#
#-----------------------------------------------------------------------------
# ANEQUALIZER explanation:
# anequalizer	High-order parametric multiband equalizer for each channel.
#
# This option string is in format: "c<chn> f=<cf> w=<bw> g=<bg> t=<ft> | ..."
# Each equalizer band is separated by '|'.
#
# chn	Channel number to which equalization will be applied (0|1 for stereo).
#	If input doesn't have that channel the entry is ignored.
# cf	Central frequency for band.  If input doesn't have that
#	frequency the entry is ignored.
# bw	Band width in hertz.
# bg	Band gain in dB.
# ft	Filter type for band, optional, can be:
#	0	Butterworth, this is default.
#	1	Chebyshev type 1.
#	2	Chebyshev type 2.
#
# Examples:
# Lower gain by 10 of central frequency 200Hz and width 100 Hz for
# first 2 channels using Chebyshev type 1 filter:
# -af "anequalizer=c0 f=200 w=100 g=-10 t=1|c1 f=200 w=100 g=-10 t=1"
#
# Rise gain by 6 dB of central frequency 200 Hz and width 300 Hz for
# first 2 channels using Butterworth type 0 filter:
# -af "anequalizer=c0 f=200 w=300 g=6 t=0|c1 f=200 w=300 g=6 t=0"
#
#-----------------------------------------------------------------------------
# AFADE filter explanation:
# afade		Apply fade-in/out effect to input audio.
#
# type, t
#   Specify the effect type, can be either "in" for fade-in, or "out"
#   for a fade-out effect. Default is "in".
#
# start_time, st
#   Specify the start time of the fade effect. Default is 0.  The value
#   must be specified as a time duration; see the Time duration section
#   in the ffmpeg-utils(1) manual for the accepted syntax.
#
# duration, d
#   Specify the duration of the fade effect. See the Time duration
#   section in the ffmpeg-utils(1) manual for the accepted syntax.  At
#   the end of the fade-in effect the output audio will have the same
#   volume as the input audio, at the end of the fade-out transition
#   the output audio will be silence.
#
# curve
#   Set curve for fade transition.
#   It accepts the following values:
#     tri	select triangular, linear slope (default)
#     qsin	select quarter of sine wave
#     hsin	select half of sine wave
#     esin	select exponential sine wave
#     log	select logarithmic
#     ipar	select inverted parabola
#     qua	select quadratic
#     cub	select cubic
#     squ	select square root
#     cbr	select cubic root
#     par	select parabola
#     exp	select exponential
#     iqsin	select inverted quarter of sine wave
#     ihsin	select inverted half of sine wave
#     dese	select double-exponential seat
#     desi	select double-exponential sigmoid
#
# Examples:
# Fade in first 1 second of audio:
# -af "afade=t=in:st=0:d=1"
# Fade out last 3 seconds of a 180 seconds audio:
# -af "afade=t=out:st=177:d=3"
#
#-----------------------------------------------------------------------------
# ATEMPO filter explanation:
# atempo - Adjust audio tempo.
#
# The filter accepts exactly one parameter, the audio tempo. If not
# specified then the filter will assume nominal 1.0 tempo. Tempo must be
# in the [0.5, 2.0] range.
#
# Examples:
# Slow down audio to 80% tempo:
# -af "atempo=0.8"
# To speed up audio to 125% tempo:
# -af atempo=1.25
#
##############################################################################
# AWK SAMPLES
#
##############################################################################
# SED SAMPLES
#
##############################################################################
# RSYNC OPTIONS
#
##############################################################################
# DIALOG SAMPLES
#
##############################################################################
# REPLACE STRINGS
#
##############################################################################
# EXIT CODES

##############################################################################
# SOURCE FILES
#
. /usr/local/etc/main.conf				# config main
#. $LLIBDIR/libfuncerr-sh				# functions error
. $LLIBDIR/libfuncstd-sh				# functions standard
#. $LLIBDIR/libfuncmath-sh				# functions math
#. $LLIBDIR/libfuncip-sh				# functions IP
#. /usr/local/etc/sample.conf				# config sample
#
#if [ ! -e ~/.samplerc ]; then				# install config user
#	cp /usr/local/share/ksm-sample/samplerc ~/.samplerc
#fi
#. ~/.samplerc						# config user

##############################################################################
# DECLARATION OF STANDARD CONSTANTS AND VARIABLES
#
readonly package=Multimedia				# package name
readonly package_file=ksm-multimedia			# package file name
readonly vinfopath="/usr/local/share/$package_file"	# path to package dir
readonly version=$(/bin/cat $vinfopath/VERSION)		# package version
readonly release=$(/bin/cat $vinfopath/RELEASE)		# package release
readonly scriptname=$(basename $0)			# name of script
#readonly tempfile=$TEMPDIR/$scriptname.$UID.tmp	# temporary file name
#tempfile=$(mktemp $TEMPDIR/$scriptname.$UID.XXXXXX)	# temporary file name
#readonly lockfile=$TEMPDIR/lock/$scriptname.$UID.lock	# lock file name
readonly debuglog="/usr/bin/logger -p user.debug -t $scriptname -- DEBUG:"	# log dbg msg
readonly errlog="/usr/bin/logger -p user.err -t $scriptname -- ERROR:"		# log err msg
readonly infolog="/usr/bin/logger -p user.info -t $scriptname -- INFO:"		# log inf msg
cmd=''							# sub command
debug=no						# debug=yes/no
verbose=''						# verbose=yes/''/no
err=${_ERR_OK_}						# error code

##############################################################################
# USER FILL IN AT FIRST RUN

##############################################################################
# SYSTEM

##############################################################################
# USER-CONSTANTS

##############################################################################
# USER-VARIABLES
#
# STRINGS
#args=''				# all args from cmdline
arg1=''					# 1. arg from cmdline
arg2=''					# 2. arg from cmdline
arg3=''					# 3. arg from cmdline
#opt_o=''				# option -o (yes)
					# option --output (yes)
#opt_i=''				# option -i (arg)
					# option --infile (arg)
#opt_o=''				# option -o (arg)
					# option --outfile (arg)
#opt_p=''				# option -p (arg)
					# option --pages (arg)
f=''

# NUMBERS
#p_first=0				# first page
#p_last=0				# last page

# ARRAYS
# Indexed arrays are always zero based string arrays.
# If index starts with 1 and all members are assigned then
# count of members of array = last index of array
#declare -a arr
#maxarr="${#arr[@]}"			# get number of elements in arr
#unset arr[@]				# remove the entire array

##############################################################################
# LANGUAGE SUPPORT

##############################################################################
# SIGNAL HANDLING

##############################################################################
# FUNCTIONS
##############################################################################
#
##############################################################################
# HELP
#
#=============================================================================
function helptext ()
{
# Output helptext
# Uses cat, echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG helptext: $# $@" >&2
	$debuglog helptext: $# $@
fi

cat <<EOT
NAME
$scriptname - Apply the treble filter.

SYNOPSIS
$scriptname [options] [par inf [outf]]

<AUDIOSTREAM> | $scriptname [options] par inf outf

DESCRIPTION
Apply the treble filter to an MP3 file or to an MP3 stream.

If <inf> is given but <outf> is not given then the outfile is generated
from <inf> prepended with 'n'.

If <inf> is a '-' then we process an incoming audio stream (type nut)
from STDIN.

If <outf> is a '-' then we stream the audio to STDOUT (stream type is
nut).

FFMPEG INFO
Boost or cut treble.

treble=g=1:f=3000:width_type=h:w=0.6

Boost or cut treble (upper) frequencies of the audio using a two-pole
shelving filter with a response similar to that of a standard hi-fi's
tone-controls. This is also known as shelving equalisation (EQ).

The filter accepts the following options:

gain, g  
    Give the gain at whichever is the lower of ~22 kHz and the Nyquist
    frequency. Its useful range is about -20 (for a large cut) to +20
    (for a large boost). Beware of clipping when using a positive gain.

frequency, f  
    Set the filter's central frequency and so can be used to extend or
    reduce the frequency range to be boosted or cut. The default value
    is 3000 Hz.

width_type  
    Set method to specify band-width of filter.

    h   Hz
    q   Q-Factor
    o   octave
    s   slope

width, w  
    Determine how steep is the filter's shelf transition.

OPTIONS
Gnu style options:

  -h|--help    = Output help, then exit.
  -V|--version = Output version info, then exit.
  -d|--debug   = Turn on DEBUG mode.
  -q|--quiet   = Be quiet.
  -v|--verbose = Be verbose.
  -a           = Process all MP3s in actual dir (supply only <par>).
  --           = End of options.

ARGUMENTS
Give if needed:

  par  = The parameter to supply 'g=1:f=3000:width_type=h:w=0.6'
  inf  = The input file name or a '-'
  outf = The output file name or a '-'

EXAMPLES
For instance:

  Apply treble filter:
  $scriptname 'g=1:f=3000:width_type=h:w=0.6' INFILE.mp3 OUTFILE.mp3

EXIT STATUS
On program exit:

  Code 0 = OK

  See output of 'showerrmsg'.

SEE ALSO
Related manpages:

  showerrmsg(1), ffmpeg(1), media2media(1),
  audiofilter-bandpass(1), audiofilter-bandreject(1), 
  audiofilter-bass(1), audiofilter-chorus(1), 
  audiofilter-compand(1), audiofilter-crossfade(1), 
  audiofilter-dynaudnorm(1), audiofilter-dynvol(1), 
  audiofilter-earwax(1), audiofilter-echo(1), 
  audiofilter-extrastereo(1), audiofilter-fade(1), 
  audiofilter-flanger(1), audiofilter-gate(1), 
  audiofilter-highpass(1), audiofilter-limiter(1), 
  audiofilter-lowpass(1), audiofilter-phaser(1), 
  audiofilter-pulsator(1), audiofilter-rubberband(1), 
  audiofilter-stereotools(1), audiofilter-stereowiden(1), 
  audiofilter-tempo(1), 
  audiofilter-tremolo(1), audiofilter-vibrato(1), 
  audiofilter-volcomp(1), audiofilter-volume(1).

AUTHORS
Juergen Kaesmann <juergen@kaesmann-online.de>
EOT
#  -o|--output  = Output to STDOUT.
#  -i f         = Input from file <f>.
#  --infile=f   = Input from file <f>.
#  -o f         = Output to file <f>.
#  --outfile=f  = Output to file <f>.
#  -p s,e       = Pages s=START e=END.
#  --pages=s,e  = Pages s=START e=END.

#FILES
#Used directories and files:
#
#  Config global = /usr/local/etc/multimedia.conf

return
}

#=============================================================================
function mainproc ()
{
# Apply treble filter to the given file.
# par1 = par
# par2 = inf
# Uses echo, logger
# Return codes:
# Standard

if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG mainproc: $# $@" >&2
	$debuglog mainproc: $# $@
fi

local par="$1" inf="$2" outf="" pre=""
local ret=0
#local -a arr
#maxarr="${#arr[@]}"			# get number of elements in arr
#unset arr[@]				# remove the entire array

if [ "$inf" != '-' ] && [ -z "$arg3" ]; then
	outf="n${inf}"
else
	outf="$arg3"
fi
                
if [ "$inf" != '-' ]; then				# input from file
	if [ "$outf" != '-' ]; then			# store to file
		case "$verbose" in
		    yes)				# allow STDOUT and STDERR
			echo "Run $scriptname"
			ffmpeg -i $inf -af "treble=${par}" -c:v copy $pre -id3v2_version 3 -write_id3v1 1 $outf
			ret=$?
			;;
		    '')					# suppress STDOUT or STDERR
			#echo "Run $scriptname"
			ffmpeg -hide_banner -i $inf -af "treble=${par}" -c:v copy $pre -id3v2_version 3 -write_id3v1 1 $outf 2>/dev/null
			#1>/dev/null
			ret=$?
			;;
		    no)					# suppress STDOUT and STDERR
			ffmpeg -hide_banner -y -i $inf -af "treble=${par}" -c:v copy $pre -id3v2_version 3 -write_id3v1 1 $outf &>/dev/null
			ret=$?
			;;
		esac
	else						# pipe to STDOUT
		ffmpeg -hide_banner -y -i $inf -af "treble=${par}" -c:v copy -id3v2_version 3 -write_id3v1 1 -f nut - 2>/dev/null
		ret=$?
	fi
else							# input from STDIN
	if [ "$outf" != '-' ]; then			# store to file
		case "$verbose" in
		    yes)				# allow STDOUT and STDERR
			echo "Run $scriptname"
			ffmpeg -f nut -i $inf -af "treble=${par}" -c:v copy $pre -id3v2_version 3 -write_id3v1 1 $outf
			ret=$?
			;;
		    '')					# suppress STDOUT or STDERR
			#echo "Run $scriptname"
			ffmpeg -hide_banner -f nut -i $inf -af "treble=${par}" -c:v copy $pre -id3v2_version 3 -write_id3v1 1 $outf 2>/dev/null
			#1>/dev/null
			ret=$?
			;;
		    no)					# suppress STDOUT and STDERR
			ffmpeg -hide_banner -y -f nut -i $inf -af "treble=${par}" -c:v copy $pre -id3v2_version 3 -write_id3v1 1 $outf &>/dev/null
			ret=$?
			;;
		esac
	else						# pipe to STDOUT
		ffmpeg -hide_banner -y -f nut -i $inf -af "treble=${par}" -c:v copy -id3v2_version 3 -write_id3v1 1 -f nut - 2>/dev/null
		ret=$?
	fi
fi

if [ "$ret" -ne 0 ]; then				# from ffmpeg
	Show_Err ${_ERR_GENERAL_} "$ret from ffmpeg!"
	ret=${_ERR_GENERAL_}
fi

return $ret
}

##############################################################################
# GET OPTIONS
##############################################################################
# Give 2 strings and all cmdline_args to func GetOpt
# (POSIX_options Gnu_long_options cmdline_args):
# GetOpt 'hVdqvi:m:' 'help version debug quiet verbose infile= myval=' $@
#
# A ':' after a POSIX option means this option needs an arg.
# A '=' after a Gnu long option means this option needs an arg.
#
# All cmd/options have to be initialised to ''!
#
# POSIX options are classified in 2 categories:
#   a) cmds (mutually exclusive). All cmds are given to var 'cmd'.
#   b) options (as many as you like). Each option is given to it's own var.
# As a general rule: If cmds/options are given multiple then last given wins.
#
# Options can take 1 argument (no whitespace in arg). If you want to give more
# than 1 arg or want to use multiple strings as 1 arg then concatenate them
# together with a delimiter like ',' or ';' or '.'
# Use a delimiter which will not be part of the arg:
# sampleprog -m val1,val2
# sampleprog --myval=val1,val2
# It's at the programmers responsibility to do meaningfull things with the
# content of the options.
#
# If err != 0 then all args are processed, else continue to look for options.
# When GetOpt finishes then all options are removed from cmdline.
#
if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG Parse Commandline: $# $@" >&2
	$debuglog Parse Commandline: $# $@
fi
#
err=${_ERR_OK_}
while [ "$err" -eq 0 ]; do
	GetOpt 'hVdqva' 'help version debug quiet verbose' $@
	err=$?
	#echo "DEBUG GET OPTIONS: err=${err}  _OPTNAME_=${_OPTNAME_}  _OPTVAL_=${_OPTVAL_}  _OPTPOS_=${_OPTPOS_}  _OPTIDX_=${_OPTIDX_}" >&2
	if [ $err -eq 0 ]; then
		case "$_OPTNAME_" in
		    h|help)	cmd="-h";;
		    V|version)	cmd="-V";;
		    a)		cmd="-${_OPTNAME_}";;
		    d|debug)	debug=yes;;
		    q|quiet)	verbose=no;;
		    v|verbose)	verbose=yes;;
#		    o|output)	opt_o=yes;;
#		    i|infile)	opt_i="${_OPTVAL_}";;
#		    o|outfile)	opt_o="${_OPTVAL_}";;
#		    p|pages)	opt_p="${_OPTVAL_}";;
		    --)		break;;
		    :)	Show_Err ${_ERR_MISSING_ARG_FOR_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_MISSING_ARG_FOR_OPT_};;
		    ?)	Show_Err ${_ERR_UNKNOWN_OPT_} "-${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_OPT_};;
		    *)	Show_Err ${_ERR_UNKNOWN_ERR_} "_OPTNAME_=${_OPTNAME_} _OPTVAL_=${_OPTVAL_}"
			exit ${_ERR_UNKNOWN_ERR_};;
		esac
	fi
done
err=${_ERR_OK_}
shift ${_OPTIDX_}				# rm all opts from cmdline
#
# Uncomment if giving a cmd is mandatory
#if [ -z "$cmd" ]; then					# error no cmd given
#	Show_Err ${_ERR_MISSING_SUB_CMD_} ""
#	exit ${_ERR_MISSING_SUB_CMD_}
#fi

##############################################################################
# CHECK LINK NAMES

##############################################################################
# CHECK OPTIONS

##############################################################################
# CHECK VERSION

##############################################################################
# CHECK ARGUMENTS
#
case "$cmd" in
    '')
	if [ "$#" -eq 2 ]; then				# parameter count ok
		arg1="$1"
		arg2="$2"
		shift 2
		#args="$@"
		#shift $#
	elif [ "$#" -eq 3 ]; then			# parameter count ok
		arg1="$1"
		arg2="$2"
		arg3="$3"
		shift 3
	else						# error in param count
		Show_Err ${_ERR_WRONG_PAR_COUNT_} ""
		exit ${_ERR_WRONG_PAR_COUNT_}
	fi
	;;
    -a)
	if [ "$#" -eq 1 ]; then				# parameter count ok
		arg1="$1"
		shift
	else						# error in param count
		Show_Err ${_ERR_WRONG_PAR_COUNT_} ""
		exit ${_ERR_WRONG_PAR_COUNT_}
	fi
	;;
    *)
	if [ "$#" -ne 0 ]; then				# error in param count
		Show_Err ${_ERR_WRONG_PAR_COUNT_} ""
		exit ${_ERR_WRONG_PAR_COUNT_}
	fi
	;;
esac

##############################################################################
# LOCK

##############################################################################
# MAINPROGRAM
##############################################################################
#
if [ "$debug" == "yes" ]; then				# DEBUG
	echo "DEBUG Main: $# $@" >&2
	$debuglog Main: $# $@
fi
#
# Check what to do (sub commands, options and args are removed from cmdline)
case "$cmd" in
    '')
	mainproc $arg1 $arg2
	err=$?
	;;
    -h)
	helptext
	exit 0
	;;
    -V)
	echo "${scriptname}: (${package}) $package_file ${version}-${release}"
	exit 0
	;;
    -a)
	for f in *.mp3; do
		mainproc $arg1 "$f"
	done
	err=$?
	;;
    *)							# error
	Show_Err ${_ERR_SUB_CMD_NOT_FOUND_} ""
	err=${_ERR_SUB_CMD_NOT_FOUND_}
	;;
esac

#rm -f $lockfile

exit $err
