Klack - A mechanical keyboard sound simulator

klack-logo

klack is a lightweight, zero-configuration mechanical keyboard sound simulator for Linux. It runs seamlessly in the background, listens directly to your selected input devices, and is designed to be easily managed as a standard systemd user service.

The application is completely agnostic to the host windowing system or compositor, so will work the same whether you are on Wayland, X11, or running in a bare TTY.

This project started as a quick afternoon project after trying out Opera GX, and liking the typing sounds feature it includes. My original intent was just to implement it for fun as a personal project, but I decided others may find use for it, so cleaned it up and turned it into a proper application.

https://codeberg.org/ForeverZer0/klack


Installation

Ensure you have Zig >= 0.16.0 installed. Clone the repository and build using your preferred release configuration:

git clone ssh://git@codeberg.org/ForeverZer0/klack.git
cd klack
zig build -Doptimize=ReleaseFast

The compiled binary will be available at zig-out/bin/klack.

Arch Linux

klack is provided as an AUR package of the same name. You can use your preferred AUR helper, such as yay, paru, etc, to install it.

yay -S klack

This also installs the systemd units automatically and shell completions for zsh, bash, and fish. To configure any desired options when using the service, the environment variables can be used. Thesse can be defined in a new $HOME/.config/environment.d/10-klack.conf so that systemd picks them up without relying upon initializing scripts of your WM/DE.

# $HOME/.config/environment.d/10-klack.conf
KLACK_SOUNDPACK="$HOME/.config/klack/mechanical"
KLACK_EXCLUDE="modifier_keys"
KLACK_VOLUME="0.8"

Usage

klack - A mechanical keyboard sound simulator

USAGE:
    klack [OPTIONS]

OPTIONS:
    -s, --soundpack <PATH>       Path to a directory or .tar.gz archive containing sounds
    -d, --device <PATH>          Target device path or name (default: primary keyboard)
    -v, --volume <VOLUME>        Volume scaling from 0.0 to 1.0 (default: 1.0)
    -r, --repeat                 Enable sound playback on key repeat events
    -b, --background             Run the process in the background (daemonize)
        --list-devices           List available input devices and exit
        --list-keys              List valid key names for custom sounds
        --list-buttons           List valid button names for custom sounds
        --list-groups            List valid tokens that define logical groups of keys/buttons
    -a, --alsa-device <NAME>     The backend device used by ALSA (default: "default")
    -e, --exclude <TOKEN>[,...]  Comma-separated list of key/buttons/groups to exclude
        --max-voices <COUNT>     Number of simultaneous effects that can play (1-16)(default: 4)
    -h, --help                   Print this help message and exit

EXAMPLES:
    klack --soundpack ~/.config/klack/mx-blues.tar.gz --background
    klack -s ./sounds/custom/ -v 0.7 --repeat
    klack --list-devices
    klack --device "AT Translated Set 2 keyboard"
    klack --d platform-i8042-serio-0-event-kbd 
    klack --exclude modifier_keys,key_esc

Quick Examples

Run manually in the foreground with a specific sound archive:

klack --soundpack ~/.config/klack/typewriter.tar.gz

Run in the background with a lower volume and key-repeat sounds enabled:

klack -s ./sounds/custom/ -v 0.7 --repeat --background

Environment Variables

The following environment variables may also be used to provide default configuration for options not specified on the command-line, which always have precedence.

  • KLACK_SOUNDPACK
  • KLACK_DEVICE
  • KLACK_VOLUME
  • KLACK_REPEAT
  • KLACK_ALSA_DEVICE
  • KLACK_EXCLUDE
  • KLACK_MAX_VOICES

LLM/AI Usage

  • No LLM or AI was used for any code within this project, and never will.
  • Google Gemini was used to generate the logo. Full credit goes to all the unnamed artists who had their work used for its training data.

Supported Zig versions

Zig 0.16+

Tested on the following:

  • 0.16.0
  • 0.17.0-dev.1397+4331ba0fb
25 Likes

Finally, some good fucking software.

6 Likes

Really cool, love it! :musical_note:

Edit: Trying to compile it, the compiler threw an error saying libasound is missing. On my distro this lib is called alsa-lib-devel and I had to search a little bit before figuring this out, just in case someone else faces a similar error…

1 Like

This is awesome, I love it! Too often we get caught up in the grind of trying to build something useful instead of building something fun.

