From 9828aba2a12f03fccbc1095bc8e4918ae58fa31b Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Thu, 21 Apr 2016 18:14:25 -0400 Subject: adds multiple voices and the ability to iterate/deiterate between them --- keyboard/preonic/keymaps/default/keymap.c | 21 +++++++++++++++++++-- quantum/audio/voices.c | 31 +++++++++++++++++++++++++++++-- quantum/audio/voices.h | 6 +++++- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/keyboard/preonic/keymaps/default/keymap.c b/keyboard/preonic/keymaps/default/keymap.c index 267bfab3d7..f0d5ed6030 100644 --- a/keyboard/preonic/keymaps/default/keymap.c +++ b/keyboard/preonic/keymaps/default/keymap.c @@ -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; }; diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 51652927bd..92ada47f7b 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -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; diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 317f5d98c5..44c5066b55 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -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 -- cgit v1.2.1