]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/process_keycode/process_music.c
Moves features to their own files (process_*), adds tap dance feature (#460)
[qmk_firmware.git] / quantum / process_keycode / process_music.c
1 #include "process_music.h"
2
3 bool music_activated = false;
4 uint8_t starting_note = 0x0C;
5 int offset = 7;
6
7 // music sequencer
8 static bool music_sequence_recording = false;
9 static bool music_sequence_playing = false;
10 static float music_sequence[16] = {0};
11 static uint8_t music_sequence_count = 0;
12 static uint8_t music_sequence_position = 0;
13
14 static uint16_t music_sequence_timer = 0;
15 static uint16_t music_sequence_interval = 100;
16
17 bool process_music(uint16_t keycode, keyrecord_t *record) {
18
19     if (keycode == AU_ON && record->event.pressed) {
20       audio_on();
21       return false;
22     }
23
24     if (keycode == AU_OFF && record->event.pressed) {
25       audio_off();
26       return false;
27     }
28
29     if (keycode == AU_TOG && record->event.pressed) {
30         if (is_audio_on())
31         {
32             audio_off();
33         }
34         else
35         {
36             audio_on();
37         }
38       return false;
39     }
40
41     if (keycode == MU_ON && record->event.pressed) {
42         music_on();
43         return false;
44     }
45
46     if (keycode == MU_OFF && record->event.pressed) {
47         music_off();
48         return false;
49     }
50
51     if (keycode == MU_TOG && record->event.pressed) {
52         if (music_activated)
53         {
54             music_off();
55         }
56         else
57         {
58             music_on();
59         }
60         return false;
61     }
62
63     if (keycode == MUV_IN && record->event.pressed) {
64         voice_iterate();
65         music_scale_user();
66         return false;
67     }
68
69     if (keycode == MUV_DE && record->event.pressed) {
70         voice_deiterate();
71         music_scale_user();
72         return false;
73     }
74
75     if (music_activated) {
76
77       if (keycode == KC_LCTL && record->event.pressed) { // Start recording
78         stop_all_notes();
79         music_sequence_recording = true;
80         music_sequence_playing = false;
81         music_sequence_count = 0;
82         return false;
83       }
84
85       if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
86         stop_all_notes();
87         music_sequence_recording = false;
88         music_sequence_playing = false;
89         return false;
90       }
91
92       if (keycode == KC_LGUI && record->event.pressed) { // Start playing
93         stop_all_notes();
94         music_sequence_recording = false;
95         music_sequence_playing = true;
96         music_sequence_position = 0;
97         music_sequence_timer = 0;
98         return false;
99       }
100
101       if (keycode == KC_UP) {
102         if (record->event.pressed)
103             music_sequence_interval-=10;
104         return false;
105       }
106
107       if (keycode == KC_DOWN) {
108         if (record->event.pressed)
109             music_sequence_interval+=10;
110         return false;
111       }
112
113       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));
114       if (record->event.pressed) {
115         play_note(freq, 0xF);
116         if (music_sequence_recording) {
117           music_sequence[music_sequence_count] = freq;
118           music_sequence_count++;
119         }
120       } else {
121         stop_note(freq);
122       }
123
124       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
125         return false;
126     }
127   return true;
128 }
129
130 bool is_music_on(void) {
131     return (music_activated != 0);
132 }
133
134 void music_toggle(void) {
135     if (!music_activated) {
136         music_on();
137     } else {
138         music_off();
139     }
140 }
141
142 void music_on(void) {
143     music_activated = 1;
144     music_on_user();
145 }
146
147 void music_off(void) {
148     music_activated = 0;
149     stop_all_notes();
150 }
151
152
153 __attribute__ ((weak))
154 void music_on_user() {}
155
156 __attribute__ ((weak))
157 void audio_on_user() {}
158
159 __attribute__ ((weak))
160 void music_scale_user() {}
161
162 void matrix_scan_music(void) {
163   if (music_sequence_playing) {
164     if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
165       music_sequence_timer = timer_read();
166       stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
167       play_note(music_sequence[music_sequence_position], 0xF);
168       music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
169     }
170   }
171 }