]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - quantum/quantum.c
Merge pull request #297 from gid0/master
[qmk_firmware.git] / quantum / quantum.c
index cd7fdbb7fe2d20889060b33ca6e08a76b1cd1b7f..d9aaafd616ef386abd0e69be35a620fa4263ac43 100644 (file)
@@ -1,4 +1,5 @@
 #include "quantum.h"
+#include "timer.h"
 
 __attribute__ ((weak))
 void matrix_init_kb(void) {}
@@ -11,17 +12,43 @@ bool process_action_kb(keyrecord_t *record) {
   return true;
 }
 
+__attribute__ ((weak))
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+  return process_record_user(keycode, record);
+}
+
+__attribute__ ((weak))
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  return true;
+}
+
 __attribute__ ((weak))
 void leader_start(void) {}
 
 __attribute__ ((weak))
 void leader_end(void) {}
 
+uint8_t starting_note = 0x0C;
+int offset = 7;
+
+
 #ifdef AUDIO_ENABLE
-  uint8_t starting_note = 0x0C;
-  int offset = 0;
   bool music_activated = false;
-  float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
+
+// music sequencer
+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;
+
+#endif
+
+#ifdef MIDI_ENABLE
+  bool midi_activated = false;
 #endif
 
 // Leader key stuff
@@ -39,6 +66,12 @@ uint8_t chord_keys[CHORDING_MAX] = {0};
 uint8_t chord_key_count = 0;
 uint8_t chord_key_down = 0;
 
+#ifdef UNICODE_ENABLE
+  static uint8_t input_mode;
+#endif
+
+static bool shift_interrupted[2] = {0, 0};
+
 bool keys_chord(uint8_t keys[]) {
   uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
   bool pass = true;
@@ -61,16 +94,27 @@ 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;
+#ifdef UNICODE_ENABLE
 
-static uint16_t music_sequence_timer = 0;
-static uint16_t music_sequence_interval = 100;
+uint16_t hex_to_keycode(uint8_t hex)
+{
+  if (hex == 0x0) {
+    return KC_0;
+  } else if (hex < 0xA) {
+    return KC_1 + (hex - 0x1);
+  } else {
+    return KC_A + (hex - 0xA);
+  }
+}
+
+void set_unicode_mode(uint8_t os_target)
+{
+  input_mode = os_target;
+}
 
-bool process_action_quantum(keyrecord_t *record) {
+#endif
+
+bool process_record_quantum(keyrecord_t *record) {
 
   /* This gets the keycode from the key pressed */
   keypos_t key = record->event.key;
@@ -90,10 +134,96 @@ bool process_action_quantum(keyrecord_t *record) {
     keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
   #endif
 
+  if (!process_record_kb(keycode, record))
+    return false;
+
+    // This is how you use actions here
+    // if (keycode == KC_LEAD) {
+    //   action_t action;
+    //   action.code = ACTION_DEFAULT_LAYER_SET(0);
+    //   process_action(record, action);
+    //   return false;
+    // }
+
+  #ifdef MIDI_ENABLE
+    if (keycode == MI_ON && record->event.pressed) {
+      midi_activated = true;
+      music_scale_user();
+      return false;
+    }
+
+    if (keycode == MI_OFF && record->event.pressed) {
+      midi_activated = false;
+      midi_send_cc(&midi_device, 0, 0x7B, 0);
+      return false;
+    }
+
+    if (midi_activated) {
+      if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
+          if (record->event.pressed) {
+              starting_note++; // Change key
+              midi_send_cc(&midi_device, 0, 0x7B, 0);
+              // midi_send_cc(&midi_device, 1, 0x7B, 0);
+              // midi_send_cc(&midi_device, 2, 0x7B, 0);
+              // midi_send_cc(&midi_device, 3, 0x7B, 0);
+              // midi_send_cc(&midi_device, 4, 0x7B, 0);
+          }
+          return false;
+      }
+      if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
+          if (record->event.pressed) {
+              starting_note--; // Change key
+              midi_send_cc(&midi_device, 0, 0x7B, 0);
+              // midi_send_cc(&midi_device, 1, 0x7B, 0);
+              // midi_send_cc(&midi_device, 2, 0x7B, 0);
+              // midi_send_cc(&midi_device, 3, 0x7B, 0);
+              // midi_send_cc(&midi_device, 4, 0x7B, 0);
+          }
+          return false;
+      }
+      if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
+          offset++; // Change scale
+          midi_send_cc(&midi_device, 0, 0x7B, 0);
+          // midi_send_cc(&midi_device, 1, 0x7B, 0);
+          // midi_send_cc(&midi_device, 2, 0x7B, 0);
+          // midi_send_cc(&midi_device, 3, 0x7B, 0);
+          // midi_send_cc(&midi_device, 4, 0x7B, 0);
+          return false;
+      }
+      if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
+          offset--; // Change scale
+          midi_send_cc(&midi_device, 0, 0x7B, 0);
+          // midi_send_cc(&midi_device, 1, 0x7B, 0);
+          // midi_send_cc(&midi_device, 2, 0x7B, 0);
+          // midi_send_cc(&midi_device, 3, 0x7B, 0);
+          // midi_send_cc(&midi_device, 4, 0x7B, 0);
+          return false;
+      }
+      // basic
+      // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row);
+      // advanced
+      // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row);
+      // guitar
+      uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row);
+      // violin
+      // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row);
+
+      if (record->event.pressed) {
+        // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
+        midi_send_noteon(&midi_device, 0, note, 127);
+      } else {
+        // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
+        midi_send_noteoff(&midi_device, 0, note, 127);
+      }
+
+      if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
+        return false;
+    }
+  #endif
+
   #ifdef AUDIO_ENABLE
     if (keycode == AU_ON && record->event.pressed) {
       audio_on();
-      audio_on_callback();
       return false;
     }
 
