Background

If you grew up in the 90s you might remember “PC Speakers”, not to be confused with “computer speakers”, the ones that you plug into a 3.5mm jack and use to listen to things, and instead I mean those small built-in speakers that could play basic sounds, and with trickery even be used to play proper sounds as if it were a multimedia speaker.

Those “PC Speakers” still exist, although nowadays as a tiny moving-iron or piezo speaker. You might know them as those annoying beeping devices that emit a high-pitched beep on a BIOS/UEFI level error, when booting, or beep non-stop through an entire firmware upgrade (I’m looking at you, Lenovo).

People seem to find these just annoying, and on Ubuntu even, these speakers are blacklisted from working. And I can see why…

I have a little “NUC” computer (not from Intel!) which has a PC speaker built-in. It has a very annoying property, which is that it emits a pointless, high-pitched beep when it starts up (and it’s really loud). Moreover, if you boot without a display connected, it will again beep several times, pointlessly, to then proceed booting.

But there’s another side to those beeping devices!

I got that NUC to use as a router, with pfSense. If you don’t know, pfSense is a “router OS” that’s based on FreeBSD. What surprised me, is that pfSense plays a little tune through the PC speaker on each startup to signal that the system is ready. It also does play a little tune when it shuts down. And here’s the thing: The tune actually plays different notes, and it’s not as loud as the startup beep. I always thought those modern speakers are just on or off, without volume or tone control… I guess I was wrong!

I have since changed my network setup (yet again), and today I took that spare NUC and installed Ubuntu Server on it. I missed having a startup/shutdown tune, so I thought I’ll simply recreate it on Linux! Let’s do this!

Linux and pcspkr

On Linux, for these beeping devices to work, you need to load the kernel module called pcspkr:

sudo modprobe pcspkr

Then install the program “beep”, if it’s not already installed. On Ubuntu, you’d do this:

sudo apt install beep

Great, assuming you have beep installed, pcspkr loaded and have a working PC speaker, you can now do this (warning, will play sound):

beep -f880 -l500 -D 70 -n -f587.33 -l1000 -D 70 -n -f698.46 -l500 -D 70 -n -f880 -l500 -D 70 -n -f587.33 -l1000 -D 70 -n -f698.46 -l500 -D 70 -n -f880 -l250 -D 70 -n -f1046.50 -l250 -D 70 -n -f987.77 -l500 -D 70 -n -f783.99 -l500 -D 70 -n -f698.46 -l250 -D 70 -n -f783.99 -l250 -D 70 -n -f880 -l500 -D 70 -n -f587.33 -l500 -D 70 -n -f523.25 -l250 -D 70 -n -f659.26 -l250 -D 70 -n -f587.33 -l750

Recognized it? It’s “Song of Time” from the game “The Legend of Zelda”. If it didn’t play, you might have to try to run it as root (not sudo!) to have permission to “access” the speaker, or set up permissions so that any user may use the speaker. See “Troubleshooting” below.

Startup and Shutdown melody

I thought, for this tutorial, I’ll simply recreate the pfSense tune during startup/shutdown. If you look at the pfSense source, you will find that they too, use the program “beep”. However, the syntax doesn’t seem to be compatible with the version of beep on Ubuntu, so I adapted it to get an approximation:

Startup:

beep -f 500 -D 50 -l 200 -n -f 400 -D 50 -l 200 -n -f 600 -D 50 -l 200 -n -f 800 -D 50 -l 200 -n -f 800 -D 50 -l 200

Shutdown:

beep -f 600 -D 50 -l 200 -n -f 800 -D 50 -l 200 -n -f 500 -D 50 -l 200 -n -f 400 -D 50 -l 200 -n -f 400 -D 50 -l 200

Allowing and loading pcspkr at boot

As mentioned before, Ubuntu does blacklist the pcspkr kernel module so we have to do two things:

  1. Remove pcspkr from the blacklist.
  2. Add pcspkr to the list of kernel modules to load at boot.

First we remove pcspkr from the blacklist by editing /etc/modprobe.d/blacklist.conf:

sudo nano /etc/modprobe.d/blacklist.conf

Find the line that says “blacklist pcspkr” and comment it out by adding a # in front of it. Hit CTRL+S to save, CTRL+X to exit.

Now create the file /etc/modules-load.d/beep.conf:

sudo nano /etc/modules-load.d/beep.conf

With the following contents:

# For the command "beep" to work (requires a "PC speaker")
pcspkr

Again, CTRL+S and CTRL+X.

Making it play the melody on startup/shutdown

Now that we tested that beep works, and set the module pcspkr to load on boot, we can create a systemd service file (no this is not from pfSense) to play a melody on startup and shutdown!

