How to Build a Keyboard Sound Simulator in Python for Linux

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.

Prerequisites

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.

Coding Time

First, let’s create a file and name it kb_sound_simulator.py. Then, let’s import the modules we are going to use.

Import libraries that will be used - keyboard sound simulator in python

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 enter, 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.

Searching through files in provided directory for sounds to play on key - keyboard sound simulator in python

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 mp3 or 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 enter or 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

Callback handlers for pressing a key and releasing it - keyboard sound simulator in python

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 enter, or 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, continuous and 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.

Initiating hook manager and attaching a keyboard hook

We started the hook manager on line 1, assigned the KeyDown and 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!

Conclusion

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.

4
2

Related Posts