Overview
Spank detects physical impacts on your MacBook by reading the Apple Silicon accelerometer directly via IOKit HID and running vibration detection algorithms on the raw sensor data.Architecture
1. Accelerometer Access via IOKit HID
Spank uses the IOKit HID framework to read raw accelerometer data from the Apple Silicon System Performance Unit (SPU) sensor.- Sensor: Bosch BMI286 IMU (Inertial Measurement Unit)
- Interface: IOKit HID (Human Interface Device) API
- Access requirement: Root privileges (
sudo) are required to access IOKit HID devices
2. Shared Memory Ring Buffer
Accelerometer samples are written to a ring buffer in shared memory (shm.RingBuffer) for lock-free, high-performance data transfer between the sensor worker and detection logic.
- Polling interval: 10ms (100 Hz)
- Batch size: Up to 200 samples per tick to avoid falling behind
- Startup delay: 100ms to allow sensor to begin producing data
3. Vibration Detection Algorithm
Spank uses a multi-stage vibration detection pipeline to identify physical impacts. The detection is performed by thedetector.New() from the github.com/taigrr/apple-silicon-accelerometer/detector package.
Detection techniques include:
- STA/LTA (Short-Term Average / Long-Term Average): Compares recent signal amplitude to historical baseline to detect sudden changes
- CUSUM (Cumulative Sum): Detects sustained deviations from the mean
- Kurtosis: Measures the “tailedness” of the acceleration distribution to identify sharp spikes
- Peak/MAD (Peak / Median Absolute Deviation): Identifies outlier peaks in the signal
4. Event Filtering
After the detector generates vibration events, Spank applies additional filters:Amplitude Threshold
Only events exceeding the--min-amplitude threshold (default: 0.3g) trigger audio responses. This filters out minor vibrations from typing or desk movement.
Source: main.go:336-338
Cooldown Mechanism
A 750ms cooldown period prevents rapid-fire audio playback. If multiple slaps are detected within this window, only the first triggers a sound. Source: main.go:69, 333-335Deduplication
Events are deduplicated by timestamp to ensure the same physical impact doesn’t trigger multiple responses. Source: main.go:328-3315. Audio Playback
When a valid slap is detected, Spank selects and plays an MP3 audio file:Mode Behavior
- Pain mode (default): Random selection from 10 embedded pain audio clips
- Halo mode (
--halo): Random selection from embedded Halo death sounds - Custom mode (
--custom): Random selection from user-provided MP3 directory - Sexy mode (
--sexy): Escalation-based selection (see below)
Sexy Mode Escalation
Sexy mode uses an exponential decay scoring system to track slap intensity over time: Source: main.go:122-175- Decay half-life: 30 seconds (score halves every 30 seconds of inactivity)
- Escalation curve:
1 - exp(-(score-1)/scale)maps score to file index (0-59) - File selection: Higher scores select more intense audio files from the escalation sequence
6. Audio Decoding & Speaker
Spank uses the beep library for audio playback:- Format: MP3 (decoded on-the-fly)
- Embedded audio: Files are embedded in the binary using
//go:embeddirectives - Concurrency: Each slap spawns a goroutine for non-blocking playback
- Speaker initialization: Lazy initialization on first playback
Data Flow
Performance Characteristics
- Latency: Typically <100ms from physical impact to audio playback start
- CPU usage: Minimal (<1% on M2/M3 during idle monitoring)
- Memory footprint: ~10-15 MB (including embedded audio)
- Sensor sampling rate: Varies by hardware (typically 100-200 Hz)