One of the most satisfying sounds for us, programmers, to hear is a keyboard sound. Apart from the underlying switch mechanism, a keyboard’s sound is beauty itself. In this tutorial, we will build a fairly small Keyboard Sound Simulator using Python. The program will play a random sound from a collection of your choice every time you press a key.
First of all, we need to install a couple of packages and Python modules. We need
sox package to play sounds and
python-xlib package for
pyxhook to work properly. Use the package manager of your system to install these packages. For example:
- On Ubuntu:
sudo apt install sox python-xlib
- On Arch:
sudo pacman -S sox python-xlib
We also need
pyxhook Python module, so
pip install pyxhook. Now we are good to go.
First, let’s create a file and name it
kb_sound_simulator.py. Then, let’s import the modules we are going to use.
A Little Pause
Before we continue, here is how the program will go. A path to a directory containing sounds we want to play will be provided to the program. The program will go through the files in that directory looking for at least one file with sound for each of
space, and other keys. Then on any keypress, the program will play the corresponding sound. Pretty easy, isn’t it?
Getting Paths for Sound Files
So, as discussed, we need to get paths for sound files.
We define some variables to store paths for sound files later if found. We get a list of files in the provided directory on line 6. On lines 8-10, we define Regular Expressions (RegEx) to use later to match file names we are expecting. On line 8, we define a Regex that matches a string that starts with the word
enter, followed by a dot
., and ending with either
wav. The same goes for line 9, but for the word
space. And same goes for line 10, but instead of matching a string starting with
space, we match a string starting with any one or more characters (.+). Then we loop through the filenames list, check for matches with any of the RegExes, and assign matched filenames to the corresponding variable. For example, on line 13, we match the
enter_re Regex against the filename, and if the result is
not None, meaning there is a match, we store that filename in the
enter_path variable. In the end, if we don’t find any of the required files, we print an error message and exit.
Handling Key Presses
To handle key presses, we will first define a function to handle pressing a key down. This function takes in an
event object which, lucky for us, contains the name of the key that was pressed. So, on lines 9-15 we assign the file path corresponding to the key pressed, in case of
space, or a random file path from the
others_paths array, in case of any other key, to the
sound variable. Now, this is a tricky part. On lines 1and 2, we declared 2 variables,
last_key. These variables are meant to help us fix issues that appear as keys are held down. So, on lines 17-20, we make sure that we are either not in continuous mode or the current key is different from the last one. This helps avoid replaying key sound when the same key is pressed down and held without interruption. Then, we set the last key to be the current one, play the sound using the
os.system() function to execute a shell command, and set continuous to
True to indicate that the key is not yet released.
NOTE: We pass the sound file path as the first argument to the play command.
Hooking Everything Up
Now, we need to actually initiate a hook manager and attach a keyboard hook, so that the program can listen to key presses.
We started the hook manager on line 1, assigned the
KeyUp callback handlers on lines 2 and 3, attached the keyboard hook on line 4, and started the hook manager on line 6. And that’s it. We are done!
First, we used
regular expressions and
os module and its helper functions to look for the files we needed. Then, we used
os.system() along with the
play shell command to play sounds. Finally, we used
pyhook module to listen for and act upon keyboard events. Now, this program is complete, but it lacks somethings, for example, we can add a command-line option to control the volume of the played sounds. We may then add a help message to make it easier to use. To learn how to do this, you can read Getting Started with Python’s Argparse.
NOTE: The source code for this tutorial can be found here.