Create the file: /etc/systemd/system/beep.service:

sudo nano /etc/systemd/system/beep.service

With the following contents:

[Unit]
Description=Startup-Shutdown-Beeps
After=basic.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/beep -f 500 -D 50 -l 200 -n -f 400 -D 50 -l 200 -n -f 600 -D 50 -l 200 -n -f 800 -D 50 -l 200 -n -f 800 -D 50 -l 200
ExecStop=/usr/bin/beep -f 600 -D 50 -l 200 -n -f 800 -D 50 -l 200 -n -f 500 -D 50 -l 200 -n -f 400 -D 50 -l 200 -n -f 400 -D 50 -l 200

[Install]
WantedBy=multi-user.target

Again, CTRL+S and CTRL+X to save and exit.

Now enable the service with:

sudo systemctl enable beep

Now, to test that it works without restarting:

sudo systemctl start beep
sudo systemctl stop beep
sudo systemctl start beep

If it played the correct tune on start, and on stop, we know it works! You can now reboot to do a real-world test! Warning, the following command will reboot:

sudo systemctl reboot

That’s all there is to it!

Troubleshooting

Module

If it doesn’t work for you, verify that the kernel module pcspkr is loaded on next boot with:

lsmod | grep pcspkr

If this command returns nothing (empty line), that means it did not load the necessary kernel module. Make sure it’s not blacklisted anywhere else!

Permissions

Make sure that beep runs as root (not sudo!) or set up permissions so that any user may use beep (thanks to ArchWiki for this udev rule):

Create the file /etc/udev/rules.d/70-pcspkr-beep.rules with the following contents:

ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="PC Speaker", ENV{DEVNAME}!="", TAG+="uaccess"

And then reload permissions:

sudo udevadm control --reload && sudo rmmod pcspkr && sudo modprobe pcspkr

Bonus

Here’s a bonus tune, for which I won’t reveal what it plays, but I’m sure you’ll recognize it once you try!

beep -l 350 -f 392 -D 100 -n -l 350 -f 392 -D 100 -n -l 350 -f 392 -D 100 -n -l 250 -f 311.1 -D 100 -n -l 25 -f 466.2 -D 100 -n -l 350 -f 392 -D 100 -n -l 250 -f 311.1 -D 100 -n -l 25 -f 466.2 -D 100 -n -l 700 -f 392 -D 100 -n -l 350 -f 587.32 -D 100 -n -l 350 -f 587.32 -D 100 -n -l 350 -f 587.32 -D 100 -n -l 250 -f 622.26 -D 100 -n -l 25 -f 466.2 -D 100 -n -l 350 -f 369.99 -D 100 -n -l 250 -f 311.1 -D 100 -n -l 25 -f 466.2 -D 100 -n -l 700 -f 392 -D 100 -n -l 350 -f 784 -D 100 -n -l 250 -f 392 -D 100 -n -l 25 -f 392 -D 100 -n -l 350 -f 784 -D 100 -n -l 250 -f 739.98 -D 100 -n -l 25 -f 698.46 -D 100 -n -l 25 -f 659.26 -D 100 -n -l 25 -f 622.26 -D 100 -n -l 50 -f 659.26 -D 400 -n -l 25 -f 415.3 -D 200 -n -l 350 -f 554.36 -D 100 -n -l 250 -f 523.25 -D 100 -n -l 25 -f 493.88 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 25 -f 440 -D 100 -n -l 50 -f 466.16 -D 400 -n -l 25 -f 311.13 -D 200 -n -l 350 -f 369.99 -D 100 -n -l 250 -f 311.13 -D 100 -n -l 25 -f 392 -D 100 -n -l 350 -f 466.16 -D 100 -n -l 250 -f 392 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 700 -f 587.32 -D 100 -n -l 350 -f 784 -D 100 -n -l 250 -f 392 -D 100 -n -l 25 -f 392 -D 100 -n -l 350 -f 784 -D 100 -n -l 250 -f 739.98 -D 100 -n -l 25 -f 698.46 -D 100 -n -l 25 -f 659.26 -D 100 -n -l 25 -f 622.26 -D 100 -n -l 50 -f 659.26 -D 400 -n -l 25 -f 415.3 -D 200 -n -l 350 -f 554.36 -D 100 -n -l 250 -f 523.25 -D 100 -n -l 25 -f 493.88 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 25 -f 440 -D 100 -n -l 50 -f 466.16 -D 400 -n -l 25 -f 311.13 -D 200 -n -l 350 -f 392 -D 100 -n -l 250 -f 311.13 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 300 -f 392.00 -D 150 -n -l 250 -f 311.13 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 700 -f 392

Have fun!

PS Who needs 7.1 surround sound when you can have 1.0 beeps? ;D