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