Commit ac4c5f33 authored by Glen Mével's avatar Glen Mével

improve `bell`

parent a5edd869
......@@ -23,19 +23,14 @@ FREQUENCY=30s
# This script depends on the program “acpi”.
command -V acpi >/dev/null || return 1
# How to ring the bell.
# FIXME: This does not work (probably because not outputing to a terminal).
# Use paplay and some sounds from /usr/share/sounds/ instead.
bell() {
# This function rings the bell for the given duration.
# It relies on an external program being available, whose usage is as follows:
# bell $percent $pitch $duration
# I have one among my personal scripts.
# TODO: Fall back to paplay with some sounds from /usr/share/sounds/.
mybell() {
duration="$1"
# Save the bell settings.
settings=( $(xset -q | grep bell | grep -o '[0-9]*') )
# Set up the bell.
xset b 100 800 "$duration"
# Ring the bell.
echo -ne '\a'
# Restore the bell settings.
xset b "${settings[@]}"
command bell 100 800 "$duration"
}
state=3
......@@ -58,7 +53,7 @@ while true ; do
# Battery becomes low.
elif [ "$state" -gt 2 -a "$status" = 'Discharging' -a "$percentage" -le "$THRESHOLD_LOW" ] ; then
state=2
bell 100
mybell 100
notify-send -u critical -i battery-good-symbolic \
"Batterie à $percentage %" 'Je suis fatigué…'
normal_brightness="$(xbacklight)"
......@@ -67,7 +62,7 @@ while true ; do
# Battery becomes very low.
elif [ "$state" -gt 1 -a "$status" = 'Discharging' -a "$percentage" -le "$THRESHOLD_VERY_LOW" ] ; then
state=1
bell 250
mybell 250
# Note: notify-send is buggy, it picks the incorrect icon “battery-low”
# from /usr/share/notify-osd/icons/ instead of “battery-low-symbolic”
# from /usr/share/icons/.
......@@ -77,7 +72,7 @@ while true ; do
# Battery becomes critically low.
elif [ "$state" -gt 0 -a "$status" = 'Discharging' -a "$percentage" -le "$THRESHOLD_CRITICAL" ] ; then
state=0
bell 500
mybell 500
notify-send -u critical -i battery-caution-symbolic \
"Batterie à $percentage %" 'Je vais dormir.'
logger 'Battery critically low, going to sleep'
......
#!/bin/sh
#!/bin/bash
# Usage:
# bell [percent [pitch [duration]]]
# Rings the bell.
# Rings the bell. Tries its best, at least.
# Volume (in percents) to use when none is given and the bell is muted:
DEFAULT_VOLUME=50
# Default volume (in percents) with the X server method when the bell is muted:
X_DEFAULT_VOLUME=50
# This script depends on the program “xset”.
command -V xset >/dev/null || return 1
# Default frequency (in Hz) with the evdev method:
EVDEV_DEFAULT_PITCH=400
# Default duration (in milliseconds) with the evdev method:
EVDEV_DEFAULT_DURATION=100
# Evdev device representing the PC speaker:
EVDEV_DEVICE='/dev/input/by-path/platform-pcspkr-evet-spkr'
function is_integer() {
case "$1" in
......@@ -19,24 +25,68 @@ function is_integer() {
is_integer "$1" && is_integer "$2" && is_integer "$3" && [ "$#" -le 3 ] || {
echo>&2 'Bad argument'
exit 1
exit 2
}
declare -i percent="$1"
declare -i pitch="$2"
declare -i duration="$3"
# The X method.
function graphical_bell()
{
# Only try this method if the output is a graphical terminal and the program
# “xset” is available.
[ -t 1 -a -n "$DISPLAY" ] && command -v xset >/dev/null || return 1
# Save the bell settings.
declare -a settings; settings=( $(xset -q | grep bell | grep -o '[0-9]*') )
# Set up the bell.
[ "$percent" -eq 0 ] && percent="${settings[0]/#0/"$X_DEFAULT_VOLUME"}"
[ "$pitch" -eq 0 ] && pitch="${settings[1]}"
[ "$duration" -eq 0 ] && duration="${settings[2]}"
xset b "$percent" "$pitch" "$duration"
# Output the visual bell character.
echo -ne '\a'
# Restore the bell settings.
xset b "${settings[@]}"
}
percent="$1"
pitch="$2"
duration="$3"
# The evdev method.
# See https://unix.stackexchange.com/questions/531324
# Save the bell settings.
settings=( $(xset -q | grep bell | grep -o '[0-9]*') )
function evdev_bell()
{
# Only try this method if we can write to the evdev device for the PC speaker.
[ -c "$EVDEV_DEVICE" -a -w "$EVDEV_DEVICE" ] || return 1
# Set up the bell.
[ "$pitch" -eq 0 ] && pitch="$EVDEV_DEFAULT_PITCH"
[ "$duration" -eq 0 ] && duration="$EVDEV_DEFAULT_DURATION"
# Convert milliseconds to seconds.
declare sec=$( printf '%u.%03u' $(( duration / 1000 )) $(( duration % 1000 )) )
# Write the sound events.
{
evdev_set_pitch "$pitch" || return 1
sleep "$sec" || return 1
evdev_set_pitch 0 || return 1
} > "$EVDEV_DEVICE"
}
# Set up the bell.
: "${percent:="${settings[0]/#0/"$DEFAULT_VOLUME"}"}"
: "${pitch:="${settings[1]}"}"
: "${duration:="${settings[2]}"}"
xset b "$percent" "$pitch" "$duration"
function evdev_set_pitch()
{
perl -e 'print pack("qqssl", 0, 0, 0x12, 2, '$1')'
}
# Ring the bell.
echo -ne '\a'
# The console method.
function console_bell()
{
# Try to write \a to /dev/console.
[ -w /dev/console ] && echo -ne '\a' >> /dev/console
}
# Restore the bell settings.
xset b "${settings[@]}"
# Try all methods in order.
graphical_bell && exit
evdev_bell && exit
console_bell && exit
exit 1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment