aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode/process_music.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode/process_music.c')
-rw-r--r--quantum/process_keycode/process_music.c141
1 files changed, 85 insertions, 56 deletions
diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c
index 2d52e47a7..217dca280 100644
--- a/quantum/process_keycode/process_music.c
+++ b/quantum/process_keycode/process_music.c
@@ -1,43 +1,72 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
1#include "process_music.h" 16#include "process_music.h"
2 17
18#ifdef AUDIO_ENABLE
19#include "process_audio.h"
20#endif
21#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
22#include "process_midi.h"
23#endif
24
25#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
26
3bool music_activated = false; 27bool music_activated = false;
4uint8_t starting_note = 0x0C; 28uint8_t music_starting_note = 0x0C;
5int offset = 7; 29int music_offset = 7;
6 30
7// music sequencer 31// music sequencer
8static bool music_sequence_recording = false; 32static bool music_sequence_recording = false;
9static bool music_sequence_recorded = false; 33static bool music_sequence_recorded = false;
10static bool music_sequence_playing = false; 34static bool music_sequence_playing = false;
11static float music_sequence[16] = {0}; 35static uint8_t music_sequence[16] = {0};
12static uint8_t music_sequence_count = 0; 36static uint8_t music_sequence_count = 0;
13static uint8_t music_sequence_position = 0; 37static uint8_t music_sequence_position = 0;
14 38
15static uint16_t music_sequence_timer = 0; 39static uint16_t music_sequence_timer = 0;
16static uint16_t music_sequence_interval = 100; 40static uint16_t music_sequence_interval = 100;
17 41
18bool process_music(uint16_t keycode, keyrecord_t *record) { 42static void music_noteon(uint8_t note) {
43 #ifdef AUDIO_ENABLE
44 process_audio_noteon(note);
45 #endif
46 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
47 process_midi_basic_noteon(note);
48 #endif
49}
19 50
20 if (keycode == AU_ON && record->event.pressed) { 51static void music_noteoff(uint8_t note) {
21 audio_on(); 52 #ifdef AUDIO_ENABLE
22 return false; 53 process_audio_noteoff(note);
23 } 54 #endif
55 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
56 process_midi_basic_noteoff(note);
57 #endif
58}
24 59
25 if (keycode == AU_OFF && record->event.pressed) { 60void music_all_notes_off(void) {
26 audio_off(); 61 #ifdef AUDIO_ENABLE
27 return false; 62 process_audio_all_notes_off();
28 } 63 #endif
64 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
65 process_midi_all_notes_off();
66 #endif
67}
29 68
30 if (keycode == AU_TOG && record->event.pressed) { 69bool process_music(uint16_t keycode, keyrecord_t *record) {
31 if (is_audio_on())
32 {
33 audio_off();
34 }
35 else
36 {
37 audio_on();
38 }
39 return false;
40 }
41 70
42 if (keycode == MU_ON && record->event.pressed) { 71 if (keycode == MU_ON && record->event.pressed) {
43 music_on(); 72 music_on();
@@ -61,22 +90,10 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
61 return false; 90 return false;
62 } 91 }
63 92
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) { 93 if (music_activated) {
77 94
78 if (keycode == KC_LCTL && record->event.pressed) { // Start recording 95 if (keycode == KC_LCTL && record->event.pressed) { // Start recording
79 stop_all_notes(); 96 music_all_notes_off();
80 music_sequence_recording = true; 97 music_sequence_recording = true;
81 music_sequence_recorded = false; 98 music_sequence_recorded = false;
82 music_sequence_playing = false; 99 music_sequence_playing = false;
@@ -85,7 +102,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
85 } 102 }
86 103
87 if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing 104 if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
88 stop_all_notes(); 105 music_all_notes_off();
89 if (music_sequence_recording) { // was recording 106 if (music_sequence_recording) { // was recording
90 music_sequence_recorded = true; 107 music_sequence_recorded = true;
91 } 108 }
@@ -95,7 +112,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
95 } 112 }
96 113
97 if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing 114 if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing
98 stop_all_notes(); 115 music_all_notes_off();
99 music_sequence_recording = false; 116 music_sequence_recording = false;
100 music_sequence_playing = true; 117 music_sequence_playing = true;
101 music_sequence_position = 0; 118 music_sequence_position = 0;
@@ -115,21 +132,33 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
115 return false; 132 return false;
116 } 133 }
117 134
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)); 135 #define MUSIC_MODE_GUITAR
136
137 #ifdef MUSIC_MODE_CHROMATIC
138 uint8_t note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
139 #elif defined(MUSIC_MODE_GUITAR)
140 uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
141 #elif defined(MUSIC_MODE_VIOLIN)
142 uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
143 #else
144 uint8_t note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
145 #endif
146
119 if (record->event.pressed) { 147 if (record->event.pressed) {
120 play_note(freq, 0xF); 148 music_noteon(note);
121 if (music_sequence_recording) { 149 if (music_sequence_recording) {
122 music_sequence[music_sequence_count] = freq; 150 music_sequence[music_sequence_count] = note;
123 music_sequence_count++; 151 music_sequence_count++;
124 } 152 }
125 } else { 153 } else {
126 stop_note(freq); 154 music_noteoff(note);
127 } 155 }
128 156
129 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through 157 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
130 return false; 158 return false;
131 } 159 }
132 return true; 160
161 return true;
133} 162}
134 163
135bool is_music_on(void) { 164bool is_music_on(void) {
@@ -151,26 +180,26 @@ void music_on(void) {
151 180
152void music_off(void) { 181void music_off(void) {
153 music_activated = 0; 182 music_activated = 0;
154 stop_all_notes(); 183 music_all_notes_off();
155} 184}
156 185
157
158__attribute__ ((weak))
159void music_on_user() {}
160
161__attribute__ ((weak))
162void audio_on_user() {}
163
164__attribute__ ((weak))
165void music_scale_user() {}
166
167void matrix_scan_music(void) { 186void matrix_scan_music(void) {
168 if (music_sequence_playing) { 187 if (music_sequence_playing) {
169 if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) { 188 if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
170 music_sequence_timer = timer_read(); 189 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)]); 190 uint8_t prev_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); 191 uint8_t next_note = music_sequence[music_sequence_position];
192 music_noteoff(prev_note);
193 music_noteon(next_note);
173 music_sequence_position = (music_sequence_position + 1) % music_sequence_count; 194 music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
174 } 195 }
175 } 196 }
176} 197}
198
199__attribute__ ((weak))
200void music_on_user() {}
201
202__attribute__ ((weak))
203void music_scale_user() {}
204
205#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) \ No newline at end of file