131 lines
2.8 KiB
Bash
Executable File
131 lines
2.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Capture a short stereo sample from the barepi mic path and print per-channel stats.
|
|
# Usage:
|
|
# ./test-mics.sh [seconds] [out.wav]
|
|
# ./test-mics.sh --thsel-high [seconds] [out.wav]
|
|
# ./test-mics.sh --thsel-low [seconds] [out.wav]
|
|
|
|
set -euo pipefail
|
|
|
|
RATE=48000
|
|
FORMAT=S32_LE
|
|
CHANNELS=2
|
|
DURATION=3
|
|
OUT=""
|
|
THSEL=""
|
|
CAPTURE_PCM="${CAPTURE_PCM:-barepi_capture}"
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage:
|
|
./test-mics.sh [seconds] [out.wav]
|
|
./test-mics.sh --thsel-high [seconds] [out.wav]
|
|
./test-mics.sh --thsel-low [seconds] [out.wav]
|
|
EOF
|
|
}
|
|
|
|
set_thsel() {
|
|
local level="$1"
|
|
command -v pinctrl >/dev/null 2>&1 || return 0
|
|
if [ "$level" = "high" ]; then
|
|
sudo pinctrl set 8 op pn dh >/dev/null
|
|
else
|
|
sudo pinctrl set 8 op pn dl >/dev/null
|
|
fi
|
|
}
|
|
|
|
prepare_wake_pin() {
|
|
command -v pinctrl >/dev/null 2>&1 || return 0
|
|
sudo pinctrl set 13 ip pn >/dev/null 2>&1 || true
|
|
}
|
|
|
|
show_pins() {
|
|
command -v pinctrl >/dev/null 2>&1 || return 0
|
|
sudo pinctrl get 8,13 || true
|
|
}
|
|
|
|
positional=()
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--thsel-high)
|
|
THSEL="high"
|
|
shift
|
|
;;
|
|
--thsel-low)
|
|
THSEL="low"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
positional+=("$1")
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ ${#positional[@]} -ge 1 ]; then
|
|
DURATION="${positional[0]}"
|
|
fi
|
|
if [ ${#positional[@]} -ge 2 ]; then
|
|
OUT="${positional[1]}"
|
|
fi
|
|
if [ -z "$OUT" ]; then
|
|
OUT="/tmp/barepi-mics-$(date +%Y%m%d-%H%M%S).wav"
|
|
fi
|
|
|
|
if ! arecord -L 2>/dev/null | grep -qx 'barepi_capture'; then
|
|
CAPTURE_PCM="plughw:CARD=barepiaudio,DEV=0"
|
|
fi
|
|
|
|
if [ -n "$THSEL" ]; then
|
|
set_thsel "$THSEL"
|
|
fi
|
|
prepare_wake_pin
|
|
show_pins
|
|
|
|
echo "Recording ${DURATION}s from ${CAPTURE_PCM} -> ${OUT}"
|
|
arecord -q -D "$CAPTURE_PCM" -f "$FORMAT" -c "$CHANNELS" -r "$RATE" -d "$DURATION" "$OUT"
|
|
|
|
python3 - <<'PY' "$OUT"
|
|
import math
|
|
import struct
|
|
import sys
|
|
import wave
|
|
|
|
path = sys.argv[1]
|
|
with wave.open(path, 'rb') as w:
|
|
channels = w.getnchannels()
|
|
width = w.getsampwidth()
|
|
rate = w.getframerate()
|
|
frames = w.getnframes()
|
|
data = w.readframes(frames)
|
|
|
|
if channels != 2 or width != 4:
|
|
print(f"Recorded {channels}ch / {width * 8}bit at {rate} Hz")
|
|
sys.exit(0)
|
|
|
|
samples = list(struct.iter_unpack('<ii', data))
|
|
left = [l for l, _ in samples]
|
|
right = [r for _, r in samples]
|
|
|
|
def rms(xs):
|
|
return math.sqrt(sum(x * x for x in xs) / len(xs)) if xs else 0.0
|
|
|
|
def peak(xs):
|
|
return max((abs(x) for x in xs), default=0)
|
|
|
|
l_rms = rms(left)
|
|
r_rms = rms(right)
|
|
l_peak = peak(left)
|
|
r_peak = peak(right)
|
|
full_scale = float(2**31 - 1)
|
|
|
|
print(f"Saved: {path}")
|
|
print(f"Rate: {rate} Hz Frames: {frames}")
|
|
print(f"Left : rms={int(l_rms):>10} peak={l_peak:>10} peak_dBFS={20*math.log10(max(l_peak,1)/full_scale):6.1f}")
|
|
print(f"Right: rms={int(r_rms):>10} peak={r_peak:>10} peak_dBFS={20*math.log10(max(r_peak,1)/full_scale):6.1f}")
|
|
PY
|