added keymap configuration yaml file

This commit is contained in:
2026-01-31 15:52:01 -06:00
parent 00851f4fbc
commit 0c1c71da49
7 changed files with 372 additions and 64 deletions

View File

@@ -72,7 +72,6 @@ qt_add_executable(metabolus
src/synth/Voice.h
src/synth/WavetableController.cpp
src/synth/WavetableController.h
resources/resources.qrc
src/ui/widgets/SmartSlider/SmartSlider.cpp
src/ui/widgets/SmartSlider/SmartSlider.h
src/ui/widgets/SmartSlider/SmartSlider.ui

View File

@@ -3,33 +3,336 @@
# Configures a computer keyboard mapping of keys to midi notes for when you don't have a midi device available
# (there's probably tools available that are able to make your keyboard act as a midi device but this was easier)
# so Qt key enum => midi note id
# { Qt::Key_Shift, 47 }, // B 2
# { Qt::Key_Z, 48 }, // C 3
# { Qt::Key_S, 49 }, // C#
# { Qt::Key_X, 50 }, // D
# { Qt::Key_D, 51 }, // D#
# { Qt::Key_C, 52 }, // E
# { Qt::Key_V, 53 }, // F
# { Qt::Key_G, 54 }, // F#
# { Qt::Key_B, 55 }, // G
# { Qt::Key_H, 56 }, // G#
# { Qt::Key_N, 57 }, // A
# { Qt::Key_J, 58 }, // A#
# { Qt::Key_M, 59 }, // B 3
# { Qt::Key_Q, 60 }, // C 4
# { Qt::Key_2, 61 }, // C#
# { Qt::Key_W, 62 }, // D
# { Qt::Key_3, 63 }, // D#
# { Qt::Key_E, 64 }, // E
# { Qt::Key_R, 65 }, // F
# { Qt::Key_5, 66 }, // F#
# { Qt::Key_T, 67 }, // G
# { Qt::Key_6, 68 }, // G#
# { Qt::Key_Y, 69 }, // A
# { Qt::Key_7, 70 }, // A#
# { Qt::Key_U, 71 }, // B 4
# { Qt::Key_I, 72 }, // C 5
keymap:
Key_Shift: B_2
Key_Z: C_3
Key_S: C#3
Key_X: D_3
Key_D: D#3
Key_C: E_3
Key_V: F_3
Key_G: F#3
Key_B: G_3
Key_H: G#3
Key_N: A_3
Key_J: A#3
Key_M: B_3
Key_Q: C_4
Key_2: C#4
Key_W: D_4
Key_3: D#4
Key_E: E_4
Key_R: F_4
Key_5: F#4
Key_T: G_4
Key_6: G#4
Key_Y: A_4
Key_7: A#4
Key_U: B_4
Key_I: C_5
Key_9: C#5
Key_O: D_5
# so we'll also need a mapping of the key strings to the qt::Key enum values
# and then a mapping of note strings to midi ids
# below are translations from strings to numbers that both Qt and the Oscillators can understand
# do not touch them unless you like the program not running
# note strings to midi ids, do not touch
# only has sharps for now, you can figure the rest out
notes:
A_0: 21
A#0: 22
B_0: 23
C_1: 24
C#1: 25
D_1: 26
D#1: 27
E_1: 28
F_1: 29
F#1: 30
G_1: 31
G#1: 32
A_1: 33
A#1: 34
B_1: 35
C_2: 36
C#2: 37
D_2: 38
D#2: 39
E_2: 40
F_2: 41
F#2: 42
G_2: 43
G#2: 44
A_2: 45
A#2: 46
B_2: 47
C_3: 48
C#3: 49
D_3: 50
D#3: 51
E_3: 52
F_3: 53
F#3: 54
G_3: 55
G#3: 56
A_3: 57
A#3: 58
B_3: 59
C_4: 60
C#4: 61
D_4: 62
D#4: 63
E_4: 64
F_4: 65
F#4: 66
G_4: 67
G#4: 68
A_4: 69
A#4: 70
B_4: 71
C_5: 72
C#5: 73
D_5: 74
D#5: 75
E_5: 76
F_5: 77
F#5: 78
G_5: 79
G#5: 80
A_5: 81
A#5: 82
B_5: 83
C_6: 84
C#6: 85
D_6: 86
D#6: 87
E_6: 88
F_6: 89
F#6: 90
G_6: 91
G#6: 92
A_6: 93
A#6: 94
B_6: 95
C_7: 96
C#7: 97
D_7: 98
D#7: 99
E_7: 100
F_7: 101
F#7: 102
G_7: 103
G#7: 104
A_7: 105
A#7: 106
B_7: 107
C_8: 108
# key strings to qt-key-ids, do not touch
keys:
Key_Space: 0x20
Key_Any: 0x20
Key_Exclam: 0x21
Key_QuoteDbl: 0x22
Key_NumberSign: 0x23
Key_Dollar: 0x24
Key_Percent: 0x25
Key_Ampersand: 0x26
Key_Apostrophe: 0x27
Key_ParenLeft: 0x28
Key_ParenRight: 0x29
Key_Asterisk: 0x2a
Key_Plus: 0x2b
Key_Comma: 0x2c
Key_Minus: 0x2d
Key_Period: 0x2e
Key_Slash: 0x2f
Key_0: 0x30
Key_1: 0x31
Key_2: 0x32
Key_3: 0x33
Key_4: 0x34
Key_5: 0x35
Key_6: 0x36
Key_7: 0x37
Key_8: 0x38
Key_9: 0x39
Key_Colon: 0x3a
Key_Semicolon: 0x3b
Key_Less: 0x3c
Key_Equal: 0x3d
Key_Greater: 0x3e
Key_Question: 0x3f
Key_At: 0x40
Key_A: 0x41
Key_B: 0x42
Key_C: 0x43
Key_D: 0x44
Key_E: 0x45
Key_F: 0x46
Key_G: 0x47
Key_H: 0x48
Key_I: 0x49
Key_J: 0x4a
Key_K: 0x4b
Key_L: 0x4c
Key_M: 0x4d
Key_N: 0x4e
Key_O: 0x4f
Key_P: 0x50
Key_Q: 0x51
Key_R: 0x52
Key_S: 0x53
Key_T: 0x54
Key_U: 0x55
Key_V: 0x56
Key_W: 0x57
Key_X: 0x58
Key_Y: 0x59
Key_Z: 0x5a
Key_BracketLeft: 0x5b
Key_Backslash: 0x5c
Key_BracketRight: 0x5d
Key_AsciiCircum: 0x5e
Key_Underscore: 0x5f
Key_QuoteLeft: 0x60
Key_BraceLeft: 0x7b
Key_Bar: 0x7c
Key_BraceRight: 0x7d
Key_AsciiTilde: 0x7e
Key_nobreakspace: 0x0a0
Key_exclamdown: 0x0a1
Key_cent: 0x0a2
Key_sterling: 0x0a3
Key_currency: 0x0a4
Key_yen: 0x0a5
Key_brokenbar: 0x0a6
Key_section: 0x0a7
Key_diaeresis: 0x0a8
Key_copyright: 0x0a9
Key_ordfeminine: 0x0aa
Key_guillemotleft: 0x0ab
Key_notsign: 0x0ac
Key_hyphen: 0x0ad
Key_registered: 0x0ae
Key_macron: 0x0af
Key_degree: 0x0b0
Key_plusminus: 0x0b1
Key_twosuperior: 0x0b2
Key_threesuperior: 0x0b3
Key_acute: 0x0b4
Key_micro: 0x0b5
Key_paragraph: 0x0b6
Key_periodcentered: 0x0b7
Key_cedilla: 0x0b8
Key_onesuperior: 0x0b9
Key_masculine: 0x0ba
Key_guillemotright: 0x0bb
Key_onequarter: 0x0bc
Key_onehalf: 0x0bd
Key_threequarters: 0x0be
Key_questiondown: 0x0bf
Key_Agrave: 0x0c0
Key_Aacute: 0x0c1
Key_Acircumflex: 0x0c2
Key_Atilde: 0x0c3
Key_Adiaeresis: 0x0c4
Key_Aring: 0x0c5
Key_AE: 0x0c6
Key_Ccedilla: 0x0c7
Key_Egrave: 0x0c8
Key_Eacute: 0x0c9
Key_Ecircumflex: 0x0ca
Key_Ediaeresis: 0x0cb
Key_Igrave: 0x0cc
Key_Iacute: 0x0cd
Key_Icircumflex: 0x0ce
Key_Idiaeresis: 0x0cf
Key_ETH: 0x0d0
Key_Ntilde: 0x0d1
Key_Ograve: 0x0d2
Key_Oacute: 0x0d3
Key_Ocircumflex: 0x0d4
Key_Otilde: 0x0d5
Key_Odiaeresis: 0x0d6
Key_multiply: 0x0d7
Key_Ooblique: 0x0d8
Key_Ugrave: 0x0d9
Key_Uacute: 0x0da
Key_Ucircumflex: 0x0db
Key_Udiaeresis: 0x0dc
Key_Yacute: 0x0dd
Key_THORN: 0x0de
Key_ssharp: 0x0df
Key_division: 0x0f7
Key_ydiaeresis: 0x0ff
Key_Escape: 0x01000000
Key_Tab: 0x01000001
Key_Backtab: 0x01000002
Key_Backspace: 0x01000003
Key_Return: 0x01000004
Key_Enter: 0x01000005
Key_Insert: 0x01000006
Key_Delete: 0x01000007
Key_Pause: 0x01000008
Key_Print: 0x01000009
Key_SysReq: 0x0100000a
Key_Clear: 0x0100000b
Key_Home: 0x01000010
Key_End: 0x01000011
Key_Left: 0x01000012
Key_Up: 0x01000013
Key_Right: 0x01000014
Key_Down: 0x01000015
Key_PageUp: 0x01000016
Key_PageDown: 0x01000017
Key_Shift: 0x01000020
Key_Control: 0x01000021
Key_Meta: 0x01000022
Key_Alt: 0x01000023
Key_CapsLock: 0x01000024
Key_NumLock: 0x01000025
Key_ScrollLock: 0x01000026
Key_F1: 0x01000030
Key_F2: 0x01000031
Key_F3: 0x01000032
Key_F4: 0x01000033
Key_F5: 0x01000034
Key_F6: 0x01000035
Key_F7: 0x01000036
Key_F8: 0x01000037
Key_F9: 0x01000038
Key_F10: 0x01000039
Key_F11: 0x0100003a
Key_F12: 0x0100003b
Key_F13: 0x0100003c
Key_F14: 0x0100003d
Key_F15: 0x0100003e
Key_F16: 0x0100003f
Key_F17: 0x01000040
Key_F18: 0x01000041
Key_F19: 0x01000042
Key_F20: 0x01000043
Key_F21: 0x01000044
Key_F22: 0x01000045
Key_F23: 0x01000046
Key_F24: 0x01000047
Key_F25: 0x01000048
Key_F26: 0x01000049
Key_F27: 0x0100004a
Key_F28: 0x0100004b
Key_F29: 0x0100004c
Key_F30: 0x0100004d
Key_F31: 0x0100004e
Key_F32: 0x0100004f
Key_F33: 0x01000050
Key_F34: 0x01000051
Key_F35: 0x01000052
Key_Super_L: 0x01000053
Key_Super_R: 0x01000054
Key_Menu: 0x01000055
Key_Hyper_L: 0x01000056
Key_Hyper_R: 0x01000057
Key_Help: 0x01000058
Key_Direction_L: 0x01000059
Key_Direction_R: 0x01000060

View File

@@ -14,8 +14,8 @@ OscWaveSelector1: 2
OscWaveSelector2: 1
# Frequency parameters
MasterOctaveOffset: [0, -5, 5]
MasterSemitoneOffset: [0, -12, 12]
MasterOctaveOffset: [1, -5, 5]
MasterSemitoneOffset: [1, -12, 12]
MasterPitchOffset: [0, -100, 100]
Osc1OctaveOffset: [0, -5, 5]
Osc1SemitoneOffset: [0, -12, 12]

View File

@@ -2,38 +2,42 @@
#include "KeyboardController.h"
#include <iostream>
#include <yaml-cpp/yaml.h>
#include <filesystem>
KeyboardController::KeyboardController(NoteQueue& queue) : queue_(queue) {
KeyboardController::KeyboardController(NoteQueue& queue, ConfigInterface* config) : queue_(queue), config_(config) {
// load keymap from config file
std::string filepath = "config/keymap.yaml";
filepath = std::filesystem::absolute(filepath).string();
YAML::Node file;
try {
file = YAML::LoadFile(filepath);
} catch(const std::exception& e) {
std::cerr << e.what() << std::endl;
return;
}
YAML::Node keymapNode = file["keymap"]; // node for string to string mappings
YAML::Node notesNode = file["notes"]; // string to midi int mappings
YAML::Node keysNode = file["keys"]; // string to qt key id mappings
// for each element in the keymap
for (const auto& entry : keymapNode) {
std::string keyString = entry.first.as<std::string>();
std::string noteString = entry.second.as<std::string>();
std::cout << keyString << ": " << noteString << std::endl;
// match the strings to ints
uint8_t noteValue = notesNode[noteString].as<uint8_t>();
uint32_t keyValue = keysNode[keyString].as<uint32_t>();
// insert into map
keymap_.emplace(keyValue, noteValue);
}
// TODO: also configurable via a yml
keymap_ = {
{ Qt::Key_Shift, 47 }, // B 2
{ Qt::Key_Z, 48 }, // C 3
{ Qt::Key_S, 49 }, // C#
{ Qt::Key_X, 50 }, // D
{ Qt::Key_D, 51 }, // D#
{ Qt::Key_C, 52 }, // E
{ Qt::Key_V, 53 }, // F
{ Qt::Key_G, 54 }, // F#
{ Qt::Key_B, 55 }, // G
{ Qt::Key_H, 56 }, // G#
{ Qt::Key_N, 57 }, // A
{ Qt::Key_J, 58 }, // A#
{ Qt::Key_M, 59 }, // B 3
{ Qt::Key_Q, 60 }, // C 4
{ Qt::Key_2, 61 }, // C#
{ Qt::Key_W, 62 }, // D
{ Qt::Key_3, 63 }, // D#
{ Qt::Key_E, 64 }, // E
{ Qt::Key_R, 65 }, // F
{ Qt::Key_5, 66 }, // F#
{ Qt::Key_T, 67 }, // G
{ Qt::Key_6, 68 }, // G#
{ Qt::Key_Y, 69 }, // A
{ Qt::Key_7, 70 }, // A#
{ Qt::Key_U, 71 }, // B 4
{ Qt::Key_I, 72 }, // C 5
};
}
void KeyboardController::handleKeyPress(QKeyEvent* e) {

View File

@@ -5,12 +5,13 @@
#include <unordered_map>
#include "NoteQueue.h"
#include "ConfigInterface.h"
// The keyboardcontroller handles user inputs from a keyboard and maps them to note events
class KeyboardController {
public:
explicit KeyboardController(NoteQueue& queue);
explicit KeyboardController(NoteQueue& queue, ConfigInterface* config);
~KeyboardController() = default;
void handleKeyPress(QKeyEvent* e);
@@ -19,6 +20,7 @@ public:
private:
NoteQueue& queue_;
ConfigInterface* config_;
// keymap is key -> midi note id
std::unordered_map<int32_t, uint8_t> keymap_;

View File

@@ -10,7 +10,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui_(new Ui::MainWindow),
config_(ConfigInterface(&params_)),
audio_(new AudioEngine(&config_, &params_)),
keyboard_(audio_->noteQueue()),
keyboard_(audio_->noteQueue(), &config_),
midi_(audio_->noteQueue()) {
// initialize ui