at master 328 lines 9.9 kB view raw
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 29bool music_activated = false; 30bool midi_activated = false; 31uint8_t music_starting_note = 0x0C; 32int music_offset = 7; 33uint8_t music_mode = MUSIC_MODE_MAJOR; 34 35// music sequencer 36static bool music_sequence_recording = false; 37static bool music_sequence_recorded = false; 38static bool music_sequence_playing = false; 39static uint8_t music_sequence[16] = {0}; 40static uint8_t music_sequence_count = 0; 41static uint8_t music_sequence_position = 0; 42 43static uint16_t music_sequence_timer = 0; 44static 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 71float music_mode_songs[NUMBER_OF_MODES][5][2] = {CHROMATIC_SONG, GUITAR_SONG, VIOLIN_SONG, MAJOR_SONG}; 72float music_on_song[][2] = MUSIC_ON_SONG; 73float music_off_song[][2] = MUSIC_OFF_SONG; 74float midi_on_song[][2] = MIDI_ON_SONG; 75float midi_off_song[][2] = MIDI_OFF_SONG; 76# endif 77 78static 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 87static 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 96void 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 105bool 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 227bool 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 243bool is_music_on(void) { 244 return (music_activated != 0); 245} 246 247void music_toggle(void) { 248 if (!music_activated) { 249 music_on(); 250 } else { 251 music_off(); 252 } 253} 254 255void 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 263void 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 271bool is_midi_on(void) { 272 return (midi_activated != 0); 273} 274 275void midi_toggle(void) { 276 if (!midi_activated) { 277 midi_on(); 278 } else { 279 midi_off(); 280 } 281} 282 283void 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 291void 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 301void 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 309void 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))