I did have a minor issue with getting it to work on my setup. First I was missing pipewire-alsa (Arch Linux[1]). Second seemed to be an issue with how my keyboard shows up in Linux: it reports both a keyboard and mouse interface. I’ve documented this issue and proposed a fix, but it’s not perfect so I didn’t create a PR for it.


  1. btw ā†©ļøŽ

2 Likes

I really should mention it uses ALSA. It was an oversight of mind to assume that just because ALSA is part of the kernel that everyone would have their systems configured for it, as in the real world we all interact with pipewire and additional layers built on top of it.

Fellow Archbro!

Thank you, I will have some free time today, so hopefully get a fix out before tomorrow.

2 Likes

Thank you both for the kind words :smiley:

Debian-based? I will need to mention the ALSA requirement so that users know to ensure they have the proper setup for their systems.

1 Like

haha this is pretty cool! i’ll definitely have to play around with it later
starred this puppy!

1 Like

This should be fixed now. The resolved event node is used to determine duplicates, so no more false positives for multi-capability devices. They can be differentiated by specifying the device name/path instead of the display name.

klack --list-devices
platform-AMDI0010:03-event-mouse (ELAN07FB:00 04F3:321A Touchpad)
pci-0000:08:00.4-usb-0:1:1.2-event-mouse (Logitech G502)
platform-i8042-serio-0-event-kbd (AT Translated Set 2 keyboard)

# Both of the following work
klack --device platform-i8042-serio-0-event-kbd
klack --device "AT Translated Set 2 keyboard"

I also created AUR package for Arch users, which includes shell-completions (including device names) and automatic creation of the systemd unit, handles pipewire-alsa and alsa-libs dependencies, etc.

yay -S klack
2 Likes

No, Void Linux. However, I still can’t get it to work. It runs fine, but no sound output on key presses. Its very likely due to my specific custom setup of the distro and not worth a git issue. Thus, I’ll try to figure it out.

1 Like

slightly of the topic
legend ps/2 keyboard
don’t need to login - simply click ā€˜X’ before play

1 Like

The only external packages you should need are alsa-lib, which is required for it to even compile successfully, and then alsa-pipewire (I think that is the package name on Void?). There might be some sym-linking required, but I am sure you are more familiar with Void than I am regarding that.

I would be happy to help you debug it, it is no trouble, but if you do figure it out and it isn’t something niche and specific to your setup, I would appreciate any tips to include in the README for making troubleshooting easier for the next person.

Thanks for the feedback. I have alsa-lib and alsa-pipewire already installed (for longer, not specific for klack). Also the symlinking from the Void docs is in place. pipewire runs fine. wpctl status also shows me alsa:

Audio
 ā”œā”€ Devices:
 │      50. Built-in Audio                      [alsa]

I’ll dig deeper when I find the time

Edit: Of course, if you got a hint, where to look, I’m happy for it. Linux sound management is nothing I’ve dealt with beside setting it up… :grin:

I have updated to version v1.1.0, which includes some fixes and additions that will hopefully provide solutions to those who have had troubles with it working correctly on their systems.

ALSA Device

You can now specify the backend device that the ALSA driver uses with --alsa-device instead of relying upon it selecting the correct default. This means if you use JACK or if was incorrectly selecting PulseAudio when you use Pipewire, you can tell it to use the desired device. The devices ALSA supports on your system can be queried with aplay -L.

# List devices
aplay -L | grep "^\S"
# Tell ALSA to use that backend
klack --alsa-device jack

Alternatively the KLACK_ALSA_DEVICE environment variable can be used.

Groups

A new concept of ā€œgroupsā€, which are special token names that correspond to logical groupings of keys/buttons, but with a single value:

  • modifier_keys
  • arrow_keys
  • printable_keys
  • function_keys

These can be used for soundpacks the same as custom keys: a filename of printable_keys.wav will be used by all printable keys as if you specified each individually.

klack --list-groups

Excluded Keys/Buttons

You can now exclude keys/buttons by black-listing them with -e or --exclude, which accepts a comma-separated list of tokes that will never emit a sound when pressed.

klack --exclude modifier_keys,key_esc

Alternatively the KLACK_EXCLUDE environment variable can be used.

Max Voices

This has been removed as build option, and now offered as a command-line argument, as well as the default lowered to 4. This is sets the maximum number simultaneous sound effects that can play. When too low, the oldest effect that is still playing will be cut short to play the newest. Given the typical sound is only ~100 MS, this value can be pretty low (even 1) without much of a discernible negative effect. Must be between 1 and 16 (inclusive).

Alternatively the KLACK_MAX_VOICES environment variable can be used.

3 Likes