An interesting question is how real-world synthesizers deal with denouncing/deglitching (henceforth just “debouncing” to mean both). All but very basic synths use velocity-sensing keys (mostly by having two or three switches per key, not just one; some very high end models, like the Yamaha AvantGrand digital pianos, use optical sensing, using non-contact fiber optic on/off optocouplers instead of electrical switches, and also an analog sensor (either an optical density sensor and a gradient “flag”, or electromagnetic sensing in newer models). So when debouncing, what logic do they use? Do they debounce each switch individually? Or do they look at the other switches, too, and use more complex logic rules? Or both? When does playback begin?
Also, one thing that people designing user interfaces don’t always realize: a “button press” means different things, depending on context, in the sense that for some applications, you want to act on the “button down” event (for example, a gun trigger), on others, on “button up” (like a standard typing keyboard keystroke). And of course then you add functions like long presses that get evaluated differently again. How you debounce in code depends entirely on which of these features you need to implement.
My boilerplate button processing code (which is normally separated from the polling or interrupt that actually reads the GPIO state) uses elapsed time measurement, and has events for button_down (zero delay), short_press_down (after a short debouncing delay, e.g., 10ms), short_press_up (button released after short_press_down), long_press_down (after a much longer delay, e.g. 1s), and long_press_up (button released after long_press_down).
You can, of course, add multiple time thresholds, for example on up/down buttons for setting values, where you want it to increment by one on short_press_down, then after being held for e.g. 500ms repeat incrementing by one every 100ms, then after being held for 3s, change from incrementing by 10 every 100ms, and after being held 6 seconds, change to incrementing by 100 every 100ms.