i raise you
```
#!/bin/bash
# Toggle push-to-talk transcription. First run starts recording; second run
# stops, transcribes with whisper.cpp, and copies the text to the clipboard.
#
# Dependencies: arecord (alsa-utils), ffmpeg, whisper.cpp, dunstify (dunst),
# copyq. Adjust WHISPER_DIR / MODEL / clipboard command below to taste.
WHISPER_DIR="$HOME/ai/v2t/whisper.cpp"
MODEL="$WHISPER_DIR/models/ggml-base.en.bin"
AUDIO_FILE="/tmp/whisper_recording.wav"
PID_FILE="/tmp/whisper_record.pid"
LOCK_FILE="/tmp/whisper_record.lock"
notify() { dunstify -u "$1" "Whisper" "$2" -t "$3"; }
# Kill any leftover whisper-cli processes from previous runs
pkill -f "whisper-cli.*whisper_recording.wav" 2>/dev/null
# If a recording is in progress (PID file exists and the process is alive), stop it.
if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
# Prevent double-tap race: if already transcribing, bail out
if [ -f "$LOCK_FILE" ]; then
notify normal "Already processing..." 1500
exit 0
fi
touch "$LOCK_FILE"
PID=$(cat "$PID_FILE")
rm -f "$PID_FILE"
notify normal "Finishing recording..." 1500
# Keep recording briefly to capture trailing speech
sleep 1.5
# Stop arecord and wait for it to exit (force-kill if it hangs)
kill -INT "$PID" 2>/dev/null
for _ in $(seq 1 20); do
kill -0 "$PID" 2>/dev/null || break
sleep 0.1
done
kill -9 "$PID" 2>/dev/null
sleep 0.3
notify normal "Processing..." 5000
# Re-encode the wav: arecord may not finalize the header when killed
# from another shell, so rewrite it to a clean 16kHz mono file.
ffmpeg -y -i "$AUDIO_FILE" -ar 16000 -ac 1 -f wav "$AUDIO_FILE.fixed" 2>/dev/null
mv -f "$AUDIO_FILE.fixed" "$AUDIO_FILE"
if [ ! -s "$AUDIO_FILE" ]; then
notify critical "No audio recorded" 3000
rm -f "$AUDIO_FILE" "$LOCK_FILE"
exit 1
fi
cd "$WHISPER_DIR" || { rm -f "$LOCK_FILE"; exit 1; }
TEXT=$(./build/bin/whisper-cli -m "$MODEL" -f "$AUDIO_FILE" -nt -np 2>/dev/null | xargs)
if [ -n "$TEXT" ]; then
printf '%s' "$TEXT" | copyq copy -
notify normal "Copied to clipboard!" 2000
else
notify critical "No speech detected" 3000
fi
rm -f "$AUDIO_FILE" "$LOCK_FILE"
else
# Not recording: clean up any stale state and start a new recording.
rm -f "$PID_FILE" "$LOCK_FILE" "$AUDIO_FILE"
notify normal "Recording started... 🎤" 2000
arecord -f S16_LE -r 16000 -c 1 "$AUDIO_FILE" 2>/dev/null &
echo $! > "$PID_FILE"
fi
```
AND
```
#!/bin/bash
# Toggle live transcription with whisper.cpp's streaming mode. First run starts
# whisper-stream; second run stops it and copies the transcript to the clipboard.
#
# Dependencies: whisper.cpp (built with stream support), dunstify (dunst),
# copyq. Adjust WHISPER_DIR / MODEL / clipboard command below to taste.
WHISPER_DIR="$HOME/ai/v2t/whisper.cpp"
MODEL="$WHISPER_DIR/models/ggml-base.en.bin"
PID_FILE="/tmp/whisper_stream.pid"
TRANSCRIPT_FILE="/tmp/whisper_transcript.txt"
notify() { dunstify -u "$1" "Whisper" "$2" -t "$3"; }
# If a stream is running (PID file exists and the process is alive), stop it.
if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
PID=$(cat "$PID_FILE")
notify normal "Stopping recording..." 2000
# Let whisper finish processing the current audio chunk before stopping.
sleep 3
# SIGTERM first so the transcript is flushed, then force-kill if it hangs.
kill -TERM "$PID" 2>/dev/null
sleep 0.5
kill -9 "$PID" 2>/dev/null
sleep 0.2
# Pull just the text out of whisper-stream's "[timestamp] text" lines.
if [ -s "$TRANSCRIPT_FILE" ]; then
TEXT=$(grep -oP "\] +\K.*" "$TRANSCRIPT_FILE" | grep -v "^$" | tr '\n' ' ')
if [ -n "$TEXT" ]; then
printf '%s' "$TEXT" | copyq copy -
notify normal "Copied to clipboard!" 2000
else
notify critical "No speech detected" 3000
fi
else
notify critical "No transcript generated" 3000
fi
rm -f "$PID_FILE" "$TRANSCRIPT_FILE"
else
# Not recording: clean up any stale state and start a new stream.
rm -f "$PID_FILE" "$TRANSCRIPT_FILE"
cd "$WHISPER_DIR" || exit 1
notify normal "Recording started... 🎤" 2000
./build/bin/whisper-stream \
-m "$MODEL" \
-t 6 \
--step 0 \
--length 10000 \
-vth 0.75 \
--keep 0 \
-f "$TRANSCRIPT_FILE" \
>/dev/null 2>&1 &
echo $! > "$PID_FILE"
fi
```
❤️1