diff --git a/CMakeLists.txt b/CMakeLists.txt index a4ed177..b7b5318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/config/keymap.yaml b/config/keymap.yaml index 6b6d60d..2298cd8 100644 --- a/config/keymap.yaml +++ b/config/keymap.yaml @@ -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 diff --git a/config/profiles/default.yaml b/config/profiles/default.yaml index 34e4e6f..7d14c22 100644 --- a/config/profiles/default.yaml +++ b/config/profiles/default.yaml @@ -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] diff --git a/resources/resources.qrc b/resources/resources.qrc deleted file mode 100644 index e69de29..0000000 diff --git a/src/KeyboardController.cpp b/src/KeyboardController.cpp index 4b60687..4dc24ea 100644 --- a/src/KeyboardController.cpp +++ b/src/KeyboardController.cpp @@ -2,38 +2,42 @@ #include "KeyboardController.h" #include +#include +#include -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 noteString = entry.second.as(); + + std::cout << keyString << ": " << noteString << std::endl; + + // match the strings to ints + uint8_t noteValue = notesNode[noteString].as(); + uint32_t keyValue = keysNode[keyString].as(); + + // 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) { diff --git a/src/KeyboardController.h b/src/KeyboardController.h index a793ac9..338014c 100644 --- a/src/KeyboardController.h +++ b/src/KeyboardController.h @@ -5,12 +5,13 @@ #include #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 keymap_; diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index c51bdd9..c29389c 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -10,7 +10,7 @@ MainWindow::MainWindow(QWidget *parent) : ui_(new Ui::MainWindow), config_(ConfigInterface(¶ms_)), audio_(new AudioEngine(&config_, ¶ms_)), - keyboard_(audio_->noteQueue()), + keyboard_(audio_->noteQueue(), &config_), midi_(audio_->noteQueue()) { // initialize ui