There are two layers involved here: The
input layer of the kernel, which translates various keyboard, mice, joysticks etc. into a common framework, and makes them available on
/dev/input/* device files (one file per device), and the X (or, depending on your distro, Wayland) layer, which reads those files, and translates them into X events which are understood by graphical applications. The latter combines the input devices and makes them available as "keyboard events from any device" and "mouse events from any device" (this is a simplification, but ok is first aproximation).
The natural way for an application is to interact with the X layer (and I'm sure there as a Ruby abstraction for that). This is in particular recommended if your application not only plays sounds, but also displays something (and even if it doesn't display anything).
Of course, if you insist, you can also open all files in
/dev/input/*, and interpret the events coming from them, but this will fail the moment a new keyboard a mouse gets attached, and you want to react on those events, too.
/dev/input/mice abstraction only exists for mice, and is a sort of legacy solution invented at the time when people were using a single PS/2 keyboard, but there were already all kinds of different mouse devices. This file may not match what the X layer considers active mouse input devices, and there's no equivalent abstraction for keyboards.