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