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