Skip to main content
Spank supports loading custom MP3 audio files from a directory on your system using the --custom flag. This allows you to personalize your laptop’s responses with any sounds you want.

Usage

sudo spank --custom /path/to/your/mp3s
The --custom, --sexy, and --halo flags are mutually exclusive. You can only use one mode at a time.

How It Works

When you specify a custom directory:
  1. Spank scans the directory for all files (non-directories)
  2. Files are sorted alphabetically and loaded into memory
  3. When a slap is detected, a random MP3 file is selected and played
  4. Custom mode uses random playback (not escalation mode)
Relevant code from main.go:91-119:
func (sp *soundPack) loadFiles() error {
    if sp.custom {
        entries, err := os.ReadDir(sp.dir)
        if err != nil {
            return err
        }
        sp.files = make([]string, 0, len(entries))
        for _, entry := range entries {
            if !entry.IsDir() {
                sp.files = append(sp.files, sp.dir+"/"+entry.Name())
            }
        }
    }
    // ... files sorted alphabetically
}

File Requirements

1

Use MP3 format

All audio files must be in MP3 format. Spank uses the beep library’s mp3.Decode() function to decode audio files.Other formats (WAV, FLAC, OGG, etc.) are not supported and will cause decode errors.
2

Create a directory

Place all your MP3 files in a single directory:
mkdir ~/my-spank-sounds
cp sound1.mp3 sound2.mp3 sound3.mp3 ~/my-spank-sounds/
3

Run with --custom flag

Point Spank to your directory:
sudo spank --custom ~/my-spank-sounds

Directory Structure

Your custom audio directory should look like this:
/path/to/custom/audio/
├── sound1.mp3
├── sound2.mp3
├── sound3.mp3
└── another-sound.mp3
  • Files are read from the top level of the directory only (subdirectories are ignored)
  • File names don’t matter; they’re just sorted alphabetically internally
  • You need at least one MP3 file in the directory, or you’ll get an error: “no audio files found”

Examples

Basic Custom Audio

# Use custom sounds from your Downloads folder
sudo spank --custom ~/Downloads/spank-sounds

Custom Audio with Sensitivity Adjustment

# More sensitive detection with custom sounds
sudo spank --custom /Users/you/my-sounds --min-amplitude 0.15

# Less sensitive (only strong slaps)
sudo spank --custom /Users/you/my-sounds --min-amplitude 0.4

Creating Your Own Sound Pack

# Create a themed sound pack
mkdir ~/spank-pokemon
cp pikachu.mp3 charmander.mp3 squirtle.mp3 ~/spank-pokemon/
sudo spank --custom ~/spank-pokemon

Playback Behavior

Custom mode uses random playback:
  • Each slap randomly selects one of your MP3 files
  • All files have equal probability of being played
  • No escalation (unlike --sexy mode)
From main.go:161-164:
func (st *slapTracker) getFile(score float64) string {
    if st.pack.mode == modeRandom {
        return st.pack.files[rand.Intn(len(st.pack.files))]
    }
    // ...
}

Technical Details

Audio Decoding

Spank uses the beep library for audio playback. Custom files are decoded using:
// From main.go:354-365
file, err := os.Open(path)
streamer, format, err = mp3.Decode(file)

Embedded vs. Custom Audio

The built-in modes (pain, sexy, halo) use go:embed to bundle MP3s directly into the binary:
//go:embed audio/pain/*.mp3
var painAudio embed.FS
Custom mode reads files from the filesystem at runtime using os.Open(), so your files stay on disk and aren’t compiled into the binary.

Troubleshooting

This means the directory is empty or contains only subdirectories.Solution: Ensure you have at least one .mp3 file in the top level of the directory.
ls /path/to/your/directory/*.mp3
The file may be corrupted or not a valid MP3.Solution: Re-encode your audio files to MP3:
ffmpeg -i input.wav -codec:a libmp3lame -qscale:a 2 output.mp3
The audio may be decoding but speaker initialization failed.Solution: Check that:
  • Your system audio is not muted
  • The MP3 files are valid
  • You have proper permissions to access audio devices

Next Steps

Troubleshooting

Common issues and solutions

Sensitivity Tuning

Adjust detection sensitivity

Build docs developers (and LLMs) love