adds multiple voices and the ability to iterate/deiterate between them
3 files changed, 53 insertions(+), 5 deletions(-) M keyboard/preonic/keymaps/default/keymap.c M quantum/audio/voices.c M quantum/audio/voices.h
M keyboard/preonic/keymaps/default/keymap.c => keyboard/preonic/keymaps/default/keymap.c +19 -2
@@ 3,7 3,6 @@ #include "eeconfig.h" #ifdef AUDIO_ENABLE #include "audio.h" #include "song_list.h" #endif @@ // Each layer gets a name for readability, which is then used in the keymap matrix below. 31,6 30,8 @@ #endif #define MUS_OFF M(8) #define MUS_ON M(9) #define VC_IN M(10) #define VC_DE M(11) // Fillers to make layering more clear @@ #define _______ KC_TRNS 171,7 172,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { {KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12}, {_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL}, {_______, _______, _______, AUD_ON, AUD_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______}, {_______, _______, _______, MUS_ON, MUS_OFF, _______, _______, _______, _______, _______, _______, _______}, {_______, VC_DE, VC_IN, MUS_ON, MUS_OFF, _______, _______, _______, _______, _______, _______, _______}, {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} } @@ 289,6 290,22 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) #endif } break; case 10: if (record->event.pressed) { #ifdef AUDIO_ENABLE voice_iterate(); PLAY_NOTE_ARRAY(music_scale, false, 0); #endif } break; case 11: if (record->event.pressed) { #ifdef AUDIO_ENABLE voice_deiterate(); PLAY_NOTE_ARRAY(music_scale, false, 0); #endif } break; } return MACRO_NONE; };
M quantum/audio/voices.c => quantum/audio/voices.c +29 -2
@@ 1,23 1,35 @@ #include "voices.h" // these are imported from audio.c extern uint16_t envelope_index; extern float note_timbre; extern float polyphony_rate; voice_type voice = default_voice; voice_type voice = duty_osc; void set_voice(voice_type v) { voice = v; } void voice_iterate() { voice = (voice + 1) % number_of_voices; } void voice_deiterate() { voice = (voice - 1) % number_of_voices; } float voice_envelope(float frequency) { // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); switch (voice) { case default_voice: // nothing here on purpose note_timbre = TIMBRE_50; polyphony_rate = 0; break; case butts_fader: polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: @@ frequency = frequency / 4; 36,6 48,7 @@ float voice_envelope(float frequency) { } break; case octave_crunch: polyphony_rate = 0; switch (compensated_index) { case 0 ... 9: @@ case 20 ... 24: 54,6 67,20 @@ float voice_envelope(float frequency) { break; } break; case duty_osc: // This slows the loop down a substantial amount, so higher notes may freeze polyphony_rate = 0; switch (compensated_index) { default: #define SPEED 10 #define AMP .75 // sine wave is slow // note_timbre = (sin((float)compensated_index/10000*SPEED) * AMP / 2) + .5; // triangle wave is a bit faster note_timbre = (float)abs((compensated_index*SPEED % 3000) - 1500) * ( AMP / 1500 ) + (1 - AMP) / 2; break; } break; } return frequency;
M quantum/audio/voices.h => quantum/audio/voices.h +5 -1
@@ 13,9 13,13 @@ float voice_envelope(float frequency); typedef enum { default_voice, butts_fader, octave_crunch octave_crunch, duty_osc, number_of_voices // important that this is last } voice_type; void set_voice(voice_type v); void voice_iterate(); void voice_deiterate(); #endif \ No newline at end of file