head 1.1; access; symbols; locks; strict; comment @# @; 1.1 date 2001.02.04.16.28.12; author alexis; state Exp; branches; next ; desc @SOUND FILE PLAYER WITH SUPPORT FOR SLOW CONVERSION AND SLOW PLAYING @ 1.1 log @Initial revision @ text @#!MARKER_SHELL_CMD #shpp include ../bldcfg/paths.shpp #PATH=/bin:/usr/bin:/sbin:/usr/sbin RCS_ID='$Header: /home/ahuxley/dev/newstruct/lx/bin/RCS/lx.shpp,v 1.18 2000/05/31 10:54:57 ahuxley Exp ahuxley $' VERSION_SCHEME=rcs ############################################################################### # # # SLOW-CONVERSION/SLOW-PLAY SOUND FILE PLAYER # # # ############################################################################### ############################################################################### # # This is probably pretty useless outside ESO's restricted diskspace # environment. But it is useful as an example of a dual-threaded script # which slowly puts files into a queue and slowly takes them out, while # minimising waiting time. # # This is implemented in the backgrounded calls to queue() and dequeue() # made in the engine() function. # ############################################################################### ############################################################################### # # CONFIGURABLE STUFF # ############################################################################### MPG123_CMD=/home/ahuxley/bin/te16/mpg123 SOX_CMD=/home/ahuxley/bin/te16/sox SENDSOUND_CMD=/opt/audio/bin/send_sound OLD_ENWARE_HOST=te13 SEQNO_WIDTH=2 ############################################################################### # # END OF CONFIGURABLE STUFF # ############################################################################### QUEUE_DIR=$TMP_DIR/$PROGNAME.$$ MAXQLEN=3 usage() { { echo "Usage: $PROGNAME " } >&2 exit 1 } main() { while [ "X$1" != X ]; do case $1 in -V) echo "$PROGNAME version $VERSION" exit 0 ;; -v) VERBOSE_LEVEL=3 ;; -d) [ "X$$2" = X ] && usage VERBOSE_LEVEL=$2 shift ;; --) break ;; -*) usage ;; *) break ;; esac shift done [ "X$1" = X ] && usage UNAMEN=`uname -n` #{ [ $UNAMEN != $OLD_ENWARE_HOST ] && MODE=remote; } || MODE=local MODE=local info "performing sanity checks ..." [ ! -x $MPG123_CMD ] && error "can't locate $MPG123_CMD" [ ! -x $SOX_CMD ] && error "can't locate $SOX_CMD" [ ! -x $SENDSOUND_CMD ] && error "can't locate $SENDSOUND_CMD" [ "X$DISPLAY" = X ] && error "DISPLAY not set" [ "X$TMP_DIR" = X ] && error "you must set TMP_DIR to something under your home" expr "$TMP_DIR" : "$HOME/" > /dev/null || error "you must set TMP_DIR to something under your home" info "configuring for $MODE access ..." if [ $MODE = remote ]; then LOCAL_XTERM=`expr $DISPLAY : '\(.*\):0.0'` [ "X$LOCAL_XTERM" = X ] && internal "LOCAL_XTERM could not be calculated, please report this!" [ "X`remsh $OLD_ENWARE_HOST -n echo ok 2>/dev/null`" != Xok ] && error "remsh access to $OLD_ENWARE_HOST" fi info "starting queue processing engine ..." engine "$@@" } queue() { typeset FILE ID SEQNO FILE="$1" SEQNO=$2 SEQNO=`printf "%0${SEQNO_WIDTH}d" $SEQNO` BASE_FILE=`basename "$FILE"` case $BASE_FILE in *.mp2) SRC_FORMAT=mp2 BASENAME=`basename "$BASE_FILE" .mp2` ;; *.Mp3) SRC_FORMAT=mp3 BASENAME=`basename "$BASE_FILE" .Mp3` ;; *.mp3) SRC_FORMAT=mp3 BASENAME=`basename "$BASE_FILE" .mp3` ;; *.WAV) SRC_FORMAT=wav BASENAME=`basename "$BASE_FILE" .WAV` ;; *.wav) SRC_FORMAT=wav BASENAME=`basename "$BASE_FILE" .wav` ;; *.au) SRC_FORMAT=au BASENAME=`basename "$BASE_FILE" .au` ;; *) error "unrecognised format ($FILE)" ;; esac debug 5 "queue: queuing $BASE_FILE ..." case $SRC_FORMAT in mp3|mp2) DST_FORMAT=wav info "converting $BASE_FILE to $DST_FORMAT format ..." # mpg123 cannot write to a pipe, but can write to stdout (WAV rewind error) $MPG123_CMD -q -w - - < "$FILE" > "$QUEUE_DIR/$SEQNO.W.$DST_FORMAT" 2>/dev/null ;; wav) DST_FORMAT=au info "converting $BASE_FILE to $DST_FORMAT format ..." $SOX_CMD "$FILE" "$QUEUE_DIR/$SEQNO.W.$DST_FORMAT" ;; au) DST_FORMAT=au cp "$FILE" "$QUEUE_DIR/$SEQNO.W.$DST_FORMAT" ;; esac #debug 5 "queue: transferring $FILE to play host ..." #remsh $OLD_ENWARE_HOST ksh -c "\"cat > $QUEUE_DIR/$SEQNO.$W.$ID\"" < $QUEUE_DIR/W.local.$ID mv "$QUEUE_DIR/$SEQNO.W.$DST_FORMAT" "$QUEUE_DIR/$SEQNO.S.$DST_FORMAT" debug 5 "queue: $FILE has been queued" } dequeue() { typeset SEQNO RESTOFNAME SEQNO=$1 SEQNO=`printf "%0${SEQNO_WIDTH}d" $SEQNO` RESTOFNAME=`cd $QUEUE_DIR && expr $SEQNO.S.* : "$SEQNO.S.\(.*\)"` debug 5 "dequeuing $SEQNO.S.$RESTOFNAME ..." mv "$QUEUE_DIR/$SEQNO.S.$RESTOFNAME" "$QUEUE_DIR/$SEQNO.R.$RESTOFNAME" case $RESTOFNAME in *.wav) FORMAT=wav ;; *.au) FORMAT=au ;; esac case $FORMAT in wav) FORMAT_OPS=-wav ;; au) FORMAT_OPS= ;; esac info "playing $SEQNO.R.$RESTOFNAME ..." if [ $MODE = local ]; then debug 10 "dequeue: cmd=$SENDSOUND_CMD $FORMAT_OPS \"$QUEUE_DIR/$SEQNO.R.$RESTOFNAME\"" ls -ld "$QUEUE_DIR/$SEQNO.R.$RESTOFNAME" | debug -f - 100 $SENDSOUND_CMD $FORMAT_OPS "$QUEUE_DIR/$SEQNO.R.$RESTOFNAME" else #remsh $OLD_ENWARE_HOST -n ksh -c "\"DISPLAY=$DISPLAY; export DISPLAY; $SENDSOUND_CMD -server $LOCAL_XTERM $FORMAT_OPS $QUEUE_DIR/$SEQNO.R.$RESTOFNAME; rm -f $QUEUE_DIR/$SEQNO.R.$RESTOFNAME\"" internal "not recoded yet" fi rm -f "$QUEUE_DIR/$SEQNO.R.$RESTOFNAME" #mv "$QUEUE_DIR/$SEQNO.R.$RESTOFNAME" "$QUEUE_DIR/$SEQNO.O.$RESTOFNAME" debug 5 "dequeue: $SEQNO.R.$RESTOFNAME has been dequeued" } queuelen() { ls -1 $QUEUE_DIR | egrep -c "^[0-9][0-9]\.$1\." } jobstat() { typeset SEQNO STATUS SEQNO=$1 SEQNO=`printf "%0${SEQNO_WIDTH}d" $SEQNO` STATUS=`ls -1 $QUEUE_DIR | sed -n "s/^$SEQNO.\([RSW]\)\..*/\1/p"` STATUS=${STATUS:-N} echo $STATUS } queuestats() { { ls -1 $QUEUE_DIR } | info -f - } engine() { typeset ID FILE WRITE_SEQNO READ_SEQNO trap 'echo "$PROGNAME: WARNING: clearing up ... \\c" >&2; rm -fr $QUEUE_DIR; echo "done" >&2; exit 1' 1 2 15 mkdir -p $QUEUE_DIR WRITE_SEQNO=0 READ_SEQNO=0 while :; do #queuestats QLEN_ALL=`queuelen .` QLEN_STATIC=`queuelen S` QLEN_BEINGREAD=`queuelen R` QLEN_BEINGWRITTEN=`queuelen W` if [ $# != 0 -a $QLEN_ALL -lt $MAXQLEN ]; then FILE="$1" [ -r "$FILE" ] || error "$FILE: not accessible" shift queue "$FILE" $WRITE_SEQNO & # this is necessary or the queue appears empty in the next test WRITE_SEQNO=`expr $WRITE_SEQNO + 1` elif [ $QLEN_ALL = 0 ]; then debug 5 "engine: all queues are empty, presumably all done" break # this '&&' instead of '-a' stops second half being pointlessly evaluated elif [ $QLEN_BEINGREAD = 0 ] && [ `jobstat $READ_SEQNO` = S ]; then dequeue $READ_SEQNO & READ_SEQNO=`expr $READ_SEQNO + 1` fi sleep 1 done rm -fr $QUEUE_DIR } #shpp include ../lib/utils.sh.shpp #shpp include ../lib/gep.sh.shpp @