diff options
| author | James Young <18669334+noroadsleft@users.noreply.github.com> | 2020-11-28 12:02:18 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-28 12:02:18 -0800 |
| commit | c66df1664497546f32662409778731143e45a552 (patch) | |
| tree | da73a2d532a27685a31d932b3a44a707d4a3af81 /quantum/process_keycode | |
| parent | 15385d4113414d42bd062c60c9de5df797d3157f (diff) | |
| download | qmk_firmware-c66df1664497546f32662409778731143e45a552.tar.gz qmk_firmware-c66df1664497546f32662409778731143e45a552.zip | |
2020 November 28 Breaking Changes Update (#11053)
* Branch point for 2020 November 28 Breaking Change
* Remove matrix_col_t to allow MATRIX_ROWS > 32 (#10183)
* Add support for soft serial to ATmega32U2 (#10204)
* Change MIDI velocity implementation to allow direct control of velocity value (#9940)
* Add ability to build a subset of all keyboards based on platform.
* Actually use eeprom_driver_init().
* Make bootloader_jump weak for ChibiOS. (#10417)
* Joystick 16-bit support (#10439)
* Per-encoder resolutions (#10259)
* Share button state from mousekey to pointing_device (#10179)
* Add hotfix for chibios keyboards not wake (#10088)
* Add advanced/efficient RGB Matrix Indicators (#8564)
* Naming change.
* Support for STM32 GPIOF,G,H,I,J,K (#10206)
* Add milc as a dependency and remove the installed milc (#10563)
* ChibiOS upgrade: early init conversions (#10214)
* ChibiOS upgrade: configuration file migrator (#9952)
* Haptic and solenoid cleanup (#9700)
* XD75 cleanup (#10524)
* OLED display update interval support (#10388)
* Add definition based on currently-selected serial driver. (#10716)
* New feature: Retro Tapping per key (#10622)
* Allow for modification of output RGB values when using rgblight/rgb_matrix. (#10638)
* Add housekeeping task callbacks so that keyboards/keymaps are capable of executing code for each main loop iteration. (#10530)
* Rescale both ChibiOS and AVR backlighting.
* Reduce Helix keyboard build variation (#8669)
* Minor change to behavior allowing display updates to continue between task ticks (#10750)
* Some GPIO manipulations in matrix.c change to atomic. (#10491)
* qmk cformat (#10767)
* [Keyboard] Update the Speedo firmware for v3.0 (#10657)
* Maartenwut/Maarten namechange to evyd13/Evy (#10274)
* [quantum] combine repeated lines of code (#10837)
* Add step sequencer feature (#9703)
* aeboards/ext65 refactor (#10820)
* Refactor xelus/dawn60 for Rev2 later (#10584)
* add DEBUG_MATRIX_SCAN_RATE_ENABLE to common_features.mk (#10824)
* [Core] Added `add_oneshot_mods` & `del_oneshot_mods` (#10549)
* update chibios os usb for the otg driver (#8893)
* Remove HD44780 References, Part 4 (#10735)
* [Keyboard] Add Valor FRL TKL (+refactor) (#10512)
* Fix cursor position bug in oled_write_raw functions (#10800)
* Fixup version.h writing when using SKIP_VERSION=yes (#10972)
* Allow for certain code in the codebase assuming length of string. (#10974)
* Add AT90USB support for serial.c (#10706)
* Auto shift: support repeats and early registration (#9826)
* Rename ledmatrix.h to match .c file (#7949)
* Split RGB_MATRIX_ENABLE into _ENABLE and _DRIVER (#10231)
* Split LED_MATRIX_ENABLE into _ENABLE and _DRIVER (#10840)
* Merge point for 2020 Nov 28 Breaking Change
Diffstat (limited to 'quantum/process_keycode')
| -rw-r--r-- | quantum/process_keycode/process_auto_shift.c | 199 | ||||
| -rw-r--r-- | quantum/process_keycode/process_auto_shift.h | 1 | ||||
| -rw-r--r-- | quantum/process_keycode/process_joystick.c | 8 | ||||
| -rw-r--r-- | quantum/process_keycode/process_midi.c | 25 | ||||
| -rw-r--r-- | quantum/process_keycode/process_midi.h | 2 | ||||
| -rw-r--r-- | quantum/process_keycode/process_sequencer.c | 62 | ||||
| -rw-r--r-- | quantum/process_keycode/process_sequencer.h | 21 |
7 files changed, 256 insertions, 62 deletions
diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c index b1267922c..a2d315408 100644 --- a/quantum/process_keycode/process_auto_shift.c +++ b/quantum/process_keycode/process_auto_shift.c | |||
| @@ -16,48 +16,149 @@ | |||
| 16 | 16 | ||
| 17 | #ifdef AUTO_SHIFT_ENABLE | 17 | #ifdef AUTO_SHIFT_ENABLE |
| 18 | 18 | ||
| 19 | # include <stdbool.h> | ||
| 19 | # include <stdio.h> | 20 | # include <stdio.h> |
| 20 | 21 | ||
| 21 | # include "process_auto_shift.h" | 22 | # include "process_auto_shift.h" |
| 22 | 23 | ||
| 23 | static bool autoshift_enabled = true; | ||
| 24 | static uint16_t autoshift_time = 0; | 24 | static uint16_t autoshift_time = 0; |
| 25 | static uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT; | 25 | static uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT; |
| 26 | static uint16_t autoshift_lastkey = KC_NO; | 26 | static uint16_t autoshift_lastkey = KC_NO; |
| 27 | static struct { | ||
| 28 | // Whether autoshift is enabled. | ||
| 29 | bool enabled : 1; | ||
| 30 | // Whether the last auto-shifted key was released after the timeout. This | ||
| 31 | // is used to replicate the last key for a tap-then-hold. | ||
| 32 | bool lastshifted : 1; | ||
| 33 | // Whether an auto-shiftable key has been pressed but not processed. | ||
| 34 | bool in_progress : 1; | ||
| 35 | // Whether the auto-shifted keypress has been registered. | ||
| 36 | bool holding_shift : 1; | ||
| 37 | } autoshift_flags = {true, false, false, false}; | ||
| 38 | |||
| 39 | /** \brief Record the press of an autoshiftable key | ||
| 40 | * | ||
| 41 | * \return Whether the record should be further processed. | ||
| 42 | */ | ||
| 43 | static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record) { | ||
| 44 | if (!autoshift_flags.enabled) { | ||
| 45 | return true; | ||
| 46 | } | ||
| 47 | |||
| 48 | # ifndef AUTO_SHIFT_MODIFIERS | ||
| 49 | if (get_mods() & (~MOD_BIT(KC_LSFT))) { | ||
| 50 | return true; | ||
| 51 | } | ||
| 52 | # endif | ||
| 53 | # ifdef AUTO_SHIFT_REPEAT | ||
| 54 | const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time); | ||
| 55 | # ifndef AUTO_SHIFT_NO_AUTO_REPEAT | ||
| 56 | if (!autoshift_flags.lastshifted) { | ||
| 57 | # endif | ||
| 58 | if (elapsed < TAPPING_TERM && keycode == autoshift_lastkey) { | ||
| 59 | // Allow a tap-then-hold for keyrepeat. | ||
| 60 | if (!autoshift_flags.lastshifted) { | ||
| 61 | register_code(autoshift_lastkey); | ||
| 62 | } else { | ||
| 63 | // Simulate pressing the shift key. | ||
| 64 | add_weak_mods(MOD_BIT(KC_LSFT)); | ||
| 65 | register_code(autoshift_lastkey); | ||
| 66 | } | ||
| 67 | return false; | ||
| 68 | } | ||
| 69 | # ifndef AUTO_SHIFT_NO_AUTO_REPEAT | ||
| 70 | } | ||
| 71 | # endif | ||
| 72 | # endif | ||
| 27 | 73 | ||
| 28 | void autoshift_flush(void) { | 74 | // Record the keycode so we can simulate it later. |
| 29 | if (autoshift_lastkey != KC_NO) { | 75 | autoshift_lastkey = keycode; |
| 30 | uint16_t elapsed = timer_elapsed(autoshift_time); | 76 | autoshift_time = now; |
| 77 | autoshift_flags.in_progress = true; | ||
| 31 | 78 | ||
| 32 | if (elapsed > autoshift_timeout) { | 79 | # if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING) |
| 33 | tap_code16(LSFT(autoshift_lastkey)); | 80 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); |
| 81 | # endif | ||
| 82 | return false; | ||
| 83 | } | ||
| 84 | |||
| 85 | /** \brief Registers an autoshiftable key under the right conditions | ||
| 86 | * | ||
| 87 | * If the autoshift delay has elapsed, register a shift and the key. | ||
| 88 | * | ||
| 89 | * If the autoshift key is released before the delay has elapsed, register the | ||
| 90 | * key without a shift. | ||
| 91 | */ | ||
| 92 | static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) { | ||
| 93 | // Called on key down with KC_NO, auto-shifted key up, and timeout. | ||
| 94 | if (autoshift_flags.in_progress) { | ||
| 95 | // Process the auto-shiftable key. | ||
| 96 | autoshift_flags.in_progress = false; | ||
| 97 | |||
| 98 | // Time since the initial press was recorded. | ||
| 99 | const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time); | ||
| 100 | if (elapsed < autoshift_timeout) { | ||
| 101 | register_code(autoshift_lastkey); | ||
| 102 | autoshift_flags.lastshifted = false; | ||
| 34 | } else { | 103 | } else { |
| 35 | tap_code(autoshift_lastkey); | 104 | // Simulate pressing the shift key. |
| 105 | add_weak_mods(MOD_BIT(KC_LSFT)); | ||
| 106 | register_code(autoshift_lastkey); | ||
| 107 | autoshift_flags.lastshifted = true; | ||
| 108 | # if defined(AUTO_SHIFT_REPEAT) && !defined(AUTO_SHIFT_NO_AUTO_REPEAT) | ||
| 109 | if (matrix_trigger) { | ||
| 110 | // Prevents release. | ||
| 111 | return; | ||
| 112 | } | ||
| 113 | # endif | ||
| 36 | } | 114 | } |
| 37 | 115 | ||
| 38 | autoshift_time = 0; | 116 | # if TAP_CODE_DELAY > 0 |
| 39 | autoshift_lastkey = KC_NO; | 117 | wait_ms(TAP_CODE_DELAY); |
| 118 | # endif | ||
| 119 | unregister_code(autoshift_lastkey); | ||
| 120 | del_weak_mods(MOD_BIT(KC_LSFT)); | ||
| 121 | } else { | ||
| 122 | // Release after keyrepeat. | ||
| 123 | unregister_code(keycode); | ||
| 124 | if (keycode == autoshift_lastkey) { | ||
| 125 | // This will only fire when the key was the last auto-shiftable | ||
| 126 | // pressed. That prevents aaaaBBBB then releasing a from unshifting | ||
| 127 | // later Bs (if B wasn't auto-shiftable). | ||
| 128 | del_weak_mods(MOD_BIT(KC_LSFT)); | ||
| 129 | } | ||
| 40 | } | 130 | } |
| 131 | send_keyboard_report(); // del_weak_mods doesn't send one. | ||
| 132 | // Roll the autoshift_time forward for detecting tap-and-hold. | ||
| 133 | autoshift_time = now; | ||
| 41 | } | 134 | } |
| 42 | 135 | ||
| 43 | void autoshift_on(uint16_t keycode) { | 136 | /** \brief Simulates auto-shifted key releases when timeout is hit |
| 44 | autoshift_time = timer_read(); | 137 | * |
| 45 | autoshift_lastkey = keycode; | 138 | * Can be called from \c matrix_scan_user so that auto-shifted keys are sent |
| 139 | * immediately after the timeout has expired, rather than waiting for the key | ||
| 140 | * to be released. | ||
| 141 | */ | ||
| 142 | void autoshift_matrix_scan(void) { | ||
| 143 | if (autoshift_flags.in_progress) { | ||
| 144 | const uint16_t now = timer_read(); | ||
| 145 | const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time); | ||
| 146 | if (elapsed >= autoshift_timeout) { | ||
| 147 | autoshift_end(autoshift_lastkey, now, true); | ||
| 148 | } | ||
| 149 | } | ||
| 46 | } | 150 | } |
| 47 | 151 | ||
| 48 | void autoshift_toggle(void) { | 152 | void autoshift_toggle(void) { |
| 49 | if (autoshift_enabled) { | 153 | autoshift_flags.enabled = !autoshift_flags.enabled; |
| 50 | autoshift_enabled = false; | 154 | del_weak_mods(MOD_BIT(KC_LSFT)); |
| 51 | autoshift_flush(); | ||
| 52 | } else { | ||
| 53 | autoshift_enabled = true; | ||
| 54 | } | ||
| 55 | } | 155 | } |
| 56 | 156 | ||
| 57 | void autoshift_enable(void) { autoshift_enabled = true; } | 157 | void autoshift_enable(void) { autoshift_flags.enabled = true; } |
| 158 | |||
| 58 | void autoshift_disable(void) { | 159 | void autoshift_disable(void) { |
| 59 | autoshift_enabled = false; | 160 | autoshift_flags.enabled = false; |
| 60 | autoshift_flush(); | 161 | del_weak_mods(MOD_BIT(KC_LSFT)); |
| 61 | } | 162 | } |
| 62 | 163 | ||
| 63 | # ifndef AUTO_SHIFT_NO_SETUP | 164 | # ifndef AUTO_SHIFT_NO_SETUP |
| @@ -70,19 +171,30 @@ void autoshift_timer_report(void) { | |||
| 70 | } | 171 | } |
| 71 | # endif | 172 | # endif |
| 72 | 173 | ||
| 73 | bool get_autoshift_state(void) { return autoshift_enabled; } | 174 | bool get_autoshift_state(void) { return autoshift_flags.enabled; } |
| 74 | 175 | ||
| 75 | uint16_t get_autoshift_timeout(void) { return autoshift_timeout; } | 176 | uint16_t get_autoshift_timeout(void) { return autoshift_timeout; } |
| 76 | 177 | ||
| 77 | void set_autoshift_timeout(uint16_t timeout) { autoshift_timeout = timeout; } | 178 | void set_autoshift_timeout(uint16_t timeout) { autoshift_timeout = timeout; } |
| 78 | 179 | ||
| 79 | bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { | 180 | bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { |
| 181 | // Note that record->event.time isn't reliable, see: | ||
| 182 | // https://github.com/qmk/qmk_firmware/pull/9826#issuecomment-733559550 | ||
| 183 | const uint16_t now = timer_read(); | ||
| 184 | |||
| 80 | if (record->event.pressed) { | 185 | if (record->event.pressed) { |
| 186 | if (autoshift_flags.in_progress) { | ||
| 187 | // Evaluate previous key if there is one. Doing this elsewhere is | ||
| 188 | // more complicated and easier to break. | ||
| 189 | autoshift_end(KC_NO, now, false); | ||
| 190 | } | ||
| 191 | // For pressing another key while keyrepeating shifted autoshift. | ||
| 192 | del_weak_mods(MOD_BIT(KC_LSFT)); | ||
| 193 | |||
| 81 | switch (keycode) { | 194 | switch (keycode) { |
| 82 | case KC_ASTG: | 195 | case KC_ASTG: |
| 83 | autoshift_toggle(); | 196 | autoshift_toggle(); |
| 84 | return true; | 197 | return true; |
| 85 | |||
| 86 | case KC_ASON: | 198 | case KC_ASON: |
| 87 | autoshift_enable(); | 199 | autoshift_enable(); |
| 88 | return true; | 200 | return true; |
| @@ -102,41 +214,28 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { | |||
| 102 | autoshift_timer_report(); | 214 | autoshift_timer_report(); |
| 103 | return true; | 215 | return true; |
| 104 | # endif | 216 | # endif |
| 217 | } | ||
| 218 | } | ||
| 219 | |||
| 220 | switch (keycode) { | ||
| 105 | # ifndef NO_AUTO_SHIFT_ALPHA | 221 | # ifndef NO_AUTO_SHIFT_ALPHA |
| 106 | case KC_A ... KC_Z: | 222 | case KC_A ... KC_Z: |
| 107 | # endif | 223 | # endif |
| 108 | # ifndef NO_AUTO_SHIFT_NUMERIC | 224 | # ifndef NO_AUTO_SHIFT_NUMERIC |
| 109 | case KC_1 ... KC_0: | 225 | case KC_1 ... KC_0: |
| 110 | # endif | 226 | # endif |
| 111 | # ifndef NO_AUTO_SHIFT_SPECIAL | 227 | # ifndef NO_AUTO_SHIFT_SPECIAL |
| 112 | case KC_TAB: | 228 | case KC_TAB: |
| 113 | case KC_MINUS ... KC_SLASH: | 229 | case KC_MINUS ... KC_SLASH: |
| 114 | case KC_NONUS_BSLASH: | 230 | case KC_NONUS_BSLASH: |
| 115 | # endif | ||
| 116 | autoshift_flush(); | ||
| 117 | if (!autoshift_enabled) return true; | ||
| 118 | |||
| 119 | # ifndef AUTO_SHIFT_MODIFIERS | ||
| 120 | if (get_mods()) { | ||
| 121 | return true; | ||
| 122 | } | ||
| 123 | # endif | ||
| 124 | autoshift_on(keycode); | ||
| 125 | |||
| 126 | // We need some extra handling here for OSL edge cases | ||
| 127 | # if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING) | ||
| 128 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | ||
| 129 | # endif | 231 | # endif |
| 232 | if (record->event.pressed) { | ||
| 233 | return autoshift_press(keycode, now, record); | ||
| 234 | } else { | ||
| 235 | autoshift_end(keycode, now, false); | ||
| 130 | return false; | 236 | return false; |
| 131 | 237 | } | |
| 132 | default: | ||
| 133 | autoshift_flush(); | ||
| 134 | return true; | ||
| 135 | } | ||
| 136 | } else { | ||
| 137 | autoshift_flush(); | ||
| 138 | } | 238 | } |
| 139 | |||
| 140 | return true; | 239 | return true; |
| 141 | } | 240 | } |
| 142 | 241 | ||
diff --git a/quantum/process_keycode/process_auto_shift.h b/quantum/process_keycode/process_auto_shift.h index e86c4658e..5b2718f11 100644 --- a/quantum/process_keycode/process_auto_shift.h +++ b/quantum/process_keycode/process_auto_shift.h | |||
| @@ -30,3 +30,4 @@ void autoshift_toggle(void); | |||
| 30 | bool get_autoshift_state(void); | 30 | bool get_autoshift_state(void); |
| 31 | uint16_t get_autoshift_timeout(void); | 31 | uint16_t get_autoshift_timeout(void); |
| 32 | void set_autoshift_timeout(uint16_t timeout); | 32 | void set_autoshift_timeout(uint16_t timeout); |
| 33 | void autoshift_matrix_scan(void); | ||
diff --git a/quantum/process_keycode/process_joystick.c b/quantum/process_keycode/process_joystick.c index 5778a7434..3ffaf42bf 100644 --- a/quantum/process_keycode/process_joystick.c +++ b/quantum/process_keycode/process_joystick.c | |||
| @@ -129,17 +129,17 @@ bool process_joystick_analogread_quantum() { | |||
| 129 | // test the converted value against the lower range | 129 | // test the converted value against the lower range |
| 130 | int32_t ref = joystick_axes[axis_index].mid_digit; | 130 | int32_t ref = joystick_axes[axis_index].mid_digit; |
| 131 | int32_t range = joystick_axes[axis_index].min_digit; | 131 | int32_t range = joystick_axes[axis_index].min_digit; |
| 132 | int32_t ranged_val = ((axis_val - ref) * -127) / (range - ref); | 132 | int32_t ranged_val = ((axis_val - ref) * -JOYSTICK_RESOLUTION) / (range - ref); |
| 133 | 133 | ||
| 134 | if (ranged_val > 0) { | 134 | if (ranged_val > 0) { |
| 135 | // the value is in the higher range | 135 | // the value is in the higher range |
| 136 | range = joystick_axes[axis_index].max_digit; | 136 | range = joystick_axes[axis_index].max_digit; |
| 137 | ranged_val = ((axis_val - ref) * 127) / (range - ref); | 137 | ranged_val = ((axis_val - ref) * JOYSTICK_RESOLUTION) / (range - ref); |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | // clamp the result in the valid range | 140 | // clamp the result in the valid range |
| 141 | ranged_val = ranged_val < -127 ? -127 : ranged_val; | 141 | ranged_val = ranged_val < -JOYSTICK_RESOLUTION ? -JOYSTICK_RESOLUTION : ranged_val; |
| 142 | ranged_val = ranged_val > 127 ? 127 : ranged_val; | 142 | ranged_val = ranged_val > JOYSTICK_RESOLUTION ? JOYSTICK_RESOLUTION : ranged_val; |
| 143 | 143 | ||
| 144 | if (ranged_val != joystick_status.axes[axis_index]) { | 144 | if (ranged_val != joystick_status.axes[axis_index]) { |
| 145 | joystick_status.axes[axis_index] = ranged_val; | 145 | joystick_status.axes[axis_index] = ranged_val; |
diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c index e52577014..8e2fb955e 100644 --- a/quantum/process_keycode/process_midi.c +++ b/quantum/process_keycode/process_midi.c | |||
| @@ -41,12 +41,12 @@ static int8_t midi_modulation_step; | |||
| 41 | static uint16_t midi_modulation_timer; | 41 | static uint16_t midi_modulation_timer; |
| 42 | midi_config_t midi_config; | 42 | midi_config_t midi_config; |
| 43 | 43 | ||
| 44 | inline uint8_t compute_velocity(uint8_t setting) { return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1)); } | 44 | inline uint8_t compute_velocity(uint8_t setting) { return setting * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN)); } |
| 45 | 45 | ||
| 46 | void midi_init(void) { | 46 | void midi_init(void) { |
| 47 | midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN; | 47 | midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN; |
| 48 | midi_config.transpose = 0; | 48 | midi_config.transpose = 0; |
| 49 | midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN); | 49 | midi_config.velocity = 127; |
| 50 | midi_config.channel = 0; | 50 | midi_config.channel = 0; |
| 51 | midi_config.modulation_interval = 8; | 51 | midi_config.modulation_interval = 8; |
| 52 | 52 | ||
| @@ -66,7 +66,7 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) { | |||
| 66 | case MIDI_TONE_MIN ... MIDI_TONE_MAX: { | 66 | case MIDI_TONE_MIN ... MIDI_TONE_MAX: { |
| 67 | uint8_t channel = midi_config.channel; | 67 | uint8_t channel = midi_config.channel; |
| 68 | uint8_t tone = keycode - MIDI_TONE_MIN; | 68 | uint8_t tone = keycode - MIDI_TONE_MIN; |
| 69 | uint8_t velocity = compute_velocity(midi_config.velocity); | 69 | uint8_t velocity = midi_config.velocity; |
| 70 | if (record->event.pressed) { | 70 | if (record->event.pressed) { |
| 71 | if (tone_status[tone] == MIDI_INVALID_NOTE) { | 71 | if (tone_status[tone] == MIDI_INVALID_NOTE) { |
| 72 | uint8_t note = midi_compute_note(keycode); | 72 | uint8_t note = midi_compute_note(keycode); |
| @@ -124,19 +124,30 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) { | |||
| 124 | return false; | 124 | return false; |
| 125 | case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX: | 125 | case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX: |
| 126 | if (record->event.pressed) { | 126 | if (record->event.pressed) { |
| 127 | midi_config.velocity = keycode - MIDI_VELOCITY_MIN; | 127 | midi_config.velocity = compute_velocity(keycode - MIDI_VELOCITY_MIN); |
| 128 | dprintf("midi velocity %d\n", midi_config.velocity); | 128 | dprintf("midi velocity %d\n", midi_config.velocity); |
| 129 | } | 129 | } |
| 130 | return false; | 130 | return false; |
| 131 | case MI_VELD: | 131 | case MI_VELD: |
| 132 | if (record->event.pressed && midi_config.velocity > 0) { | 132 | if (record->event.pressed && midi_config.velocity > 0) { |
| 133 | midi_config.velocity--; | 133 | if (midi_config.velocity == 127) { |
| 134 | midi_config.velocity -= 10; | ||
| 135 | } else if (midi_config.velocity > 12) { | ||
| 136 | midi_config.velocity -= 13; | ||
| 137 | } else { | ||
| 138 | midi_config.velocity = 0; | ||
| 139 | } | ||
| 140 | |||
| 134 | dprintf("midi velocity %d\n", midi_config.velocity); | 141 | dprintf("midi velocity %d\n", midi_config.velocity); |
| 135 | } | 142 | } |
| 136 | return false; | 143 | return false; |
| 137 | case MI_VELU: | 144 | case MI_VELU: |
| 138 | if (record->event.pressed) { | 145 | if (record->event.pressed && midi_config.velocity < 127) { |
| 139 | midi_config.velocity++; | 146 | if (midi_config.velocity < 115) { |
| 147 | midi_config.velocity += 13; | ||
| 148 | } else { | ||
| 149 | midi_config.velocity = 127; | ||
| 150 | } | ||
| 140 | dprintf("midi velocity %d\n", midi_config.velocity); | 151 | dprintf("midi velocity %d\n", midi_config.velocity); |
| 141 | } | 152 | } |
| 142 | return false; | 153 | return false; |
diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h index 0007b3ed2..ef5661dd4 100644 --- a/quantum/process_keycode/process_midi.h +++ b/quantum/process_keycode/process_midi.h | |||
| @@ -35,7 +35,7 @@ typedef union { | |||
| 35 | struct { | 35 | struct { |
| 36 | uint8_t octave : 4; | 36 | uint8_t octave : 4; |
| 37 | int8_t transpose : 4; | 37 | int8_t transpose : 4; |
| 38 | uint8_t velocity : 4; | 38 | uint8_t velocity : 7; |
| 39 | uint8_t channel : 4; | 39 | uint8_t channel : 4; |
| 40 | uint8_t modulation_interval : 4; | 40 | uint8_t modulation_interval : 4; |
| 41 | }; | 41 | }; |
diff --git a/quantum/process_keycode/process_sequencer.c b/quantum/process_keycode/process_sequencer.c new file mode 100644 index 000000000..334b4c009 --- /dev/null +++ b/quantum/process_keycode/process_sequencer.c | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /* Copyright 2020 Rodolphe Belouin | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "process_sequencer.h" | ||
| 18 | |||
| 19 | bool process_sequencer(uint16_t keycode, keyrecord_t *record) { | ||
| 20 | if (record->event.pressed) { | ||
| 21 | switch (keycode) { | ||
| 22 | case SQ_ON: | ||
| 23 | sequencer_on(); | ||
| 24 | return false; | ||
| 25 | case SQ_OFF: | ||
| 26 | sequencer_off(); | ||
| 27 | return false; | ||
| 28 | case SQ_TOG: | ||
| 29 | sequencer_toggle(); | ||
| 30 | return false; | ||
| 31 | case SQ_TMPD: | ||
| 32 | sequencer_decrease_tempo(); | ||
| 33 | return false; | ||
| 34 | case SQ_TMPU: | ||
| 35 | sequencer_increase_tempo(); | ||
| 36 | return false; | ||
| 37 | case SEQUENCER_RESOLUTION_MIN ... SEQUENCER_RESOLUTION_MAX: | ||
| 38 | sequencer_set_resolution(keycode - SEQUENCER_RESOLUTION_MIN); | ||
| 39 | return false; | ||
| 40 | case SQ_RESD: | ||
| 41 | sequencer_decrease_resolution(); | ||
| 42 | return false; | ||
| 43 | case SQ_RESU: | ||
| 44 | sequencer_increase_resolution(); | ||
| 45 | return false; | ||
| 46 | case SQ_SALL: | ||
| 47 | sequencer_set_all_steps_on(); | ||
| 48 | return false; | ||
| 49 | case SQ_SCLR: | ||
| 50 | sequencer_set_all_steps_off(); | ||
| 51 | return false; | ||
| 52 | case SEQUENCER_STEP_MIN ... SEQUENCER_STEP_MAX: | ||
| 53 | sequencer_toggle_step(keycode - SEQUENCER_STEP_MIN); | ||
| 54 | return false; | ||
| 55 | case SEQUENCER_TRACK_MIN ... SEQUENCER_TRACK_MAX: | ||
| 56 | sequencer_toggle_single_active_track(keycode - SEQUENCER_TRACK_MIN); | ||
| 57 | return false; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | return true; | ||
| 62 | } | ||
diff --git a/quantum/process_keycode/process_sequencer.h b/quantum/process_keycode/process_sequencer.h new file mode 100644 index 000000000..2b85f2429 --- /dev/null +++ b/quantum/process_keycode/process_sequencer.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Copyright 2020 Rodolphe Belouin | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #pragma once | ||
| 18 | |||
| 19 | #include "quantum.h" | ||
| 20 | |||
| 21 | bool process_sequencer(uint16_t keycode, keyrecord_t *record); | ||