@@ -102,31 +232,53 @@ bool process_action_quantum(keyrecord_t *record) {
       return false;
     }
 
-    if (keycode == MU_ON && record->event.pressed) {
-      music_activated = true;
-      PLAY_NOTE_ARRAY(music_scale, false, 0);
+    if (keycode == AU_TOG && record->event.pressed) {
+        if (is_audio_on())
+        {
+            audio_off();
+        }
+        else
+        {
+            audio_on();
+        }
       return false;
     }
 
+    if (keycode == MU_ON && record->event.pressed) {
+        music_on();
+        return false;
+    }
+
     if (keycode == MU_OFF && record->event.pressed) {
-      music_activated = false;
-      stop_all_notes();
-      return false;
+        music_off();
+        return false;
+    }
+
+    if (keycode == MU_TOG && record->event.pressed) {
+        if (music_activated)
+        {
+            music_off();
+        }
+        else
+        {
+            music_on();
+        }
+        return false;
     }
 
     if (keycode == MUV_IN && record->event.pressed) {
-      voice_iterate();
-      PLAY_NOTE_ARRAY(music_scale, false, 0);
-      return false;
+        voice_iterate();
+        music_scale_user();
+        return false;
     }
 
     if (keycode == MUV_DE && record->event.pressed) {
-      voice_deiterate();
-      PLAY_NOTE_ARRAY(music_scale, false, 0);
-      return false;
+        voice_deiterate();
+        music_scale_user();
+        return false;
     }
 
-    if (music_activated) {   
+    if (music_activated) {
 
       if (keycode == KC_LCTL && record->event.pressed) { // Start recording
         stop_all_notes();
@@ -135,12 +287,14 @@ bool process_action_quantum(keyrecord_t *record) {
         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;
@@ -152,16 +306,17 @@ bool process_action_quantum(keyrecord_t *record) {
 
       if (keycode == KC_UP) {
         if (record->event.pressed)
-          music_sequence_interval-=10;
+            music_sequence_interval-=10;
         return false;
       }
+    
       if (keycode == KC_DOWN) {
         if (record->event.pressed)
-          music_sequence_interval+=10;
+            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));
+      float freq = ((float)220.0)*pow(2.0, -5.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(freq, 0xF);
         if (music_sequence_recording) {
@@ -170,15 +325,13 @@ bool process_action_quantum(keyrecord_t *record) {
         }
       } else {
         stop_note(freq);
-      }  
+      }
 
       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
         return false;
     }
   #endif
 
-
-
 #ifndef DISABLE_LEADER
   // Leader key set-up
   if (record->event.pressed) {
@@ -239,6 +392,83 @@ bool process_action_quantum(keyrecord_t *record) {
 
 #endif
 
+#ifdef UNICODE_ENABLE
+
+  if (keycode > UNICODE(0) && record->event.pressed) {
+    uint16_t unicode = keycode & 0x7FFF;
+    switch(input_mode) {
+      case UC_OSX:
+        register_code(KC_LALT);
+        break;
+      case UC_LNX:
+        register_code(KC_LCTL);
+        register_code(KC_LSFT);
+        register_code(KC_U);
+        unregister_code(KC_U);
+        break;
+      case UC_WIN:
+        register_code(KC_LALT);
+        register_code(KC_PPLS);
+        unregister_code(KC_PPLS);
+        break;
+    }
+    for(int i = 3; i >= 0; i--) {
+        uint8_t digit = ((unicode >> (i*4)) & 0xF);
+        register_code(hex_to_keycode(digit));
+        unregister_code(hex_to_keycode(digit));
+    }
+    switch(input_mode) {
+      case UC_OSX:
+      case UC_WIN:
+        unregister_code(KC_LALT);
+        break;
+      case UC_LNX:
+        unregister_code(KC_LCTL);
+        unregister_code(KC_LSFT);
+        break;
+    }
+  }
+
+#endif
+
+  switch(keycode) {
+    case KC_LSPO: {
+                    if (record->event.pressed) {
+                      shift_interrupted[0] = false;
+                      register_mods(MOD_BIT(KC_LSFT));
+                    }
+                    else {
+                      if (!shift_interrupted[0]) {
+                        register_code(KC_9);
+                        unregister_code(KC_9);
+                      }
+                      unregister_mods(MOD_BIT(KC_LSFT));
+                    }
+                    return false;
+                    break;
+                  }
+
+    case KC_RSPC: {
+                    if (record->event.pressed) {
+                      shift_interrupted[1] = false;
+                      register_mods(MOD_BIT(KC_RSFT));
+                    }
+                    else {
+                      if (!shift_interrupted[1]) {
+                        register_code(KC_0);
+                        unregister_code(KC_0);
+                      }
+                      unregister_mods(MOD_BIT(KC_RSFT));
+                    }
+                    return false;
+                    break;
+                  }
+    default: {
+               shift_interrupted[0] = true;
+               shift_interrupted[1] = true;
+               break;
+             }
+  }
 
   return process_action_kb(record);
 }
@@ -259,5 +489,51 @@ void matrix_scan_quantum() {
   }
 
   #endif
+
   matrix_scan_kb();
-}
\ No newline at end of file
+}
+#ifdef AUDIO_ENABLE
+  bool is_music_on(void) {
+      return (music_activated != 0);
+  }
+
+  void music_toggle(void) {
+      if (!music_activated) {
+          music_on();
+      } else {
+          music_off();
+      }
+  }
+
+  void music_on(void) {
+      music_activated = 1;
+      music_on_user();
+  }
+
+  void music_off(void) {
+      music_activated = 0;
+      stop_all_notes();
+  }
+
+#endif
+
+//------------------------------------------------------------------------------
+// Override these functions in your keymap file to play different tunes on 
+// different events such as startup and bootloader jump
+
+__attribute__ ((weak))
+void startup_user() {}
+
+__attribute__ ((weak))
+void shutdown_user() {}
+
+__attribute__ ((weak))
+void music_on_user() {}
+
+__attribute__ ((weak))
+void audio_on_user() {}
+
+__attribute__ ((weak))
+void music_scale_user() {}
+
+//------------------------------------------------------------------------------