qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

voices.c (12341B)


      1 /* Copyright 2016 Jack Humbert
      2  * Copyright 2020 JohSchneider
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 2 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16  */
     17 #include "voices.h"
     18 #include "audio.h"
     19 #include "timer.h"
     20 #include <stdlib.h>
     21 #include <math.h>
     22 
     23 uint8_t note_timbre      = TIMBRE_DEFAULT;
     24 bool    glissando        = false;
     25 bool    vibrato          = false;
     26 float   vibrato_strength = 0.5;
     27 float   vibrato_rate     = 0.125;
     28 
     29 uint16_t voices_timer = 0;
     30 
     31 #ifdef AUDIO_VOICE_DEFAULT
     32 voice_type voice = AUDIO_VOICE_DEFAULT;
     33 #else
     34 voice_type voice = default_voice;
     35 #endif
     36 
     37 void set_voice(voice_type v) {
     38     voice = v;
     39 }
     40 
     41 void voice_iterate(void) {
     42     voice = (voice + 1) % number_of_voices;
     43 }
     44 
     45 void voice_deiterate(void) {
     46     voice = (voice - 1 + number_of_voices) % number_of_voices;
     47 }
     48 
     49 #ifdef AUDIO_VOICES
     50 float mod(float a, int b) {
     51     float r = fmod(a, b);
     52     return r < 0 ? r + b : r;
     53 }
     54 
     55 // Effect: 'vibrate' a given target frequency slightly above/below its initial value
     56 float voice_add_vibrato(float average_freq) {
     57     float vibrato_counter = mod(timer_read() / (100 * vibrato_rate), VIBRATO_LUT_LENGTH);
     58 
     59     return average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength);
     60 }
     61 
     62 // Effect: 'slides' the 'frequency' from the starting-point, to the target frequency
     63 float voice_add_glissando(float from_freq, float to_freq) {
     64     if (to_freq != 0 && from_freq < to_freq && from_freq < to_freq * pow(2, -440 / to_freq / 12 / 2)) {
     65         return from_freq * pow(2, 440 / from_freq / 12 / 2);
     66     } else if (to_freq != 0 && from_freq > to_freq && from_freq > to_freq * pow(2, 440 / to_freq / 12 / 2)) {
     67         return from_freq * pow(2, -440 / from_freq / 12 / 2);
     68     } else {
     69         return to_freq;
     70     }
     71 }
     72 #endif
     73 
     74 float voice_envelope(float frequency) {
     75     // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz
     76 //    __attribute__((unused)) uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency));
     77 #ifdef AUDIO_VOICES
     78     uint16_t envelope_index    = timer_elapsed(voices_timer); // TODO: multiply in some factor?
     79     uint16_t compensated_index = envelope_index / 100;        // TODO: correct factor would be?
     80 #endif
     81 
     82     switch (voice) {
     83         case default_voice:
     84             glissando = false;
     85             // note_timbre    = TIMBRE_50; //Note: leave the user the possibility to adjust the timbre with 'audio_set_timbre'
     86             break;
     87 
     88 #ifdef AUDIO_VOICES
     89 
     90         case vibrating:
     91             glissando = false;
     92             vibrato   = true;
     93             break;
     94 
     95         case something:
     96             glissando = false;
     97             switch (compensated_index) {
     98                 case 0 ... 9:
     99                     note_timbre = TIMBRE_12;
    100                     break;
    101 
    102                 case 10 ... 19:
    103                     note_timbre = TIMBRE_25;
    104                     break;
    105 
    106                 case 20 ... 200:
    107                     note_timbre = 12 + 12;
    108                     break;
    109 
    110                 default:
    111                     note_timbre = 12;
    112                     break;
    113             }
    114             break;
    115 
    116         case drums:
    117             glissando = false;
    118             // switch (compensated_index) {
    119             //     case 0 ... 10:
    120             //         note_timbre = 50;
    121             //         break;
    122             //     case 11 ... 20:
    123             //         note_timbre = 50 * (21 - compensated_index) / 10;
    124             //         break;
    125             //     default:
    126             //         note_timbre = 0;
    127             //         break;
    128             // }
    129             // frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8);
    130 
    131             if (frequency < 80.0) {
    132             } else if (frequency < 160.0) {
    133                 // Bass drum: 60 - 100 Hz
    134                 frequency = (rand() % (int)(40)) + 60;
    135                 switch (envelope_index) {
    136                     case 0 ... 10:
    137                         note_timbre = 50;
    138                         break;
    139                     case 11 ... 20:
    140                         note_timbre = 50 * (21 - envelope_index) / 10;
    141                         break;
    142                     default:
    143                         note_timbre = 0;
    144                         break;
    145                 }
    146 
    147             } else if (frequency < 320.0) {
    148                 // Snare drum: 1 - 2 KHz
    149                 frequency = (rand() % (int)(1000)) + 1000;
    150                 switch (envelope_index) {
    151                     case 0 ... 5:
    152                         note_timbre = 50;
    153                         break;
    154                     case 6 ... 20:
    155                         note_timbre = 50 * (21 - envelope_index) / 15;
    156                         break;
    157                     default:
    158                         note_timbre = 0;
    159                         break;
    160                 }
    161 
    162             } else if (frequency < 640.0) {
    163                 // Closed Hi-hat: 3 - 5 KHz
    164                 frequency = (rand() % (int)(2000)) + 3000;
    165                 switch (envelope_index) {
    166                     case 0 ... 15:
    167                         note_timbre = 50;
    168                         break;
    169                     case 16 ... 20:
    170                         note_timbre = 50 * (21 - envelope_index) / 5;
    171                         break;
    172                     default:
    173                         note_timbre = 0;
    174                         break;
    175                 }
    176 
    177             } else if (frequency < 1280.0) {
    178                 // Open Hi-hat: 3 - 5 KHz
    179                 frequency = (rand() % (int)(2000)) + 3000;
    180                 switch (envelope_index) {
    181                     case 0 ... 35:
    182                         note_timbre = 50;
    183                         break;
    184                     case 36 ... 50:
    185                         note_timbre = 50 * (51 - envelope_index) / 15;
    186                         break;
    187                     default:
    188                         note_timbre = 0;
    189                         break;
    190                 }
    191             }
    192             break;
    193         case butts_fader:
    194             glissando = true;
    195             switch (compensated_index) {
    196                 case 0 ... 9:
    197                     frequency   = frequency / 4;
    198                     note_timbre = TIMBRE_12;
    199                     break;
    200 
    201                 case 10 ... 19:
    202                     frequency   = frequency / 2;
    203                     note_timbre = TIMBRE_12;
    204                     break;
    205 
    206                 case 20 ... 200:
    207                     note_timbre = 12 - (uint8_t)(pow(((float)compensated_index - 20) / (200 - 20), 2) * 12.5);
    208                     break;
    209 
    210                 default:
    211                     note_timbre = 0;
    212                     break;
    213             }
    214             break;
    215 
    216             // case octave_crunch:
    217             //     switch (compensated_index) {
    218             //         case 0 ... 9:
    219             //         case 20 ... 24:
    220             //         case 30 ... 32:
    221             //             frequency = frequency / 2;
    222             //             note_timbre = TIMBRE_12;
    223             //         break;
    224 
    225             //         case 10 ... 19:
    226             //         case 25 ... 29:
    227             //         case 33 ... 35:
    228             //             frequency = frequency * 2;
    229             //             note_timbre = TIMBRE_12;
    230             //          break;
    231 
    232             //         default:
    233             //             note_timbre = TIMBRE_12;
    234             //          break;
    235             //     }
    236             //  break;
    237 
    238         case duty_osc:
    239             // This slows the loop down a substantial amount, so higher notes may freeze
    240             glissando = true;
    241             switch (compensated_index) {
    242                 default:
    243 #    define OCS_SPEED 10
    244 #    define OCS_AMP .25
    245                     // sine wave is slow
    246                     // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5;
    247                     // triangle wave is a bit faster
    248                     note_timbre = (uint8_t)abs((compensated_index * OCS_SPEED % 3000) - 1500) * (OCS_AMP / 1500) + (1 - OCS_AMP) / 2;
    249                     break;
    250             }
    251             break;
    252 
    253         case duty_octave_down:
    254             glissando   = true;
    255             note_timbre = (uint8_t)(100 * (envelope_index % 2) * .125 + .375 * 2);
    256             if ((envelope_index % 4) == 0) note_timbre = 50;
    257             if ((envelope_index % 8) == 0) note_timbre = 0;
    258             break;
    259         case delayed_vibrato:
    260             glissando   = true;
    261             note_timbre = TIMBRE_50;
    262 #    define VOICE_VIBRATO_DELAY 150
    263 #    define VOICE_VIBRATO_SPEED 50
    264             switch (compensated_index) {
    265                 case 0 ... VOICE_VIBRATO_DELAY:
    266                     break;
    267                 default:
    268                     // TODO: merge/replace with voice_add_vibrato above
    269                     frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1)) / 1000 * VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)];
    270                     break;
    271             }
    272             break;
    273             // case delayed_vibrato_octave:
    274             //     if ((envelope_index % 2) == 1) {
    275             //         note_timbre = 55;
    276             //     } else {
    277             //         note_timbre = 45;
    278             //     }
    279             //     #define VOICE_VIBRATO_DELAY 150
    280             //     #define VOICE_VIBRATO_SPEED 50
    281             //     switch (compensated_index) {
    282             //         case 0 ... VOICE_VIBRATO_DELAY:
    283             //             break;
    284             //         default:
    285             //             frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)];
    286             //             break;
    287             //     }
    288             //     break;
    289             // case duty_fifth_down:
    290             //     note_timbre = TIMBRE_50;
    291             //     if ((envelope_index % 3) == 0)
    292             //         note_timbre = TIMBRE_75;
    293             //     break;
    294             // case duty_fourth_down:
    295             //     note_timbre = 0;
    296             //     if ((envelope_index % 12) == 0)
    297             //         note_timbre = TIMBRE_75;
    298             //     if (((envelope_index % 12) % 4) != 1)
    299             //         note_timbre = TIMBRE_75;
    300             //     break;
    301             // case duty_third_down:
    302             //     note_timbre = TIMBRE_50;
    303             //     if ((envelope_index % 5) == 0)
    304             //         note_timbre = TIMBRE_75;
    305             //     break;
    306             // case duty_fifth_third_down:
    307             //     note_timbre = TIMBRE_50;
    308             //     if ((envelope_index % 5) == 0)
    309             //         note_timbre = TIMBRE_75;
    310             //     if ((envelope_index % 3) == 0)
    311             //         note_timbre = TIMBRE_25;
    312             //     break;
    313 
    314 #endif // AUDIO_VOICES
    315 
    316         default:
    317             break;
    318     }
    319 
    320 #ifdef AUDIO_VOICES
    321     if (vibrato && (vibrato_strength > 0)) {
    322         frequency = voice_add_vibrato(frequency);
    323     }
    324 
    325     if (glissando) {
    326         // TODO: where to keep track of the start-frequency?
    327         // frequency = voice_add_glissando(??, frequency);
    328     }
    329 #endif // AUDIO_VOICES
    330 
    331     return frequency;
    332 }
    333 
    334 // Vibrato functions
    335 
    336 void voice_set_vibrato_rate(float rate) {
    337     vibrato_rate = rate;
    338 }
    339 void voice_increase_vibrato_rate(float change) {
    340     vibrato_rate *= change;
    341 }
    342 void voice_decrease_vibrato_rate(float change) {
    343     vibrato_rate /= change;
    344 }
    345 void voice_set_vibrato_strength(float strength) {
    346     vibrato_strength = strength;
    347 }
    348 void voice_increase_vibrato_strength(float change) {
    349     vibrato_strength *= change;
    350 }
    351 void voice_decrease_vibrato_strength(float change) {
    352     vibrato_strength /= change;
    353 }
    354 
    355 // Timbre functions
    356 
    357 void voice_set_timbre(uint8_t timbre) {
    358     if ((timbre > 0) && (timbre < 100)) {
    359         note_timbre = timbre;
    360     }
    361 }
    362 uint8_t voice_get_timbre(void) {
    363     return note_timbre;
    364 }