Skip to content

Commit 52c0560

Browse files
committed
fix: increase cooldown to 750ms, make all sounds reachable
- Cooldown 500ms → 750ms - Adjust escalation math so sustained max-rate slapping reaches the final file instead of asymptotically approaching it
1 parent b543ede commit 52c0560

2 files changed

Lines changed: 11 additions & 9 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ sudo launchctl unload /Library/LaunchDaemons/com.taigrr.spank.plist
186186
1. Reads raw accelerometer data directly via IOKit HID (Apple SPU sensor)
187187
2. Runs vibration detection (STA/LTA, CUSUM, kurtosis, peak/MAD)
188188
3. When a significant impact is detected, plays an embedded MP3 response
189-
4. 500ms cooldown between responses to prevent rapid-fire
189+
4. 750ms cooldown between responses to prevent rapid-fire
190190

191191
## Credits
192192

main.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const (
6666
decayHalfLife = 30.0
6767

6868
// slapCooldown prevents rapid-fire audio playback.
69-
slapCooldown = 500 * time.Millisecond
69+
slapCooldown = 750 * time.Millisecond
7070

7171
// sensorPollInterval is how often we check for new accelerometer data.
7272
sensorPollInterval = 10 * time.Millisecond
@@ -130,12 +130,13 @@ type slapTracker struct {
130130
}
131131

132132
func newSlapTracker(pack *soundPack) *slapTracker {
133-
// scale is derived so that the theoretical max steady-state score
134-
// (at peak slap rate with slapCooldown) maps to approximately the
135-
// second-to-last file, making the last file asymptotically unreachable.
133+
// scale maps the exponential curve so that sustained max-rate
134+
// slapping (one per cooldown) reaches the final file. At steady
135+
// state the score converges to ssMax; we set scale so that score
136+
// maps to the last index.
136137
cooldownSec := slapCooldown.Seconds()
137138
ssMax := 1.0 / (1.0 - math.Pow(0.5, cooldownSec/decayHalfLife))
138-
scale := (ssMax - 1) / math.Log(float64(len(pack.files)))
139+
scale := (ssMax - 1) / math.Log(float64(len(pack.files)+1))
139140
return &slapTracker{
140141
halfLife: decayHalfLife,
141142
scale: scale,
@@ -162,10 +163,11 @@ func (st *slapTracker) getFile(score float64) string {
162163
return st.pack.files[rand.Intn(len(st.pack.files))]
163164
}
164165

165-
// Escalation: 1-exp(-x) curve asymptotically approaches the top
166-
// without ever reaching it. Slap faster to climb; slow down to decay.
166+
// Escalation: 1-exp(-x) curve maps score to file index.
167+
// At sustained max slap rate, score reaches ssMax which maps
168+
// to the final file.
167169
maxIdx := len(st.pack.files) - 1
168-
idx := int(float64(maxIdx) * (1.0 - math.Exp(-(score-1)/st.scale)))
170+
idx := int(float64(len(st.pack.files)) * (1.0 - math.Exp(-(score-1)/st.scale)))
169171
if idx > maxIdx {
170172
idx = maxIdx
171173
}

0 commit comments

Comments
 (0)