5

Is there any way to randomize the alert sound effect in Mac OS? In system prefs I am able to select which sound effect I want to hear. Is there a way for the system to choose a random sound each time?

2 Answers 2

3

This isn't built into macOS so this is something you are going to have to script and do a bit of customization. You will need the following:

  • Custom location for your sound
  • Script to randomize the sound
  • launchd plist to run the script at a set interval

Custom Location for Sound

System sounds are in the /System/Library/Sounds directory which I don't recommend attempting to modify. You can copy them to ~/Libary/Sounds or another custom directory of your choosing. This way, you can add your own custom sounds without interfering with the System sounds themselves.

Script to Randomize Soundfile

The script below will generate a random number between 0 and the number of files you have in your sound directory. It will then create an array of all the file names and then select a random filename (array element) which it will then copy that file to another file called CustomAlert.aif. You can customize the filename and path to suit your needs.

#!/bin/bash
#
# script filename:  randomAlert.sh

#User Defined Variables
  sdir="/Users/foobar/test"
  sfname="CustomAlert.aif"


#Remove Custom Alert Sound if already Exists

  if [ -f ${sdir}/${sfname} ]; then
    rm -f ${sdir}/${sfname}
  fi



#Get Number of Files in Directory
  numfiles=(*)
  numfiles=${#numfiles[@]}


#Generate Random Number
  rnum=$(( $RANDOM % ${numfiles}  + 0 ))


#Put names of files into array
  fnames=(*)

#Copy file to Alert Sound File
  cp ${sdir}/${fnames[${rnum}]} ${sdir}/${sfname}

exit

Make sure the script's permissions is set to allow execution:

chmod +x randomAlert.sh

Finally, make sure the script is in a "safe" location (a folder in your home directory is always a good place)

Launchd plist

To have the script run, you need to use the launchd service. The plist can go in any one of 3 locations:

  • ~/Library/LaunchAgents - For just one user, run as the user (i.e. yourself)
  • /Library/LaunchAgents - For all users, run as the user
  • /Library/LaunchDaemons - As a system daemon (run as root)

I recommend either of the first two; it doesn't make sense to run as a system daemon.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.user.randomSound</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/USERNAME/Path_to_Scripts/randomAlert.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <array>
    <dict>
        <key>Hour</key>
        <integer>00</integer>
        <key>Minute</key>
        <integer>00</integer>
    </dict>

</dict>
</plist>

Once you have copied it to the appropriate directory, you need to launch it with launchctl

launchctl load com.user.randomSound.plist

Set your Alert Sound to the Custom File

In your settings, set the alert to CustomAlert.aif. Even though the sound will change, the name of the file will stay the same.

That's it! Every 24 hours, your script will kick off and set a new random alert sound.

0

Bash and "Launchd plist" both sound very frightening to me...

So I came up with a solution that involves Python and a cron job instead. (Shout out to the answer above and this other one: Change default alert sound from terminal in Mac OSX)


I wrote a longer blog post explaining this in more details and using custom alert sounds: Randomizing the Alert Sound on a Mac

But here's the TLDR:

1- You can set the alert sound via the shell.

For instance, this:

defaults write .GlobalPreferences com.apple.sound.beep.sound /System/Library/Sounds/Sosumi.aiff

Sets "Sosumi" as your alert sound.

2- You can iterate over your sound files with Python and call the command from step 1.

#!/usr/bin/env python3
import subprocess, random, glob

sounds = glob.glob('/System/Library/Sounds/*.aiff')
sound = random.choice(sounds)
print('randomly selected sound: ', sound)
command = 'defaults write .GlobalPreferences com.apple.sound.beep.sound /System/Library/Sounds/{}.aiff'.format(sound)

# You could also define an array of sounds yourself,  
# if you don't want every .aiff file to be a possibility
# sounds=['sound1', 'sound2', 'sound3']
# sound=random.choice(sounds)
# command = 'defaults write .GlobalPreferences com.apple.sound.beep.sound /System/Library/Sounds/{}.aiff'.format(sound)

subprocess.call(command, shell=True)

3- You can call the Python script from step 2 with cron.

I use nano to edit my crontab file (but go ahead and use Vim or emacs if you're cool 😉).

env EDITOR=nano crontab -e

Assuming you named the script from step 2 "randomize.py", adapt the path and put this in your crontab file:

MAILTO=""
* * * * * python3 /Wherever/youWill/store/thisFile/randomize.py

Voilà! You now have a script that randomizes your alert sound every minute. I run it every hour now, so * * * * * became 59 * * * *.

1
  • I agree re bash - if it has more than 5 lines use a proper language but launchd is easy with a GUI like Launch Control
    – mmmmmm
    Sep 12, 2021 at 0:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .