summary refs log tree commit diff
path: root/quantum/process_keycode/process_music.c
diff options
context:
space:
mode:
authorRyan Ascheman <rascheman@groupon.com>2016-10-18 12:42:02 -0700
committerRyan Ascheman <rascheman@groupon.com>2016-10-18 12:42:02 -0700
commit55b8b8477cc6aee82dfe6792eea4e589cac433d5 (patch)
treece5bfbd1b0ee59dbffdc2044bcf90c89614392ed /quantum/process_keycode/process_music.c
parentd1c70328f8d8ded6ce1e5422b468fc41ef315e7d (diff)
parent04df74f6360464661bcc1e6794e9fd3549084390 (diff)
Merge remote-tracking branch 'upstream/master'
* upstream/master: (1239 commits)
  Update ez.c
  removes planck/rev3 temporarily
  Move hand_swap_config to ez.c, removes error for infinity
  Update Makefile
  ergodox: Update algernon's keymap to v1.9
  Added VS Code dir to .gitignore
  Support the Pegasus Hoof controller.
  [Jack & Erez] Simplifies and documents TO
  add readme
  use wait_ms instead of _delay_ms
  add messenger
  init keymap
  Add example keymap
  Adding whiskey_tango_foxtrot_capslock ergodox keymap
  Unicode map framework. Allow unicode up to 0xFFFFF using separate mapping table
  CIE 1931 dim curve
  Apply the dim curve to the RGB output
  Update the Cluecard readme files
  Tune snake and knight intervals for Cluecard
  Tunable RGB light intervals
  ...
Diffstat (limited to 'quantum/process_keycode/process_music.c')
-rw-r--r--quantum/process_keycode/process_music.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c
new file mode 100644
index 0000000000..2d52e47a72
--- /dev/null
+++ b/quantum/process_keycode/process_music.c
@@ -0,0 +1,176 @@
+#include "process_music.h"
+
+bool music_activated = false;
+uint8_t starting_note = 0x0C;
+int offset = 7;
+
+// music sequencer
+static bool music_sequence_recording = false;
+static bool music_sequence_recorded = 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_music(uint16_t keycode, keyrecord_t *record) {
+
+    if (keycode == AU_ON && record->event.pressed) {
+      audio_on();
+      return false;
+    }
+
+    if (keycode == AU_OFF && record->event.pressed) {
+      audio_off();
+      return false;
+    }
+
+    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_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();
+        music_scale_user();
+        return false;
+    }
+
+    if (keycode == MUV_DE && record->event.pressed) {
+        voice_deiterate();
+        music_scale_user();
+        return false;
+    }
+
+    if (music_activated) {
+
+      if (keycode == KC_LCTL && record->event.pressed) { // Start recording
+        stop_all_notes();
+        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
+        stop_all_notes();
+        if (music_sequence_recording) { // was recording
+          music_sequence_recorded = true;
+        }
+        music_sequence_recording = false;
+        music_sequence_playing = false;
+        return false;
+      }
+
+      if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // 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, -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) {
+          music_sequence[music_sequence_count] = freq;
+          music_sequence_count++;
+        }
+      } else {
+        stop_note(freq);
+      }
+
+      if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
+        return false;
+    }
+  return true;
+}
+
+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();
+}
+
+
+__attribute__ ((weak))
+void music_on_user() {}
+
+__attribute__ ((weak))
+void audio_on_user() {}
+
+__attribute__ ((weak))
+void music_scale_user() {}
+
+void matrix_scan_music(void) {
+  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;
+    }
+  }
+}