]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
adds a sequencer to the music mode (#330)
authorJack Humbert <jack.humb@gmail.com>
Sun, 15 May 2016 04:40:59 +0000 (00:40 -0400)
committerJack Humbert <jack.humb@gmail.com>
Sun, 15 May 2016 04:40:59 +0000 (00:40 -0400)
* implements leader key for planck experimental

* allows override of leader timeout

* adds ability to use the leader key in seq

* fixes leader keycode

* adds chording prototype

* fixes keycode detection

* moves music mode to quantum.c

* disables chording by default

* adds music sequencer functionality

* implements audio/music functions in quantum.c

* Merge branch 'master' into process-record

keyboard/planck/keymaps/experimental/keymap.c
quantum/audio/audio.c
quantum/audio/audio.h
quantum/keymap_common.h
quantum/quantum.c

index 8dc158c73f61f22d100808c652790b8ad94744fc..8bc7334c9aab2dda1f47e55046dd0a006b245013 100644 (file)
@@ -20,8 +20,7 @@ extern keymap_config_t keymap_config;
 #define _DVORAK 2
 #define _LOWER 3
 #define _RAISE 4
-#define _MUSIC 5
-#define _PLOVER 6
+#define _PLOVER 5
 #define _ADJUST 16
 
 // Macro name shortcuts
@@ -31,12 +30,6 @@ extern keymap_config_t keymap_config;
 #define LOWER M(_LOWER)
 #define RAISE M(_RAISE)
 #define M_BL 5
-#define AUD_OFF M(6)
-#define AUD_ON M(7)
-#define MUS_OFF M(8)
-#define MUS_ON M(9)
-#define VC_IN M(10)
-#define VC_DE M(11)
 #define PLOVER M(12)
 #define EXT_PLV M(13)
 
@@ -136,16 +129,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
   {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
 },
 
-/* Music (reserved for process_action_user)
- *
- */
-[_MUSIC] = {
-  {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX},
-  {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX},
-  {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX},
-  {XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, LOWER,   XXXXXXX, XXXXXXX, RAISE,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX}
-},
-
 /* Plover layer (http://opensteno.org)
  * ,-----------------------------------------------------------------------------------.
  * |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |
@@ -178,8 +161,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  */
 [_ADJUST] = {
   {_______, RESET,   _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
-  {_______, _______, _______, AUD_ON,  AUD_OFF, AG_NORM, AG_SWAP, QWERTY,  COLEMAK, DVORAK,  PLOVER,  _______},
-  {_______, VC_DE,   VC_IN,   MUS_ON,  MUS_OFF, _______, _______, _______, _______, _______, _______, _______},
+  {_______, _______, _______, AU_ON,   AU_OFF,  AG_NORM, AG_SWAP, QWERTY,  COLEMAK, DVORAK,  PLOVER,  _______},
+  {_______, MUV_DE,  MUV_IN,  MU_ON,   MU_OFF,  _______, _______, _______, _______, _______, _______, _______},
   {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
 }
 
@@ -205,7 +188,6 @@ float tone_colemak[][2]    = SONG(COLEMAK_SOUND);
 float tone_plover[][2]     = SONG(PLOVER_SOUND);
 float tone_plover_gb[][2]  = SONG(PLOVER_GOODBYE_SOUND);
 
-float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
 float goodbye[][2] = SONG(GOODBYE_SOUND);
 #endif
 
@@ -274,53 +256,6 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
             unregister_code(KC_RSFT);
           }
         break;
-        case 6:
-          if (record->event.pressed) {
-            #ifdef AUDIO_ENABLE
-              audio_off();
-            #endif
-          }
-        break;
-        case 7:
-          if (record->event.pressed) {
-            #ifdef AUDIO_ENABLE
-              audio_on();
-              PLAY_NOTE_ARRAY(tone_startup, false, 0);
-            #endif
-          }
-        break;
-        case 8:
-          if (record->event.pressed) {
-            #ifdef AUDIO_ENABLE
-              music_activated = false;
-              stop_all_notes();
-            #endif
-          }
-        break;
-        case 9:
-          if (record->event.pressed) {
-            #ifdef AUDIO_ENABLE
-              PLAY_NOTE_ARRAY(music_scale, false, 0);
-              music_activated = true;
-            #endif
-          }
-        break;
-        case 10:
-          if (record->event.pressed) {
-            #ifdef AUDIO_ENABLE
-              voice_iterate();
-              PLAY_NOTE_ARRAY(music_scale, false, 0);
-            #endif
-          }
-        break;
-        case 11:
-          if (record->event.pressed) {
-            #ifdef AUDIO_ENABLE
-              voice_deiterate();
-              PLAY_NOTE_ARRAY(music_scale, false, 0);
-            #endif
-          }
-        break;
         case 12:
           if (record->event.pressed) {
             #ifdef AUDIO_ENABLE
@@ -330,7 +265,6 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
             layer_off(_RAISE);
             layer_off(_LOWER);
             layer_off(_ADJUST);
-            layer_off(_MUSIC);
             layer_on(_PLOVER);
             if (!eeconfig_is_enabled()) {
                 eeconfig_init();
index 27b64f8c96224da8b35e6b4a5ecb45f9d9ed618c..243f49f0eefdc188100aee7ac35fe9cfc810a137 100644 (file)
@@ -478,12 +478,11 @@ void increase_tempo(uint8_t tempo_change) {
 // Override these functions in your keymap file to play different tunes on
 // startup and bootloader jump
 __attribute__ ((weak))
-void play_startup_tone()
-{
-}
+void play_startup_tone() {}
 
 __attribute__ ((weak))
-void play_goodbye_tone()
-{
-}
+void play_goodbye_tone() {}
+
+__attribute__ ((weak))
+void audio_on_callback(void) {}
 //------------------------------------------------------------------------------
index 4ba879bbb1d25b8b0e2d09723005e3821b4e5d04..fe85061318ed0cb9936b179710d3cb2d438baa35 100644 (file)
@@ -29,6 +29,7 @@ bool is_audio_on(void);
 void audio_toggle(void);
 void audio_on(void);
 void audio_off(void);
+void audio_on_callback(void);
 
 // Vibrato rate functions
 
index 2ad1ba6c603ad84d4ed8896aa9e1d1ee2e03e45c..4107d575bef5cd32146cfabcee6161f473d55026 100644 (file)
@@ -191,8 +191,6 @@ extern const uint16_t fn_actions[];
 
 #define RESET 0x5000
 #define DEBUG 0x5001
-#define KC_LEAD 0x5014
-
 
 // MAGIC keycodes
 #define MAGIC_SWAP_CONTROL_CAPSLOCK      0x5002
@@ -217,6 +215,19 @@ extern const uint16_t fn_actions[];
 #define AG_SWAP MAGIC_SWAP_ALT_GUI
 #define AG_NORM MAGIC_UNSWAP_ALT_GUI
 
+#define KC_LEAD 0x5014
+
+// Audio on/off
+#define AU_ON  0x5020
+#define AU_OFF 0x5021
+
+// Music mode on/off
+#define MU_ON  0x5022
+#define MU_OFF 0x5023
+
+// Music voice iterate
+#define MUV_IN 0x5024
+#define MUV_DE 0x5025
 
 // GOTO layer - 16 layers max
 // when:
index e274d846f2614b13852b828cc91226635ace5143..cd7fdbb7fe2d20889060b33ca6e08a76b1cd1b7f 100644 (file)
@@ -21,6 +21,7 @@ void leader_end(void) {}
   uint8_t starting_note = 0x0C;
   int offset = 0;
   bool music_activated = false;
+  float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
 #endif
 
 // Leader key stuff
@@ -60,6 +61,15 @@ bool keys_chord(uint8_t keys[]) {
   return (pass && (in == keys_size));
 }
 
+static bool music_sequence_recording = false;
+static bool music_sequence_playing = false;
+static float music_sequence[16] = {0};
+static uint8_t music_sequence_count = 0;
+static uint8_t music_sequence_position = 0;
+
+static uint16_t music_sequence_timer = 0;
+static uint16_t music_sequence_interval = 100;
+
 bool process_action_quantum(keyrecord_t *record) {
 
   /* This gets the keycode from the key pressed */
@@ -81,12 +91,87 @@ bool process_action_quantum(keyrecord_t *record) {
   #endif
 
   #ifdef AUDIO_ENABLE
-    if (music_activated) {
+    if (keycode == AU_ON && record->event.pressed) {
+      audio_on();
+      audio_on_callback();
+      return false;
+    }
+
+    if (keycode == AU_OFF && record->event.pressed) {
+      audio_off();
+      return false;
+    }
+
+    if (keycode == MU_ON && record->event.pressed) {
+      music_activated = true;
+      PLAY_NOTE_ARRAY(music_scale, false, 0);
+      return false;
+    }
+
+    if (keycode == MU_OFF && record->event.pressed) {
+      music_activated = false;
+      stop_all_notes();
+      return false;
+    }
+
+    if (keycode == MUV_IN && record->event.pressed) {
+      voice_iterate();
+      PLAY_NOTE_ARRAY(music_scale, false, 0);
+      return false;
+    }
+
+    if (keycode == MUV_DE && record->event.pressed) {
+      voice_deiterate();
+      PLAY_NOTE_ARRAY(music_scale, false, 0);
+      return false;
+    }
+
+    if (music_activated) {   
+
+      if (keycode == KC_LCTL && record->event.pressed) { // Start recording
+        stop_all_notes();
+        music_sequence_recording = true;
+        music_sequence_playing = false;
+        music_sequence_count = 0;
+        return false;
+      }
+      if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
+        stop_all_notes();
+        music_sequence_recording = false;
+        music_sequence_playing = false;
+        return false;
+      }
+      if (keycode == KC_LGUI && record->event.pressed) { // Start playing
+        stop_all_notes();
+        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_DOWN) {
+        if (record->event.pressed)
+          music_sequence_interval+=10;
+        return false;
+      }
+
+      float freq = ((float)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row));
       if (record->event.pressed) {
-          play_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
+        play_note(freq, 0xF);
+        if (music_sequence_recording) {
+          music_sequence[music_sequence_count] = freq;
+          music_sequence_count++;
+        }
       } else {
-          stop_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
-      }
+        stop_note(freq);
+      }  
+
       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
         return false;
     }
@@ -163,5 +248,16 @@ void matrix_init_quantum() {
 }
 
 void matrix_scan_quantum() {
+  #ifdef AUDIO_ENABLE
+  if (music_sequence_playing) {
+    if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
+      music_sequence_timer = timer_read();
+      stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
+      play_note(music_sequence[music_sequence_position], 0xF);
+      music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
+    }
+  }
+
+  #endif
   matrix_scan_kb();
 }
\ No newline at end of file