#!/bin/sh

export LANG=C
export LC_ALL=C

trap 'bailout "interrupted"' INT QUIT KILL

usage(){
   echo "usage: vtsgram [options] [input] > imagefile" >&2
   echo "" >&2
   echo "options:" >&2
   echo " -t title   Title for the spectrogram" >&2
   echo "            (default is start timestamp)" >&2
   echo " -p pps     Pixels per second (default 100)" >&2
   echo " -s 'opts'  Extra options passed to Sox" >&2
   echo " -b bins    Number of frequency bins (variable default)" >&2
   exit 1
}

cleanup(){
   [ "$TMP" != "" ] && rm -f $TMP $TMP.png
}

bailout(){
   echo "vtsgram: $*" >&2
   cleanup
   exit 1
}

#
#  Check Sox is installed and has the spectrogram 'effect'.
#

t=$(sox --help 2> /dev/null | grep spectrogram)

[ $? -ne 0 ] && bailout "cannot run sox"
[ "$t" = "" ] && bailout "sox does not have the spectrogram effect"

TITLE=""
BINS=""    # Frequency bins, "" leaves it up to Sox
PPS=100    # Pixels per second
EXTRA=""

#
#  Parse options
#

OPTS=$(getopt -n vtsgram -o t:p:b:s:? -- "$@")
[ $? != 0 ] && usage

eval set -- "$OPTS"

while :
do
   case "$1" in

      -t) TITLE="$2" ; shift 2 ;;

      -p) PPS=$2 ; shift 2 ;;

      -b) BINS="-y $2" ; shift 2 ;;

      -s) EXTRA="$2" ; shift 2 ;;

      -\?) usage ;;

      --) shift ; break ;;

       *) bailout "getopt error" ;;
   esac
done

#
#  Input stream, if any, follows arguments
#

INPUT=""   # Defaults to stdin
[ $# -eq 1 ] && INPUT=$1
[ $# -gt 1 ] && usage

#
#  First run the input stream into a temp file so we can determine sample
#  rate and number of channels.
#

TMP=/tmp/vtsgram.$$
vtcat -- $INPUT > $TMP

[ $? != 0 ] && bailout "failed to read input stream"
[ ! -s $TMP ] && bailout "no data was found"

info=$(vtstat -i < $TMP | awk '{
   if( $1 == "channels:") nc = $2
   if( $2 == "rate:") rate = $3
   if( $1 == "duration:") duration = $2
   if( $1 == "start:") start = $2 " " $3
   }END{
      printf( "%d %d %.6f %s\n", nc, rate, duration, start);
   }')

eval set -- "$info"

NC=$1           # Number of channels
RATE=$2         # Sample rate
DUR=$3          # Duration
START="$4 $5"   # Start date and time

[ "$TITLE" = "" ] && TITLE="$START"

#
#  Run the stream through Sox
#

vtraw < $TMP 2> /dev/null | sox -t raw -e signed-integer -b16 -r$RATE -c$NC \
      - -n spectrogram -t "$TITLE" -X $PPS $BINS -c vtsgram \
     -d $DUR -o $TMP.png $EXTRA

[ $? -ne 0 ] && bailout "sox did not run properly"
[ ! -s $TMP.png ] && bailout "failed to produce a spectrogram"

cat $TMP.png

cleanup

