Created
November 9, 2025 06:41
-
-
Save IngwiePhoenix/1145643124aac0ad97041d2dac364350 to your computer and use it in GitHub Desktop.
freebsd-beep
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # @author ChatGPT, Ingwie Phoenix | |
| # | |
| # @file | |
| # Hacked, AI generated, shitty wrapper around freebsd's beep. | |
| # I wanted my firewall to beep Bad Apple at me - this script dpes that. | |
| # The scale that worked for me was 0.1 so I recommend you do: | |
| # echo 0.1 > /usr/local/etc/beep-scale | |
| # And then use a repo with some lovely beep scripts! | |
| # | |
| # Technically, this script could also translate to the melody files used | |
| # for startup/shutdown - but I haven't gone that far yet. Besides, I actually | |
| # don't know how to persist them between FW upgrades o.o... | |
| # So for now, this is just for the lulz. | |
| # | |
| # Enjoy. | |
| # Usage: | |
| # ./bsd-beep.sh path/to/script/calling/beep.sh | |
| # Notes: | |
| # - Requires python3 for automatic calibration (measuring time precisely). If not present, | |
| # you can set BEEP_MS_SCALE manually (see below). | |
| # - Because the BSD beep uses atoi, this function ensures the passed duration is an integer. | |
| # - The script persists calibration at /usr/local/etc/beep-scale | |
| # Notes 2: | |
| # Prepend `beep --calibrate` to make the script attempt to calibrate itself. | |
| # Untested - I just fucked around and found out. >.>... | |
| SCALE_FILE=/usr/local/etc/beep-scale | |
| : "${BEEP_MS_SCALE:=$( [ -r "$SCALE_FILE" ] && cat "$SCALE_FILE" 2>/dev/null || echo 1.0 )}" | |
| _translate_ms_to_driver_units() { | |
| # $1 = requested_ms (Linux-style) | |
| # multiply by BEEP_MS_SCALE and round to nearest integer (ensure >=1) | |
| local req_ms=$1 | |
| local scaled | |
| scaled=$(awk "BEGIN{printf \"%d\", ($req_ms * $BEEP_MS_SCALE) + 0.5}") | |
| if [ "$scaled" -lt 1 ]; then scaled=1; fi | |
| printf "%d" "$scaled" | |
| } | |
| _calibrate_driver() { | |
| # Play a reference tone and measure real wall time. | |
| # The measured time is used to compute BEEP_MS_SCALE such that: | |
| # driver_units = round(requested_ms * BEEP_MS_SCALE) | |
| # i.e. BEEP_MS_SCALE = driver_units_needed / requested_ms | |
| # We measure requested_ms / measured_ms to obtain scale mapping Linux-ms -> driver units. | |
| local ref_req_ms=1000 # 1 second reference tone | |
| if ! command -v python3 >/dev/null 2>&1; then | |
| echo "Calibration needs python3. Install python3 or set BEEP_MS_SCALE manually." | |
| return 1 | |
| fi | |
| echo "Calibrating: playing ${ref_req_ms} ms tone, measuring actual elapsed time..." | |
| # call python to measure wall-clock time around beep call | |
| local measured_ms | |
| measured_ms=$(python3 - <<PY | |
| import time, subprocess, sys | |
| req = ${ref_req_ms} | |
| start = time.time() | |
| subprocess.call(["/usr/local/bin/beep","-p","1000",str(req)]) | |
| end = time.time() | |
| ms = (end - start) * 1000.0 | |
| print(int(ms + 0.5)) | |
| PY | |
| ) | |
| if [ -z "$measured_ms" ]; then | |
| echo "Calibration failed: no measurement." | |
| return 1 | |
| fi | |
| if [ "$measured_ms" -le 0 ]; then | |
| echo "Calibration failed: measured non-positive time: $measured_ms" | |
| return 1 | |
| fi | |
| # If the beep program consumes its argument as "driver-units" and those driver-units | |
| # correspond to X ms in the real world, then: | |
| # driver_units_needed_for_req = req_ms * (driver_units_per_ms) | |
| # We want BEEP_MS_SCALE such that driver_units = round(req_ms * BEEP_MS_SCALE) | |
| # Measured_ms is the real-world time we observed when we asked for req_ms. | |
| # So BEEP_MS_SCALE = req_ms / measured_ms * (driver interpretation) | |
| # Simplify: we will set BEEP_MS_SCALE = req_ms / measured_ms | |
| # (this works as a practical correction factor: if measured_ms < req_ms, scale > 1) | |
| local new_scale | |
| new_scale=$(awk "BEGIN{printf \"%.6f\", ${ref_req_ms} / ${measured_ms}}") | |
| if [ -z "$new_scale" ]; then | |
| echo "Calibration arithmetic failed." | |
| return 1 | |
| fi | |
| echo "$new_scale" > "$SCALE_FILE" || { echo "Failed to write $SCALE_FILE"; return 1; } | |
| export BEEP_MS_SCALE="$new_scale" | |
| echo "Calibration complete: measured ${measured_ms} ms for requested ${ref_req_ms} ms." | |
| echo "Wrote BEEP_MS_SCALE=${BEEP_MS_SCALE} to $SCALE_FILE" | |
| return 0 | |
| } | |
| beep() { | |
| local default_gap_ms=50 | |
| local freq="" len="" gap_ms="$default_gap_ms" immediate=false | |
| # parsing | |
| while [ $# -gt 0 ]; do | |
| case "$1" in | |
| --calibrate) _calibrate_driver; return $? ;; | |
| -f) freq="$2"; shift 2 ;; | |
| -f?*) freq="${1#-f}"; shift ;; | |
| -l) len="$2"; shift 2 ;; | |
| -l?*) len="${1#-l}"; shift ;; | |
| -D) gap_ms="$2"; shift 2 ;; | |
| -D?*) gap_ms="${1#-D}"; shift ;; | |
| -n) immediate=true; shift ;; | |
| --) shift; break ;; | |
| *) shift ;; | |
| esac | |
| if [ -n "$freq" ] && [ -n "$len" ]; then | |
| # convert len (ms) -> driver units (integer), because beep uses atoi | |
| driver_len=$(_translate_ms_to_driver_units "$len") | |
| /usr/local/bin/beep -p "$freq" "$driver_len" | |
| if [ "$immediate" = false ]; then | |
| # sleep gap in seconds | |
| awk "BEGIN{printf \"%.3f\", $gap_ms/1000}" | read gap_sec | |
| # portable sleep with fractional seconds: | |
| sleep "$(awk "BEGIN{printf \"%.3f\", $gap_ms/1000}")" | |
| fi | |
| freq="" len="" immediate=false gap_ms="$default_gap_ms" | |
| fi | |
| done | |
| } | |
| # Poor man's wrapper. Hey, it works. | |
| . $1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment