summaryrefslogtreecommitdiff
path: root/quantum/process_keycode
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode')
-rw-r--r--quantum/process_keycode/process_audio.c22
-rw-r--r--quantum/process_keycode/process_music.c153
-rw-r--r--quantum/process_keycode/process_music.h9
-rw-r--r--quantum/process_keycode/process_steno.c166
-rw-r--r--quantum/process_keycode/process_steno.h31
-rw-r--r--quantum/process_keycode/process_tap_dance.c18
-rw-r--r--quantum/process_keycode/process_tap_dance.h14
7 files changed, 353 insertions, 60 deletions
diff --git a/quantum/process_keycode/process_audio.c b/quantum/process_keycode/process_audio.c
index 0b6380ed39..32057ae8dc 100644
--- a/quantum/process_keycode/process_audio.c
+++ b/quantum/process_keycode/process_audio.c
@@ -1,10 +1,19 @@
#include "audio.h"
#include "process_audio.h"
+#ifndef VOICE_CHANGE_SONG
+ #define VOICE_CHANGE_SONG SONG(VOICE_CHANGE_SOUND)
+#endif
+float voice_change_song[][2] = VOICE_CHANGE_SONG;
+
+#ifndef PITCH_STANDARD_A
+ #define PITCH_STANDARD_A 440.0f
+#endif
+
static float compute_freq_for_midi_note(uint8_t note)
{
// https://en.wikipedia.org/wiki/MIDI_tuning_standard
- return pow(2.0, (note - 69) / 12.0) * 440.0f;
+ return pow(2.0, (note - 69) / 12.0) * PITCH_STANDARD_A;
}
bool process_audio(uint16_t keycode, keyrecord_t *record) {
@@ -20,12 +29,9 @@ bool process_audio(uint16_t keycode, keyrecord_t *record) {
}
if (keycode == AU_TOG && record->event.pressed) {
- if (is_audio_on())
- {
+ if (is_audio_on()) {
audio_off();
- }
- else
- {
+ } else {
audio_on();
}
return false;
@@ -33,13 +39,13 @@ bool process_audio(uint16_t keycode, keyrecord_t *record) {
if (keycode == MUV_IN && record->event.pressed) {
voice_iterate();
- music_scale_user();
+ PLAY_SONG(voice_change_song);
return false;
}
if (keycode == MUV_DE && record->event.pressed) {
voice_deiterate();
- music_scale_user();
+ PLAY_SONG(voice_change_song);
return false;
}
diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c
index 217dca2807..63841d1e87 100644
--- a/quantum/process_keycode/process_music.c
+++ b/quantum/process_keycode/process_music.c
@@ -27,6 +27,7 @@
bool music_activated = false;
uint8_t music_starting_note = 0x0C;
int music_offset = 7;
+uint8_t music_mode = MUSIC_MODE_CHROMATIC;
// music sequencer
static bool music_sequence_recording = false;
@@ -39,6 +40,39 @@ static uint8_t music_sequence_position = 0;
static uint16_t music_sequence_timer = 0;
static uint16_t music_sequence_interval = 100;
+#ifdef AUDIO_ENABLE
+ #ifndef MUSIC_ON_SONG
+ #define MUSIC_ON_SONG SONG(MUSIC_ON_SOUND)
+ #endif
+ #ifndef MUSIC_OFF_SONG
+ #define MUSIC_OFF_SONG SONG(MUSIC_OFF_SOUND)
+ #endif
+ #ifndef CHROMATIC_SONG
+ #define CHROMATIC_SONG SONG(CHROMATIC_SOUND)
+ #endif
+ #ifndef GUITAR_SONG
+ #define GUITAR_SONG SONG(GUITAR_SOUND)
+ #endif
+ #ifndef VIOLIN_SONG
+ #define VIOLIN_SONG SONG(VIOLIN_SOUND)
+ #endif
+ #ifndef MAJOR_SONG
+ #define MAJOR_SONG SONG(MAJOR_SOUND)
+ #endif
+ float music_mode_songs[NUMBER_OF_MODES][5][2] = {
+ CHROMATIC_SONG,
+ GUITAR_SONG,
+ VIOLIN_SONG,
+ MAJOR_SONG
+ };
+ float music_on_song[][2] = MUSIC_ON_SONG;
+ float music_off_song[][2] = MUSIC_OFF_SONG;
+#endif
+
+#ifndef MUSIC_MASK
+ #define MUSIC_MASK keycode < 0xFF
+#endif
+
static void music_noteon(uint8_t note) {
#ifdef AUDIO_ENABLE
process_audio_noteon(note);
@@ -79,70 +113,71 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
}
if (keycode == MU_TOG && record->event.pressed) {
- if (music_activated)
- {
+ if (music_activated) {
music_off();
- }
- else
- {
+ } else {
music_on();
}
return false;
}
- if (music_activated) {
+ if (keycode == MU_MOD && record->event.pressed) {
+ music_mode_cycle();
+ return false;
+ }
- if (keycode == KC_LCTL && record->event.pressed) { // Start recording
- music_all_notes_off();
- music_sequence_recording = true;
- music_sequence_recorded = false;
- music_sequence_playing = false;
- music_sequence_count = 0;
- return false;
- }
+ if (music_activated) {
+ if (record->event.pressed) {
+ if (keycode == KC_LCTL) { // Start recording
+ music_all_notes_off();
+ music_sequence_recording = true;
+ music_sequence_recorded = false;
+ music_sequence_playing = false;
+ music_sequence_count = 0;
+ return false;
+ }
- if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
- music_all_notes_off();
- if (music_sequence_recording) { // was recording
- music_sequence_recorded = true;
+ if (keycode == KC_LALT) { // Stop recording/playing
+ music_all_notes_off();
+ if (music_sequence_recording) { // was recording
+ music_sequence_recorded = true;
+ }
+ music_sequence_recording = false;
+ music_sequence_playing = false;
+ return false;
}
- music_sequence_recording = false;
- music_sequence_playing = false;
- return false;
- }
- if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing
- music_all_notes_off();
- music_sequence_recording = false;
- music_sequence_playing = true;
- music_sequence_position = 0;
- music_sequence_timer = 0;
- return false;
- }
+ if (keycode == KC_LGUI && music_sequence_recorded) { // Start playing
+ music_all_notes_off();
+ music_sequence_recording = false;
+ music_sequence_playing = true;
+ music_sequence_position = 0;
+ music_sequence_timer = 0;
+ return false;
+ }
- if (keycode == KC_UP) {
- if (record->event.pressed)
- music_sequence_interval-=10;
- return false;
- }
+ if (keycode == KC_UP) {
+ music_sequence_interval-=10;
+ return false;
+ }
- if (keycode == KC_DOWN) {
- if (record->event.pressed)
- music_sequence_interval+=10;
- return false;
+ if (keycode == KC_DOWN) {
+ music_sequence_interval+=10;
+ return false;
+ }
}
- #define MUSIC_MODE_GUITAR
-
- #ifdef MUSIC_MODE_CHROMATIC
- uint8_t note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
- #elif defined(MUSIC_MODE_GUITAR)
- uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
- #elif defined(MUSIC_MODE_VIOLIN)
- uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
- #else
- uint8_t note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
- #endif
+ uint8_t note;
+ if (music_mode == MUSIC_MODE_CHROMATIC)
+ note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
+ else if (music_mode == MUSIC_MODE_GUITAR)
+ note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
+ else if (music_mode == MUSIC_MODE_VIOLIN)
+ note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
+ else if (music_mode == MUSIC_MODE_MAJOR)
+ note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
+ else
+ note = music_starting_note;
if (record->event.pressed) {
music_noteon(note);
@@ -154,7 +189,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
music_noteoff(note);
}
- if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
+ if (MUSIC_MASK)
return false;
}
@@ -175,12 +210,26 @@ void music_toggle(void) {
void music_on(void) {
music_activated = 1;
+ #ifdef AUDIO_ENABLE
+ PLAY_SONG(music_on_song);
+ #endif
music_on_user();
}
void music_off(void) {
- music_activated = 0;
music_all_notes_off();
+ music_activated = 0;
+ #ifdef AUDIO_ENABLE
+ PLAY_SONG(music_off_song);
+ #endif
+}
+
+void music_mode_cycle(void) {
+ music_all_notes_off();
+ music_mode = (music_mode + 1) % NUMBER_OF_MODES;
+ #ifdef AUDIO_ENABLE
+ PLAY_SONG(music_mode_songs[music_mode]);
+ #endif
}
void matrix_scan_music(void) {
diff --git a/quantum/process_keycode/process_music.h b/quantum/process_keycode/process_music.h
index 8dfbf041f4..ee027197c2 100644
--- a/quantum/process_keycode/process_music.h
+++ b/quantum/process_keycode/process_music.h
@@ -21,6 +21,14 @@
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
+enum music_modes {
+ MUSIC_MODE_CHROMATIC,
+ MUSIC_MODE_GUITAR,
+ MUSIC_MODE_VIOLIN,
+ MUSIC_MODE_MAJOR,
+ NUMBER_OF_MODES
+};
+
bool process_music(uint16_t keycode, keyrecord_t *record);
bool is_music_on(void);
@@ -31,6 +39,7 @@ void music_off(void);
void music_on_user(void);
void music_scale_user(void);
void music_all_notes_off(void);
+void music_mode_cycle(void);
void matrix_scan_music(void);
diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c
new file mode 100644
index 0000000000..71e5e8ff1c
--- /dev/null
+++ b/quantum/process_keycode/process_steno.c
@@ -0,0 +1,166 @@
+/* Copyright 2017 Joseph Wasson
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "process_steno.h"
+#include "quantum_keycodes.h"
+#include "keymap_steno.h"
+#include "virtser.h"
+
+// TxBolt Codes
+#define TXB_NUL 0
+#define TXB_S_L 0b00000001
+#define TXB_T_L 0b00000010
+#define TXB_K_L 0b00000100
+#define TXB_P_L 0b00001000
+#define TXB_W_L 0b00010000
+#define TXB_H_L 0b00100000
+#define TXB_R_L 0b01000001
+#define TXB_A_L 0b01000010
+#define TXB_O_L 0b01000100
+#define TXB_STR 0b01001000
+#define TXB_E_R 0b01010000
+#define TXB_U_R 0b01100000
+#define TXB_F_R 0b10000001
+#define TXB_R_R 0b10000010
+#define TXB_P_R 0b10000100
+#define TXB_B_R 0b10001000
+#define TXB_L_R 0b10010000
+#define TXB_G_R 0b10100000
+#define TXB_T_R 0b11000001
+#define TXB_S_R 0b11000010
+#define TXB_D_R 0b11000100
+#define TXB_Z_R 0b11001000
+#define TXB_NUM 0b11010000
+
+#define TXB_GRP0 0b00000000
+#define TXB_GRP1 0b01000000
+#define TXB_GRP2 0b10000000
+#define TXB_GRP3 0b11000000
+#define TXB_GRPMASK 0b11000000
+
+#define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6)
+
+#define BOLT_STATE_SIZE 4
+#define GEMINI_STATE_SIZE 6
+
+uint8_t state[MAX(BOLT_STATE_SIZE, GEMINI_STATE_SIZE)] = {0};
+uint8_t pressed = 0;
+steno_mode_t mode;
+
+uint8_t boltmap[64] = {
+ TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM,
+ TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L,
+ TXB_R_L, TXB_A_L, TXB_O_L, TXB_STR, TXB_STR, TXB_NUL, TXB_NUL,
+ TXB_NUL, TXB_STR, TXB_STR, TXB_E_R, TXB_U_R, TXB_F_R, TXB_R_R,
+ TXB_P_R, TXB_B_R, TXB_L_R, TXB_G_R, TXB_T_R, TXB_S_R, TXB_D_R,
+ TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_Z_R
+};
+
+#define BOLTMAP_MASK (sizeof(boltmap) - 1)
+
+
+void steno_clear_state(void) {
+ memset(state, 0, sizeof(state));
+}
+
+void steno_init() {
+ if (!eeconfig_is_enabled()) {
+ eeconfig_init();
+ }
+ mode = eeprom_read_byte(EECONFIG_STENOMODE);
+}
+
+void steno_set_mode(steno_mode_t new_mode) {
+ steno_clear_state();
+ mode = new_mode;
+ eeprom_update_byte(EECONFIG_STENOMODE, mode);
+}
+
+void send_steno_state(uint8_t size, bool send_empty) {
+ for (uint8_t i = 0; i < size; ++i) {
+ if (state[i] || send_empty) {
+ virtser_send(state[i]);
+ }
+ }
+ steno_clear_state();
+}
+
+bool update_state_bolt(uint8_t key) {
+ uint8_t boltcode = boltmap[key];
+ state[TXB_GET_GROUP(boltcode)] |= boltcode;
+ return false;
+}
+
+bool send_state_bolt(void) {
+ send_steno_state(BOLT_STATE_SIZE, false);
+ virtser_send(0); // terminating byte
+ return false;
+}
+
+bool update_state_gemini(uint8_t key) {
+ state[key / 7] |= 1 << (6 - (key % 7));
+ return false;
+}
+
+bool send_state_gemini(void) {
+ state[0] |= 0x80; // Indicate start of packet
+ send_steno_state(GEMINI_STATE_SIZE, true);
+ return false;
+}
+
+bool process_steno(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case QK_STENO_BOLT:
+ if (IS_PRESSED(record->event)) {
+ steno_set_mode(STENO_MODE_BOLT);
+ }
+ return false;
+
+ case QK_STENO_GEMINI:
+ if (IS_PRESSED(record->event)) {
+ steno_set_mode(STENO_MODE_GEMINI);
+ }
+ return false;
+
+ case STN__MIN...STN__MAX:
+ if (IS_PRESSED(record->event)) {
+ uint8_t key = keycode - QK_STENO;
+ ++pressed;
+ switch(mode) {
+ case STENO_MODE_BOLT:
+ return update_state_bolt(key);
+ case STENO_MODE_GEMINI:
+ return update_state_gemini(key);
+ default:
+ return false;
+ }
+ } else {
+ --pressed;
+ if (pressed <= 0) {
+ pressed = 0;
+ switch(mode) {
+ case STENO_MODE_BOLT:
+ return send_state_bolt();
+ case STENO_MODE_GEMINI:
+ return send_state_gemini();
+ default:
+ return false;
+ }
+ }
+ }
+
+ }
+ return true;
+}
diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h
new file mode 100644
index 0000000000..3bbcbeaaf8
--- /dev/null
+++ b/quantum/process_keycode/process_steno.h
@@ -0,0 +1,31 @@
+/* Copyright 2017 Joseph Wasson
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef PROCESS_STENO_H
+#define PROCESS_STENO_H
+
+#include "quantum.h"
+
+#if defined(STENO_ENABLE) && !defined(VIRTSER_ENABLE)
+ #error "must have virtser enabled to use steno"
+#endif
+
+typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t;
+
+bool process_steno(uint16_t keycode, keyrecord_t *record);
+void steno_init(void);
+void steno_set_mode(steno_mode_t mode);
+
+#endif \ No newline at end of file
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index 4fd45810bb..00870c4e7f 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -41,6 +41,24 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) {
}
}
+void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data) {
+ qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
+
+ if (state->count == 1) {
+ register_code16 (pair->kc);
+ } else if (state->count == 2) {
+ layer_invert (pair->layer);
+ }
+}
+
+void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data) {
+ qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
+
+ if (state->count == 1) {
+ unregister_code16 (pair->kc);
+ }
+}
+
static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state,
void *user_data,
qk_tap_dance_user_fn_t fn)
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index f42c154a05..37a27c5366 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -54,11 +54,22 @@ typedef struct
uint16_t kc2;
} qk_tap_dance_pair_t;
+typedef struct
+{
+ uint16_t kc;
+ uint8_t layer;
+} qk_tap_dance_dual_role_t;
+
#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \
.fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \
.user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \
}
+#define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) { \
+ .fn = { NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, \
+ .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer }), \
+ }
+
#define ACTION_TAP_DANCE_FN(user_fn) { \
.fn = { NULL, user_fn, NULL }, \
.user_data = NULL, \
@@ -86,6 +97,9 @@ void reset_tap_dance (qk_tap_dance_state_t *state);
void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data);
void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data);
+void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data);
+void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data);
+
#else
#define TD(n) KC_NO