process_music.c (9939B)
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 */ 16 #include "process_music.h" 17 #include "timer.h" 18 19 #ifdef AUDIO_ENABLE 20 # include "audio.h" 21 # include "process_audio.h" 22 #endif 23 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC) 24 # include "process_midi.h" 25 #endif 26 27 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) 28 29 bool music_activated = false; 30 bool midi_activated = false; 31 uint8_t music_starting_note = 0x0C; 32 int music_offset = 7; 33 uint8_t music_mode = MUSIC_MODE_MAJOR; 34 35 // music sequencer 36 static bool music_sequence_recording = false; 37 static bool music_sequence_recorded = false; 38 static bool music_sequence_playing = false; 39 static uint8_t music_sequence[16] = {0}; 40 static uint8_t music_sequence_count = 0; 41 static uint8_t music_sequence_position = 0; 42 43 static uint16_t music_sequence_timer = 0; 44 static uint16_t music_sequence_interval = 100; 45 46 # ifdef AUDIO_ENABLE 47 # ifndef MUSIC_ON_SONG 48 # define MUSIC_ON_SONG SONG(MUSIC_ON_SOUND) 49 # endif 50 # ifndef MUSIC_OFF_SONG 51 # define MUSIC_OFF_SONG SONG(MUSIC_OFF_SOUND) 52 # endif 53 # ifndef MIDI_ON_SONG 54 # define MIDI_ON_SONG SONG(MUSIC_ON_SOUND) 55 # endif 56 # ifndef MIDI_OFF_SONG 57 # define MIDI_OFF_SONG SONG(MUSIC_OFF_SOUND) 58 # endif 59 # ifndef CHROMATIC_SONG 60 # define CHROMATIC_SONG SONG(CHROMATIC_SOUND) 61 # endif 62 # ifndef GUITAR_SONG 63 # define GUITAR_SONG SONG(GUITAR_SOUND) 64 # endif 65 # ifndef VIOLIN_SONG 66 # define VIOLIN_SONG SONG(VIOLIN_SOUND) 67 # endif 68 # ifndef MAJOR_SONG 69 # define MAJOR_SONG SONG(MAJOR_SOUND) 70 # endif 71 float music_mode_songs[NUMBER_OF_MODES][5][2] = {CHROMATIC_SONG, GUITAR_SONG, VIOLIN_SONG, MAJOR_SONG}; 72 float music_on_song[][2] = MUSIC_ON_SONG; 73 float music_off_song[][2] = MUSIC_OFF_SONG; 74 float midi_on_song[][2] = MIDI_ON_SONG; 75 float midi_off_song[][2] = MIDI_OFF_SONG; 76 # endif 77 78 static void music_noteon(uint8_t note) { 79 # ifdef AUDIO_ENABLE 80 if (music_activated) process_audio_noteon(note); 81 # endif 82 # if defined(MIDI_ENABLE) && defined(MIDI_BASIC) 83 if (midi_activated) process_midi_basic_noteon(note); 84 # endif 85 } 86 87 static void music_noteoff(uint8_t note) { 88 # ifdef AUDIO_ENABLE 89 if (music_activated) process_audio_noteoff(note); 90 # endif 91 # if defined(MIDI_ENABLE) && defined(MIDI_BASIC) 92 if (midi_activated) process_midi_basic_noteoff(note); 93 # endif 94 } 95 96 void music_all_notes_off(void) { 97 # ifdef AUDIO_ENABLE 98 if (music_activated) process_audio_all_notes_off(); 99 # endif 100 # if defined(MIDI_ENABLE) && defined(MIDI_BASIC) 101 if (midi_activated) process_midi_all_notes_off(); 102 # endif 103 } 104 105 bool process_music(uint16_t keycode, keyrecord_t *record) { 106 if (keycode == QK_MUSIC_ON && record->event.pressed) { 107 music_on(); 108 return false; 109 } 110 111 if (keycode == QK_MUSIC_OFF && record->event.pressed) { 112 music_off(); 113 return false; 114 } 115 116 if (keycode == QK_MUSIC_TOGGLE && record->event.pressed) { 117 if (music_activated) { 118 music_off(); 119 } else { 120 music_on(); 121 } 122 return false; 123 } 124 125 if (keycode == QK_MIDI_ON && record->event.pressed) { 126 midi_on(); 127 return false; 128 } 129 130 if (keycode == QK_MIDI_OFF && record->event.pressed) { 131 midi_off(); 132 return false; 133 } 134 135 if (keycode == QK_MIDI_TOGGLE && record->event.pressed) { 136 if (midi_activated) { 137 midi_off(); 138 } else { 139 midi_on(); 140 } 141 return false; 142 } 143 144 if (keycode == QK_MUSIC_MODE_NEXT && record->event.pressed) { 145 music_mode_cycle(); 146 return false; 147 } 148 149 if (music_activated || midi_activated) { 150 if (record->event.pressed) { 151 if (keycode == KC_LEFT_CTRL) { // Start recording 152 music_all_notes_off(); 153 music_sequence_recording = true; 154 music_sequence_recorded = false; 155 music_sequence_playing = false; 156 music_sequence_count = 0; 157 return false; 158 } 159 160 if (keycode == KC_LEFT_ALT) { // Stop recording/playing 161 music_all_notes_off(); 162 if (music_sequence_recording) { // was recording 163 music_sequence_recorded = true; 164 } 165 music_sequence_recording = false; 166 music_sequence_playing = false; 167 return false; 168 } 169 170 if (keycode == KC_LEFT_GUI && music_sequence_recorded) { // Start playing 171 music_all_notes_off(); 172 music_sequence_recording = false; 173 music_sequence_playing = true; 174 music_sequence_position = 0; 175 music_sequence_timer = 0; 176 return false; 177 } 178 179 if (keycode == KC_UP) { 180 music_sequence_interval -= 10; 181 return false; 182 } 183 184 if (keycode == KC_DOWN) { 185 music_sequence_interval += 10; 186 return false; 187 } 188 } 189 190 uint8_t note = 36; 191 # ifdef MUSIC_MAP 192 if (music_mode == MUSIC_MODE_CHROMATIC) { 193 note = music_starting_note + music_offset + 36 + music_map[record->event.key.row][record->event.key.col]; 194 } else { 195 uint8_t position = music_map[record->event.key.row][record->event.key.col]; 196 note = music_starting_note + music_offset + 36 + SCALE[position % 7] + (position / 7) * 12; 197 } 198 # else 199 if (music_mode == MUSIC_MODE_CHROMATIC) 200 note = (music_starting_note + record->event.key.col + music_offset - 3) + 12 * (MATRIX_ROWS - record->event.key.row); 201 else if (music_mode == MUSIC_MODE_GUITAR) 202 note = (music_starting_note + record->event.key.col + music_offset + 32) + 5 * (MATRIX_ROWS - record->event.key.row); 203 else if (music_mode == MUSIC_MODE_VIOLIN) 204 note = (music_starting_note + record->event.key.col + music_offset + 32) + 7 * (MATRIX_ROWS - record->event.key.row); 205 else if (music_mode == MUSIC_MODE_MAJOR) 206 note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3) + 12 * (MATRIX_ROWS - record->event.key.row); 207 else 208 note = music_starting_note; 209 # endif 210 211 if (record->event.pressed) { 212 music_noteon(note); 213 if (music_sequence_recording) { 214 music_sequence[music_sequence_count] = note; 215 music_sequence_count++; 216 } 217 } else { 218 music_noteoff(note); 219 } 220 221 if (music_mask(keycode)) return false; 222 } 223 224 return true; 225 } 226 227 bool music_mask(uint16_t keycode) { 228 # ifdef MUSIC_MASK 229 return MUSIC_MASK; 230 # else 231 return music_mask_kb(keycode); 232 # endif 233 } 234 235 __attribute__((weak)) bool music_mask_kb(uint16_t keycode) { 236 return music_mask_user(keycode); 237 } 238 239 __attribute__((weak)) bool music_mask_user(uint16_t keycode) { 240 return keycode < 0xFF; 241 } 242 243 bool is_music_on(void) { 244 return (music_activated != 0); 245 } 246 247 void music_toggle(void) { 248 if (!music_activated) { 249 music_on(); 250 } else { 251 music_off(); 252 } 253 } 254 255 void music_on(void) { 256 music_activated = 1; 257 # ifdef AUDIO_ENABLE 258 PLAY_SONG(music_on_song); 259 # endif 260 music_on_user(); 261 } 262 263 void music_off(void) { 264 music_all_notes_off(); 265 music_activated = 0; 266 # ifdef AUDIO_ENABLE 267 PLAY_SONG(music_off_song); 268 # endif 269 } 270 271 bool is_midi_on(void) { 272 return (midi_activated != 0); 273 } 274 275 void midi_toggle(void) { 276 if (!midi_activated) { 277 midi_on(); 278 } else { 279 midi_off(); 280 } 281 } 282 283 void midi_on(void) { 284 midi_activated = 1; 285 # ifdef AUDIO_ENABLE 286 PLAY_SONG(midi_on_song); 287 # endif 288 midi_on_user(); 289 } 290 291 void midi_off(void) { 292 # if defined(MIDI_ENABLE) && defined(MIDI_BASIC) 293 process_midi_all_notes_off(); 294 # endif 295 midi_activated = 0; 296 # ifdef AUDIO_ENABLE 297 PLAY_SONG(midi_off_song); 298 # endif 299 } 300 301 void music_mode_cycle(void) { 302 music_all_notes_off(); 303 music_mode = (music_mode + 1) % NUMBER_OF_MODES; 304 # ifdef AUDIO_ENABLE 305 PLAY_SONG(music_mode_songs[music_mode]); 306 # endif 307 } 308 309 void music_task(void) { 310 if (music_sequence_playing) { 311 if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) { 312 music_sequence_timer = timer_read(); 313 uint8_t prev_note = music_sequence[(music_sequence_position - 1 < 0) ? (music_sequence_position - 1 + music_sequence_count) : (music_sequence_position - 1)]; 314 uint8_t next_note = music_sequence[music_sequence_position]; 315 music_noteoff(prev_note); 316 music_noteon(next_note); 317 music_sequence_position = (music_sequence_position + 1) % music_sequence_count; 318 } 319 } 320 } 321 322 __attribute__((weak)) void music_on_user(void) {} 323 324 __attribute__((weak)) void midi_on_user(void) {} 325 326 __attribute__((weak)) void music_scale_user(void) {} 327 328 #endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))