]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/quantum.c
34c575af42bd15e86ef393ebdfd05baf994e619e
[qmk_firmware.git] / quantum / quantum.c
1 #include "quantum.h"
2 #include "timer.h"
3
4 __attribute__ ((weak))
5 void matrix_init_kb(void) {}
6
7 __attribute__ ((weak))
8 void matrix_scan_kb(void) {}
9
10 __attribute__ ((weak))
11 bool process_action_kb(keyrecord_t *record) {
12   return true;
13 }
14
15 __attribute__ ((weak))
16 void leader_start(void) {}
17
18 __attribute__ ((weak))
19 void leader_end(void) {}
20
21 uint8_t starting_note = 0x0C;
22 int offset = 7;
23
24 #ifdef AUDIO_ENABLE
25   bool music_activated = false;
26   float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
27
28   // music sequencer
29   static bool music_sequence_recording = false;
30   static bool music_sequence_playing = false;
31   static float music_sequence[16] = {0};
32   static uint8_t music_sequence_count = 0;
33   static uint8_t music_sequence_position = 0;
34
35   static uint16_t music_sequence_timer = 0;
36   static uint16_t music_sequence_interval = 100;
37
38 #endif
39
40 #ifdef MIDI_ENABLE
41   bool midi_activated = false;
42 #endif
43
44 // Leader key stuff
45 bool leading = false;
46 uint16_t leader_time = 0;
47
48 uint16_t leader_sequence[3] = {0, 0, 0};
49 uint8_t leader_sequence_size = 0;
50
51 // Chording stuff
52 #define CHORDING_MAX 4
53 bool chording = false;
54
55 uint8_t chord_keys[CHORDING_MAX] = {0};
56 uint8_t chord_key_count = 0;
57 uint8_t chord_key_down = 0;
58
59 #ifdef UNICODE_ENABLE
60   static uint8_t input_mode;
61 #endif
62
63 bool keys_chord(uint8_t keys[]) {
64   uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
65   bool pass = true;
66   uint8_t in = 0;
67   for (uint8_t i = 0; i < chord_key_count; i++) {
68     bool found = false;
69     for (uint8_t j = 0; j < keys_size; j++) {
70       if (chord_keys[i] == (keys[j] & 0xFF)) {
71         in++; // detects key in chord
72         found = true;
73         break;
74       }
75     }
76     if (found)
77       continue;
78     if (chord_keys[i] != 0)  {
79       pass = false; // makes sure rest are blank
80     }
81   }
82   return (pass && (in == keys_size));
83 }
84
85 #ifdef UNICODE_ENABLE
86
87 uint16_t hex_to_keycode(uint8_t hex)
88 {
89   if (hex == 0x0) {
90     return KC_0;
91   } else if (hex < 0xA) {
92     return KC_1 + (hex - 0x1);
93   } else {
94     return KC_A + (hex - 0xA);
95   }
96 }
97
98 void set_unicode_mode(uint8_t os_target)
99 {
100   input_mode = os_target;
101 }
102
103 #endif
104
105 bool process_record_quantum(keyrecord_t *record) {
106
107   /* This gets the keycode from the key pressed */
108   keypos_t key = record->event.key;
109   uint16_t keycode;
110
111   #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
112     uint8_t layer;
113
114     if (record->event.pressed) {
115       layer = layer_switch_get_layer(key);
116       update_source_layers_cache(key, layer);
117     } else {
118       layer = read_source_layers_cache(key);
119     }
120     keycode = keymap_key_to_keycode(layer, key);
121   #else
122     keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
123   #endif
124
125     // This is how you use actions here
126     // if (keycode == KC_LEAD) {
127     //   action_t action;
128     //   action.code = ACTION_DEFAULT_LAYER_SET(0);
129     //   process_action(record, action);
130     //   return false;
131     // }
132
133   #ifdef MIDI_ENABLE
134     if (keycode == MI_ON && record->event.pressed) {
135       midi_activated = true;
136       play_music_scale();
137       return false;
138     }
139
140     if (keycode == MI_OFF && record->event.pressed) {
141       midi_activated = false;
142       midi_send_cc(&midi_device, 0, 0x7B, 0);
143       return false;
144     }
145
146     if (midi_activated) {
147       if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
148           if (record->event.pressed) {
149               starting_note++; // Change key
150               midi_send_cc(&midi_device, 0, 0x7B, 0);
151               // midi_send_cc(&midi_device, 1, 0x7B, 0);
152               // midi_send_cc(&midi_device, 2, 0x7B, 0);
153               // midi_send_cc(&midi_device, 3, 0x7B, 0);
154               // midi_send_cc(&midi_device, 4, 0x7B, 0);
155           }
156           return false;
157       }
158       if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
159           if (record->event.pressed) {
160               starting_note--; // Change key
161               midi_send_cc(&midi_device, 0, 0x7B, 0);
162               // midi_send_cc(&midi_device, 1, 0x7B, 0);
163               // midi_send_cc(&midi_device, 2, 0x7B, 0);
164               // midi_send_cc(&midi_device, 3, 0x7B, 0);
165               // midi_send_cc(&midi_device, 4, 0x7B, 0);
166           }
167           return false;
168       }
169       if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
170           offset++; // Change scale
171           midi_send_cc(&midi_device, 0, 0x7B, 0);
172           // midi_send_cc(&midi_device, 1, 0x7B, 0);
173           // midi_send_cc(&midi_device, 2, 0x7B, 0);
174           // midi_send_cc(&midi_device, 3, 0x7B, 0);
175           // midi_send_cc(&midi_device, 4, 0x7B, 0);
176           return false;
177       }
178       if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
179           offset--; // Change scale
180           midi_send_cc(&midi_device, 0, 0x7B, 0);
181           // midi_send_cc(&midi_device, 1, 0x7B, 0);
182           // midi_send_cc(&midi_device, 2, 0x7B, 0);
183           // midi_send_cc(&midi_device, 3, 0x7B, 0);
184           // midi_send_cc(&midi_device, 4, 0x7B, 0);
185           return false;
186       }
187       // basic
188       // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row);
189       // advanced
190       // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row);
191       // guitar
192       uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row);
193       // violin
194       // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row);
195
196       if (record->event.pressed) {
197         // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
198         midi_send_noteon(&midi_device, 0, note, 127);
199       } else {
200         // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
201         midi_send_noteoff(&midi_device, 0, note, 127);
202       }
203
204       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
205         return false;
206     }
207   #endif
208
209   #ifdef AUDIO_ENABLE
210     if (keycode == AU_ON && record->event.pressed) {
211       audio_on();
212       return false;
213     }
214
215     if (keycode == AU_OFF && record->event.pressed) {
216       audio_off();
217       return false;
218     }
219
220     if (keycode == AU_TOG && record->event.pressed) {
221         if (is_audio_on())
222         {
223             audio_off();
224         }
225         else
226         {
227             audio_on();
228         }
229       return false;
230     }
231
232     if (keycode == MU_ON && record->event.pressed) {
233       music_on();
234       return false;
235     }
236
237     if (keycode == MU_OFF && record->event.pressed) {
238       music_off();
239       return false;
240     }
241
242     if (keycode == MU_TOG && record->event.pressed) {
243         if (music_activated)
244         {
245           music_off();
246         }
247         else
248         {
249           music_on();
250         }
251         return false;
252     }
253
254     if (keycode == MUV_IN && record->event.pressed) {
255       voice_iterate();
256       play_music_scale();
257       return false;
258     }
259
260     if (keycode == MUV_DE && record->event.pressed) {
261       voice_deiterate();
262       play_music_scale();
263       return false;
264     }
265
266     if (music_activated) {
267
268       if (keycode == KC_LCTL && record->event.pressed) { // Start recording
269         stop_all_notes();
270         music_sequence_recording = true;
271         music_sequence_playing = false;
272         music_sequence_count = 0;
273         return false;
274       }
275       if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
276         stop_all_notes();
277         music_sequence_recording = false;
278         music_sequence_playing = false;
279         return false;
280       }
281       if (keycode == KC_LGUI && record->event.pressed) { // Start playing
282         stop_all_notes();
283         music_sequence_recording = false;
284         music_sequence_playing = true;
285         music_sequence_position = 0;
286         music_sequence_timer = 0;
287         return false;
288       }
289
290       if (keycode == KC_UP) {
291         if (record->event.pressed)
292           music_sequence_interval-=10;
293         return false;
294       }
295       if (keycode == KC_DOWN) {
296         if (record->event.pressed)
297           music_sequence_interval+=10;
298         return false;
299       }
300
301       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));
302       if (record->event.pressed) {
303         play_note(freq, 0xF);
304         if (music_sequence_recording) {
305           music_sequence[music_sequence_count] = freq;
306           music_sequence_count++;
307         }
308       } else {
309         stop_note(freq);
310       }
311
312       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
313         return false;
314     }
315   #endif
316
317 #ifndef DISABLE_LEADER
318   // Leader key set-up
319   if (record->event.pressed) {
320     if (!leading && keycode == KC_LEAD) {
321       leader_start();
322       leading = true;
323       leader_time = timer_read();
324       leader_sequence_size = 0;
325       leader_sequence[0] = 0;
326       leader_sequence[1] = 0;
327       leader_sequence[2] = 0;
328       return false;
329     }
330     if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
331       leader_sequence[leader_sequence_size] = keycode;
332       leader_sequence_size++;
333       return false;
334     }
335   }
336 #endif
337
338 #define DISABLE_CHORDING
339 #ifndef DISABLE_CHORDING
340
341   if (keycode >= 0x5700 && keycode <= 0x57FF) {
342     if (record->event.pressed) {
343       if (!chording) {
344         chording = true;
345         for (uint8_t i = 0; i < CHORDING_MAX; i++)
346           chord_keys[i] = 0;
347         chord_key_count = 0;
348         chord_key_down = 0;
349       }
350       chord_keys[chord_key_count] = (keycode & 0xFF);
351       chord_key_count++;
352       chord_key_down++;
353       return false;
354     } else {
355       if (chording) {
356         chord_key_down--;
357         if (chord_key_down == 0) {
358           chording = false;
359           // Chord Dictionary
360           if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
361             register_code(KC_A);
362             unregister_code(KC_A);
363             return false;
364           }
365           for (uint8_t i = 0; i < chord_key_count; i++) {
366             register_code(chord_keys[i]);
367             unregister_code(chord_keys[i]);
368             return false;
369           }
370         }
371       }
372     }
373   }
374
375 #endif
376
377 #ifdef UNICODE_ENABLE
378
379   if (keycode > UNICODE(0) && record->event.pressed) {
380     uint16_t unicode = keycode & 0x7FFF;
381     switch(input_mode) {
382       case UC_OSX:
383         register_code(KC_LALT);
384         break;
385       case UC_LNX:
386         register_code(KC_LCTL);
387         register_code(KC_LSFT);
388         register_code(KC_U);
389         unregister_code(KC_U);
390         break;
391       case UC_WIN:
392         register_code(KC_LALT);
393         register_code(KC_PPLS);
394         unregister_code(KC_PPLS);
395         break;
396     }
397     for(int i = 3; i >= 0; i--) {
398         uint8_t digit = ((unicode >> (i*4)) & 0xF);
399         register_code(hex_to_keycode(digit));
400         unregister_code(hex_to_keycode(digit));
401     }
402     switch(input_mode) {
403       case UC_OSX:
404       case UC_WIN:
405         unregister_code(KC_LALT);
406         break;
407       case UC_LNX:
408         unregister_code(KC_LCTL);
409         unregister_code(KC_LSFT);
410         break;
411     }
412   }
413
414 #endif
415
416   return process_action_kb(record);
417 }
418
419 void matrix_init_quantum() {
420   matrix_init_kb();
421 }
422
423 void matrix_scan_quantum() {
424   #ifdef AUDIO_ENABLE
425   if (music_sequence_playing) {
426     if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
427       music_sequence_timer = timer_read();
428       stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
429       play_note(music_sequence[music_sequence_position], 0xF);
430       music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
431     }
432   }
433
434   #endif
435
436   matrix_scan_kb();
437 }
438 #ifdef AUDIO_ENABLE
439   bool is_music_on(void) {
440       return (music_activated != 0);
441   }
442
443   void music_toggle(void) {
444       if (!music_activated) {
445           music_on();
446       } else {
447           music_off();
448       }
449   }
450
451   void music_on(void) {
452       music_activated = 1;
453       music_on_user();
454   }
455
456   void music_off(void) {
457       music_activated = 0;
458       stop_all_notes();
459   }
460
461 #endif
462 __attribute__ ((weak))
463 void music_on_user() {}