# FreeSlapMac Silent

A silent build of [FreeSlapMac](https://freeslapmac.app) — same detection, same screen flash, same combo
counter, **no sound**. Plus the reason it needs to exist, which is a one-word answer: FreeSlapMac has no mute.

## Why this is necessary

The slap/tap sounds are not played by the app. They are MP3s in
`FreeSlapMac.app/Contents/Resources/Sounds/` played by the bundled `spank` process, and `spank` exposes no
volume or mute switch:

```
$ /Applications/FreeSlapMac.app/Contents/MacOS/spank --help
  --custom DIR  --min-amplitude F  --cooldown MS  --speed F  --volume-scaling
```

The app itself stores only `sensitivity`, `triggerMode`, `screenFlash`, `launchAtLogin` and
`_creakingEnabled` — no volume, no `soundEnabled`. So "turn the sound off" has no supported answer in 1.1.0.
This does not patch the app or hook its audio: it builds a *copy* whose entire sound library is digital
silence, so there is nothing to play. Detection and visuals never touch the audio path, so they keep working.

## Requirements

macOS. That's it. No python, no Homebrew, no ffmpeg — it uses `afinfo`, `afconvert`, `codesign`, `ditto`
and `PlistBuddy`, all of which ship with the OS. You do need FreeSlapMac installed, since the build starts
from your own copy (the app is not redistributed here).

## Build

```sh
bash build.sh
# → /Applications/FreeSlapMac Silent.app
```

Custom locations:

```sh
bash build.sh "/Applications/FreeSlapMac.app" "$HOME/Applications/FreeSlapMac Silent.app"
FORCE=1 bash build.sh          # replace an existing silent build
```

It copies the bundle, overwrites every MP3 with a hand-built silent MPEG frame of the same duration,
renames the copy so you can tell the two apart, re-signs it ad-hoc (the original is ad-hoc signed too) and
strips quarantine. ~270 files, about a minute.

## Verify it yourself

```sh
bash verify.sh
```

For each clip it decodes the file with macOS's own AudioToolbox — the same decoder `spank` uses — and asserts
the PCM contains no non-zero byte, that the duration still matches the original, that the signature is valid
and that the executable is byte-identical to the original (only the signature blob differs). Expected output:

```
== files ==
  original: 267 mp3   silent: 267 mp3
== decode check (AudioToolbox) ==
  decoded: 267   digitally silent: 267   audible: 0   duration mismatches: 0
== signature / identity ==
  signature: valid (ad-hoc)
  bundle id: com.devesh.freeslapmac (settings carry over)
  display name: FreeSlapMac Silent
  executable: identical code
PASS — every clip decodes to digital silence, signature valid, same code and settings.
```

Zero non-zero bytes is what silence means here. A trimmed file, a sped-up file or a "quiet" file would fail.

## Use

```sh
bash switch.sh silent    # quit the loud build, launch the silent one
bash switch.sh loud      # back to sound
```

One at a time only: both builds write `/tmp/freeslapmac_cmd` and each launch kills every `spank` it finds, so
two instances fight each other. First launch asks for your admin password once, exactly like the original —
`spank` needs it to read the accelerometer.

Settings are shared (same bundle id), so sensitivity, sound mode, cooldown and the lid-creak toggle carry over
untouched. If you want the silent build at login, remove "Open at Login" from the loud one first — login items
resolve by bundle id, and both builds share it.

## Uninstall

```sh
rm -rf "/Applications/FreeSlapMac Silent.app"
```

The original app is never modified.

## Notes

- **Lid creak is not covered.** If you use a lid-creak helper that plays its own audio (mine does), that sound
  does not come from this bundle; disable it in FreeSlapMac's own "Lid Creaking Sound" switch or in the helper.
- **Security, unrelated to this script:** FreeSlapMac starts a *root* wrapper that `eval`s whatever any local
  process writes to the world-writable FIFO `/tmp/freeslapmac_cmd`. While it runs, any user on the machine can
  get root. This build changes none of that — don't leave either build running on a shared or guest account,
  and it is worth reporting upstream.
- Not affiliated with FreeSlapMac. No third-party audio is redistributed: the silence is generated locally and
  the app itself is never shipped.

MIT — see LICENSE.
