]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/quantum.c
753dde5c66a3ff9b0f89aa9cbef869d3f8c8877a
[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
25 #ifdef AUDIO_ENABLE
26   bool music_activated = false;
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 static bool shift_interrupted[] = {0, 0, 0};
64
65 bool keys_chord(uint8_t keys[]) {
66   uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
67   bool pass = true;
68   uint8_t in = 0;
69   for (uint8_t i = 0; i < chord_key_count; i++) {
70     bool found = false;
71     for (uint8_t j = 0; j < keys_size; j++) {
72       if (chord_keys[i] == (keys[j] & 0xFF)) {
73         in++; // detects key in chord
74         found = true;
75         break;
76       }
77     }
78     if (found)
79       continue;
80     if (chord_keys[i] != 0)  {
81       pass = false; // makes sure rest are blank
82     }
83   }
84   return (pass && (in == keys_size));
85 }
86
87 #ifdef UNICODE_ENABLE
88
89 uint16_t hex_to_keycode(uint8_t hex)
90 {
91   if (hex == 0x0) {
92     return KC_0;
93   } else if (hex < 0xA) {
94     return KC_1 + (hex - 0x1);
95   } else {
96     return KC_A + (hex - 0xA);
97   }
98 }
99
100 void set_unicode_mode(uint8_t os_target)
101 {
102   input_mode = os_target;
103 }
104
105 #endif
106
107 bool process_record_quantum(keyrecord_t *record) {
108
109   /* This gets the keycode from the key pressed */
110   keypos_t key = record->event.key;
111   uint16_t keycode;
112
113   #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
114     uint8_t layer;
115
116     if (record->event.pressed) {
117       layer = layer_switch_get_layer(key);
118       update_source_layers_cache(key, layer);
119     } else {
120       layer = read_source_layers_cache(key);
121     }
122     keycode = keymap_key_to_keycode(layer, key);
123   #else
124     keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
125   #endif
126
127     // This is how you use actions here
128     // if (keycode == KC_LEAD) {
129     //   action_t action;
130     //   action.code = ACTION_DEFAULT_LAYER_SET(0);
131     //   process_action(record, action);
132     //   return false;
133     // }
134
135   #ifdef MIDI_ENABLE
136     if (keycode == MI_ON && record->event.pressed) {
137       midi_activated = true;
138       music_scale_user();
139       return false;
140     }
141
142     if (keycode == MI_OFF && record->event.pressed) {
143       midi_activated = false;
144       midi_send_cc(&midi_device, 0, 0x7B, 0);
145       return false;
146     }
147
148     if (midi_activated) {
149       if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
150           if (record->event.pressed) {
151               starting_note++; // Change key
152               midi_send_cc(&midi_device, 0, 0x7B, 0);
153               // midi_send_cc(&midi_device, 1, 0x7B, 0);
154               // midi_send_cc(&midi_device, 2, 0x7B, 0);
155               // midi_send_cc(&midi_device, 3, 0x7B, 0);
156               // midi_send_cc(&midi_device, 4, 0x7B, 0);
157           }
158           return false;
159       }
160       if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
161           if (record->event.pressed) {
162               starting_note--; // Change key
163               midi_send_cc(&midi_device, 0, 0x7B, 0);
164               // midi_send_cc(&midi_device, 1, 0x7B, 0);
165               // midi_send_cc(&midi_device, 2, 0x7B, 0);
166               // midi_send_cc(&midi_device, 3, 0x7B, 0);
167               // midi_send_cc(&midi_device, 4, 0x7B, 0);
168           }
169           return false;
170       }
171       if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
172           offset++; // Change scale
173           midi_send_cc(&midi_device, 0, 0x7B, 0);
174           // midi_send_cc(&midi_device, 1, 0x7B, 0);
175           // midi_send_cc(&midi_device, 2, 0x7B, 0);
176           // midi_send_cc(&midi_device, 3, 0x7B, 0);
177           // midi_send_cc(&midi_device, 4, 0x7B, 0);
178           return false;
179       }
180       if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
181           offset--; // Change scale
182           midi_send_cc(&midi_device, 0, 0x7B, 0);
183           // midi_send_cc(&midi_device, 1, 0x7B, 0);
184           // midi_send_cc(&midi_device, 2, 0x7B, 0);
185           // midi_send_cc(&midi_device, 3, 0x7B, 0);
186           // midi_send_cc(&midi_device, 4, 0x7B, 0);
187           return false;
188       }
189       // basic
190       // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row);
191       // advanced
192       // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row);
193       // guitar
194       uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row);
195       // violin
196       // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row);
197
198       if (record->event.pressed) {
199         // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
200         midi_send_noteon(&midi_device, 0, note, 127);
201       } else {
202         // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
203         midi_send_noteoff(&midi_device, 0, note, 127);
204       }
205
206       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
207         return false;
208     }
209   #endif
210
211   #ifdef AUDIO_ENABLE
212     if (keycode == AU_ON && record->event.pressed) {
213       audio_on();
214       return false;
215     }
216
217     if (keycode == AU_OFF && record->event.pressed) {
218       audio_off();
219       return false;
220     }
221
222     if (keycode == AU_TOG && record->event.pressed) {
223         if (is_audio_on())
224         {
225             audio_off();
226         }
227         else
228         {
229             audio_on();
230         }
231       return false;
232     }
233
234     if (keycode == MU_ON && record->event.pressed) {
235         music_on();
236         return false;
237     }
238
239     if (keycode == MU_OFF && record->event.pressed) {
240         music_off();
241         return false;
242     }
243
244     if (keycode == MU_TOG && record->event.pressed) {
245         if (music_activated)
246         {
247             music_off();
248         }
249         else
250         {
251             music_on();
252         }
253         return false;
254     }
255
256     if (keycode == MUV_IN && record->event.pressed) {
257         voice_iterate();
258         music_scale_user();
259         return false;
260     }
261
262     if (keycode == MUV_DE && record->event.pressed) {
263         voice_deiterate();
264         music_scale_user();
265         return false;
266     }
267
268     if (music_activated) {
269
270       if (keycode == KC_LCTL && record->event.pressed) { // Start recording
271         stop_all_notes();
272         music_sequence_recording = true;
273         music_sequence_playing = false;
274         music_sequence_count = 0;
275         return false;
276       }
277     
278       if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
279         stop_all_notes();
280         music_sequence_recording = false;
281         music_sequence_playing = false;
282         return false;
283       }
284     
285       if (keycode == KC_LGUI && record->event.pressed) { // Start playing
286         stop_all_notes();
287         music_sequence_recording = false;
288         music_sequence_playing = true;
289         music_sequence_position = 0;
290         music_sequence_timer = 0;
291         return false;
292       }
293
294       if (keycode == KC_UP) {
295         if (record->event.pressed)
296             music_sequence_interval-=10;
297         return false;
298       }
299     
300       if (keycode == KC_DOWN) {
301         if (record->event.pressed)
302             music_sequence_interval+=10;
303         return false;
304       }
305
306       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));
307       if (record->event.pressed) {
308         play_note(freq, 0xF);
309         if (music_sequence_recording) {
310           music_sequence[music_sequence_count] = freq;
311           music_sequence_count++;
312         }
313       } else {
314         stop_note(freq);
315       }
316
317       if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
318         return false;
319     }
320   #endif
321
322 #ifndef DISABLE_LEADER
323   // Leader key set-up
324   if (record->event.pressed) {
325     if (!leading && keycode == KC_LEAD) {
326       leader_start();
327       leading = true;
328       leader_time = timer_read();
329       leader_sequence_size = 0;
330       leader_sequence[0] = 0;
331       leader_sequence[1] = 0;
332       leader_sequence[2] = 0;
333       return false;
334     }
335     if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
336       leader_sequence[leader_sequence_size] = keycode;
337       leader_sequence_size++;
338       return false;
339     }
340   }
341 #endif
342
343 #define DISABLE_CHORDING
344 #ifndef DISABLE_CHORDING
345
346   if (keycode >= 0x5700 && keycode <= 0x57FF) {
347     if (record->event.pressed) {
348       if (!chording) {
349         chording = true;
350         for (uint8_t i = 0; i < CHORDING_MAX; i++)
351           chord_keys[i] = 0;
352         chord_key_count = 0;
353         chord_key_down = 0;
354       }
355       chord_keys[chord_key_count] = (keycode & 0xFF);
356       chord_key_count++;
357       chord_key_down++;
358       return false;
359     } else {
360       if (chording) {
361         chord_key_down--;
362         if (chord_key_down == 0) {
363           chording = false;
364           // Chord Dictionary
365           if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
366             register_code(KC_A);
367             unregister_code(KC_A);
368             return false;
369           }
370           for (uint8_t i = 0; i < chord_key_count; i++) {
371             register_code(chord_keys[i]);
372             unregister_code(chord_keys[i]);
373             return false;
374           }
375         }
376       }
377     }
378   }
379
380 #endif
381
382 #ifdef UNICODE_ENABLE
383
384   if (keycode > UNICODE(0) && record->event.pressed) {
385     uint16_t unicode = keycode & 0x7FFF;
386     switch(input_mode) {
387       case UC_OSX:
388         register_code(KC_LALT);
389         break;
390       case UC_LNX:
391         register_code(KC_LCTL);
392         register_code(KC_LSFT);
393         register_code(KC_U);
394         unregister_code(KC_U);
395         break;
396       case UC_WIN:
397         register_code(KC_LALT);
398         register_code(KC_PPLS);
399         unregister_code(KC_PPLS);
400         break;
401     }
402     for(int i = 3; i >= 0; i--) {
403         uint8_t digit = ((unicode >> (i*4)) & 0xF);
404         register_code(hex_to_keycode(digit));
405         unregister_code(hex_to_keycode(digit));
406     }
407     switch(input_mode) {
408       case UC_OSX:
409       case UC_WIN:
410         unregister_code(KC_LALT);
411         break;
412       case UC_LNX:
413         unregister_code(KC_LCTL);
414         unregister_code(KC_LSFT);
415         break;
416     }
417   }
418
419 #endif
420
421   switch(keycode) {
422     case KC_LSPO: {
423                     if (record->event.pressed) {
424                       shift_interrupted[0] = false;
425                       register_mods(MOD_BIT(KC_LSFT));
426                     }
427                     else {
428                       if (!shift_interrupted[0]) {
429                         register_code(KC_9);
430                         unregister_code(KC_9);
431                       }
432                       unregister_mods(MOD_BIT(KC_LSFT));
433                     }
434                     return false;
435                     break;
436                   }
437
438     case KC_RSPC: {
439                     if (record->event.pressed) {
440                       shift_interrupted[1] = false;
441                       register_mods(MOD_BIT(KC_RSFT));
442                     }
443                     else {
444                       if (!shift_interrupted[1]) {
445                         register_code(KC_0);
446                         unregister_code(KC_0);
447                       }
448                       unregister_mods(MOD_BIT(KC_RSFT));
449                     }
450                     return false;
451                     break;
452                   }
453     default: {
454                shift_interrupted[0] = true;
455                shift_interrupted[1] = true;
456                break;
457              }
458   }
459
460   return process_action_kb(record);
461 }
462
463 void matrix_init_quantum() {
464   matrix_init_kb();
465 }
466
467 void matrix_scan_quantum() {
468   #ifdef AUDIO_ENABLE
469   if (music_sequence_playing) {
470     if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
471       music_sequence_timer = timer_read();
472       stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
473       play_note(music_sequence[music_sequence_position], 0xF);
474       music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
475     }
476   }
477
478   #endif
479
480   matrix_scan_kb();
481 }
482 #ifdef AUDIO_ENABLE
483   bool is_music_on(void) {
484       return (music_activated != 0);
485   }
486
487   void music_toggle(void) {
488       if (!music_activated) {
489           music_on();
490       } else {
491           music_off();
492       }
493   }
494
495   void music_on(void) {
496       music_activated = 1;
497       music_on_user();
498   }
499
500   void music_off(void) {
501       music_activated = 0;
502       stop_all_notes();
503   }
504
505 #endif
506
507 //------------------------------------------------------------------------------
508 // Override these functions in your keymap file to play different tunes on 
509 // different events such as startup and bootloader jump
510
511 __attribute__ ((weak))
512 void startup_user() {}
513
514 __attribute__ ((weak))
515 void shutdown_user() {}
516
517 __attribute__ ((weak))
518 void music_on_user() {}
519
520 __attribute__ ((weak))
521 void audio_on_user() {}
522
523 __attribute__ ((weak))
524 void music_scale_user() {}
525
526 //------------------------------------------------------------------------------