add muxa-vr

This commit is contained in:
Sebastian Kiesel 2023-03-31 01:22:50 +02:00
parent c8d97515dc
commit 0a19796698

331
bin/muxsa-vr Executable file
View File

@ -0,0 +1,331 @@
#!/bin/bash
# muxsa-vr (voice recorder)
#
# part of muxsa, https://git-nks-public.tik.uni-stuttgart.de/edu/muxsa
#
# this script waits for keystrokes, in particular the typical key sequences
# of a "wireless presenter" device, and controls audacity and geeqie, for
# convenient recording of voiceover for presentation slides.
# MIT License
#
# Copyright (c) 2023 Sebastian Kiesel <sebastian.kiesel@tik.uni-stuttgart.de>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
############################################################################
echo "This is muxsa-vr."
show_help () {
cat <<EOF
############################################################################
This is muxsa-vr. Enter one of the following keys.
NORMAL COMMANDS
i
initialize muxsa-vr and audacity (normally do it once after start)
PgDown (big right key on wireless presenter)
start or stop recording, respectively
PgUp (big left key on wireless presenter)
play clip that has been recorded most recently
. (dot, small right key on wireless presenter)
add a numbered label at current position
F5/ESC (small left key on wireless presenter)
delete most recent clip or label
SPECIAL-PURPOSE / RECOVERY COMMANDS
s = set state to STOP
l = manually enter current label number
c = manually enter current clip number
u = send undo to Audacity
r = send redo to Audacity
b = send back to Geeqie
n = send next to Geeqie
############################################################################
EOF
}
############################################################################
# interaction with audacity
# https://manual.audacityteam.org/man/scripting_reference.html
AUDACITY_PIPE_FROM="/tmp/audacity_script_pipe.from.$(id -u)"
AUDACITY_PIPE_TO="/tmp/audacity_script_pipe.to.$(id -u)"
send_to_audacity () {
if [ -p "${AUDACITY_PIPE_TO}" ] ; then
echo "muxsa-vr: send_to_audacity: $1"
echo "$1" > "${AUDACITY_PIPE_TO}"
else
echo "muxsa-vr: send_to_audacity: pipe ${AUDACITY_PIPE_TO}"\
"does not exist. not sending: $1"
fi
}
receive_from_audacity () {
while true ; do
if [ -p "${AUDACITY_PIPE_FROM}" ] ; then
timeout 10 sed 's/^/muxsa-vr: receive_from_audacity: /' \
${AUDACITY_PIPE_FROM}
else
echo "muxsa-vr: receive_from_audacity:"\
"pipe ${AUDACITY_PIPE_FROM} does not exist."\
"wait for one second"
sleep 1
fi
done
}
receive_from_audacity &
RECEIVE_FROM_AUDACITY_PID=$!
echo "muxsa-vr: receive_from_audacity subprocess started"\
"with PID: ${RECEIVE_FROM_AUDACITY_PID}"
trap 'kill "${RECEIVE_FROM_AUDACITY_PID}"' EXIT
#####
# LABEL is assumed to be a global variable holding an integer value
set_label_text_audacity () {
local L="${LABEL:-"0"}"
local T="$(printf "%04d" ${LABEL:-"0"})"
send_to_audacity "SetLabel: Label=${L} Selected=0 Text=\"${T}\""
}
############################################################################
# interation with geeqie
send_to_geeqie () {
echo "muxsa-vr: send_to_geeqie: $1"
case "$1" in
back)
geeqie --remote --back
;;
next)
geeqie --remote --next
;;
*)
echo "muxsa-vr: send_to_geeqie: ignore unknown command $1"
;;
esac
}
############################################################################
# main
STATE="uninitialized"
LABEL=0
CLIPS[0]=0
echo "muxsa-vr started. press i to initialize or h for help."
while true ; do
echo "State: ${STATE} Label: ${LABEL} Clips: ${CLIPS[$LABEL]:=0}"
##### read one key stroke, including some special keys
read -s -n1 -p "Press key (h for help): " KEYCODE
while read -t0.001 -s -n1 MORE ; do
KEYCODE="${KEYCODE}${MORE}"
done
case "${KEYCODE}" in
$'\e[6~')
KEYCODE="PGDOWN"
;;
$'\e[5~')
KEYCODE="PGUP"
;;
$'\e[15~')
KEYCODE="F5"
;;
$'\e')
KEYCODE="ESC"
;;
esac
#####
echo "muxsa-vr: key pressed: ${KEYCODE}"
case "${KEYCODE}" in
'h')
show_help
;;
'i')
echo "Initializing muxsa-vr and Audacity."
STATE="STOP"
LABEL=0
CLIPS[0]=0
send_to_audacity 'NewMonoTrack'
send_to_audacity 'NewLabelTrack'
send_to_audacity 'AddLabel'
set_label_text_audacity
send_to_audacity 'SelAllTracks'
;;
'PGDOWN')
# pgdown = right big button on the wireless presenter
case "${STATE}" in
'STOP')
send_to_audacity 'CursTrackEnd'
send_to_audacity 'Record1stChoice'
echo "START RECORDING"
STATE="RECORDING"
;;
'RECORDING')
send_to_audacity 'Stop'
send_to_audacity 'CursTrackEnd'
echo "STOP RECORDING"
STATE="STOP"
CLIPS[$LABEL]=$(( ${CLIPS[$LABEL]} + 1 ))
;;
*)
echo "start/stop: invalid state ${STATE} ... ignore"
;;
esac
;;
'PGUP')
# pgup = left big button on the wireless presenter
case "${STATE}" in
'STOP')
echo "Playback last clip"
send_to_audacity 'CursTrackEnd'
send_to_audacity 'CursPrevClipBoundary'
send_to_audacity 'Play'
send_to_audacity 'CursTrackEnd'
;;
*)
echo "playback: invalid state ${STATE} ... ignore"
;;
esac
;;
$'.')
# dot = right small button on the wireless presenter
case "${STATE}" in
'STOP')
if [ "${CLIPS[$LABEL]}" -eq 0 ] ; then
echo "Add label: not adding a second label here"
else
echo "Adding label at end while paused"
send_to_audacity 'CursTrackEnd'
send_to_audacity 'AddLabel'
LABEL=$(( ${LABEL} + 1 ))
CLIPS[$LABEL]=0
set_label_text_audacity
send_to_geeqie 'next'
fi
;;
'RECORDING')
send_to_audacity 'AddLabelPlaying'
echo "Adding label while recording"
LABEL=$(( ${LABEL} + 1 ))
CLIPS[$LABEL]=0
send_to_geeqie 'next'
;;
*)
echo "add label: invalid state ${STATE} ... ignore"
;;
esac
;;
'F5'|'ESC')
# F5/Esc(alternating) = left small button on the wireless presenter
case "${STATE}" in
'STOP')
case "${CLIPS[$LABEL]}" in
'0')
if [ "${LABEL}" -eq 0 ] ; then
echo "Delete: Nothing recorded ... ignore."
else
echo "Nothing recorded since last label."
echo "Deleting last label."
send_to_audacity 'CursTrackEnd'
send_to_audacity 'Delete'
send_to_geeqie 'back'
LABEL=$(( ${LABEL} - 1 ))
fi
;;
'1')
echo "Deleting first clip after label."
send_to_audacity 'CursTrackEnd'
send_to_audacity 'SelPrevClipBoundaryToCursor'
send_to_audacity 'Delete'
echo "Re-install deleted label"
send_to_audacity 'AddLabel'
set_label_text_audacity
CLIPS[$LABEL]=0
;;
*)
echo "Deleting second or later clip after label."
send_to_audacity 'CursTrackEnd'
send_to_audacity 'SelPrevClipBoundaryToCursor'
send_to_audacity 'Delete'
CLIPS[$LABEL]=$(( ${CLIPS[$LABEL]} - 1 ))
;;
esac
;;
*)
echo "Delete: invalid state ${STATE} ... ignore"
;;
esac
;;
's')
echo "Setting STATE to STOP"
STATE="STOP"
;;
'l')
read -p "Enter current label number: " LABEL
[ "${LABEL}" -gt 0 ] &>/dev/null || LABEL=0
;;
'c')
read -p "Enter current clip number: " CLIPS[$LABEL]
[ "${CLIPS[$LABEL]}" -gt 0 ] &>/dev/null || CLIPS[$LABEL]=0
;;
'u')
send_to_audacity 'Undo'
;;
'r')
send_to_audacity 'Redo'
;;
'b')
send_to_geeqie 'back'
;;
'n')
send_to_geeqie 'next'
;;
*)
echo "unknown key pressed: ${KEYCODE}"
;;
esac
done
# End of muxsa-vr
############################################################################