diff options
Diffstat (limited to 'docs/feature_audio.md')
| -rw-r--r-- | docs/feature_audio.md | 149 |
1 files changed, 129 insertions, 20 deletions
diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 5132dfe97..9e7ba75f5 100644 --- a/docs/feature_audio.md +++ b/docs/feature_audio.md | |||
| @@ -1,21 +1,117 @@ | |||
| 1 | # Audio | 1 | # Audio |
| 2 | 2 | ||
| 3 | Your keyboard can make sounds! If you've got a Planck, Preonic, or basically any AVR keyboard that allows access to certain PWM-capable pins, you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. | 3 | Your keyboard can make sounds! If you've got a spare pin you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. |
| 4 | 4 | ||
| 5 | Up to two simultaneous audio voices are supported, one driven by timer 1 and another driven by timer 3. The following pins can be defined as audio outputs in config.h: | 5 | To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. |
| 6 | 6 | ||
| 7 | Timer 1: | 7 | ## AVR based boards |
| 8 | `#define B5_AUDIO` | 8 | On Atmega32U4 based boards, up to two simultaneous tones can be rendered. |
| 9 | `#define B6_AUDIO` | 9 | With one speaker connected to a PWM capable pin on PORTC driven by timer 3 and the other on one of the PWM pins on PORTB driven by timer 1. |
| 10 | `#define B7_AUDIO` | ||
| 11 | 10 | ||
| 12 | Timer 3: | 11 | The following pins can be configured as audio outputs in `config.h` - for one speaker set eiter one out of: |
| 13 | `#define C4_AUDIO` | ||
| 14 | `#define C5_AUDIO` | ||
| 15 | `#define C6_AUDIO` | ||
| 16 | 12 | ||
| 17 | If you add `AUDIO_ENABLE = yes` to your `rules.mk`, there's a couple different sounds that will automatically be enabled without any other configuration: | 13 | * `#define AUDIO_PIN C4` |
| 14 | * `#define AUDIO_PIN C5` | ||
| 15 | * `#define AUDIO_PIN C6` | ||
| 16 | * `#define AUDIO_PIN B5` | ||
| 17 | * `#define AUDIO_PIN B6` | ||
| 18 | * `#define AUDIO_PIN B7` | ||
| 18 | 19 | ||
| 20 | and *optionally*, for a second speaker, one of: | ||
| 21 | * `#define AUDIO_PIN_ALT B5` | ||
| 22 | * `#define AUDIO_PIN_ALT B6` | ||
| 23 | * `#define AUDIO_PIN_ALT B7` | ||
| 24 | |||
| 25 | ### Wiring | ||
| 26 | per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN for the primary; and similarly with AUDIO_PIN_ALT for the secondary. | ||
| 27 | |||
| 28 | |||
| 29 | ## ARM based boards | ||
| 30 | for more technical details, see the notes on [Audio driver](audio_driver.md). | ||
| 31 | |||
| 32 | <!-- because I'm not sure where to fit this in: https://waveeditonline.com/ --> | ||
| 33 | ### DAC (basic) | ||
| 34 | Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set in `config.h` either: | ||
| 35 | |||
| 36 | `#define AUDIO_PIN A4` or `#define AUDIO_PIN A5` | ||
| 37 | |||
| 38 | the other DAC channel can optionally be used with a secondary speaker, just set: | ||
| 39 | |||
| 40 | `#define AUDIO_PIN_ALT A4` or `#define AUDIO_PIN_ALT A5` | ||
| 41 | |||
| 42 | Do note though that the dac_basic driver is only capable of reproducing one tone per speaker/channel at a time, for more tones simultaneously, try the dac_additive driver. | ||
| 43 | |||
| 44 | #### Wiring: | ||
| 45 | for two piezos, for example configured as `AUDIO_PIN A4` and `AUDIO_PIN_ALT A5` would be: red lead to A4 and black to Ground, and similarly with the second one: A5 = red, and Ground = black | ||
| 46 | |||
| 47 | another alternative is to drive *one* piezo with both DAC pins - for an extra "push". | ||
| 48 | wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO_PIN_ALT_AS_NEGATIVE` to `config.h` | ||
| 49 | |||
| 50 | ##### Proton-C Example: | ||
| 51 | The Proton-C comes (optionally) with one 'builtin' piezo, which is wired to A4+A5. | ||
| 52 | For this board `config.h` would include these defines: | ||
| 53 | |||
| 54 | ```c | ||
| 55 | #define AUDIO_PIN A5 | ||
| 56 | #define AUDIO_PIN_ALT A4 | ||
| 57 | #define AUDIO_PIN_ALT_AS_NEGATIVE | ||
| 58 | ``` | ||
| 59 | |||
| 60 | ### DAC (additive) | ||
| 61 | Another option, besides dac_basic (which produces sound through a square-wave), is to use the DAC to do additive wave synthesis. | ||
| 62 | With a number of predefined wave-forms or by providing your own implementation to generate samples on the fly. | ||
| 63 | To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN A4` or `#define AUDIO_PIN A5`. | ||
| 64 | |||
| 65 | The used waveform *defaults* to sine, but others can be selected by adding one of the following defines to `config.h`: | ||
| 66 | |||
| 67 | * `#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` | ||
| 68 | * `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE` | ||
| 69 | * `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID` | ||
| 70 | * `#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE` | ||
| 71 | |||
| 72 | Should you rather choose to generate and use your own sample-table with the DAC unit, implement `uint16_t dac_value_generate(void)` with your keyboard - for an example implementation see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable | ||
| 73 | |||
| 74 | |||
| 75 | ### PWM (software) | ||
| 76 | if the DAC pins are unavailable (or the MCU has no usable DAC at all, like STM32F1xx); PWM can be an alternative. | ||
| 77 | Note that there is currently only one speaker/pin supported. | ||
| 78 | |||
| 79 | set in `rules.mk`: | ||
| 80 | |||
| 81 | `AUDIO_DRIVER = pwm_software` and in `config.h`: | ||
| 82 | `#define AUDIO_PIN C13` (can be any pin) to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software. | ||
| 83 | |||
| 84 | #### Wiring | ||
| 85 | the usual piezo wiring: red goes to the selected AUDIO_PIN, black goes to ground. | ||
| 86 | |||
| 87 | OR if you can chose to drive one piezo with two pins, for example `#define AUDIO_PIN B1`, `#define AUDIO_PIN_ALT B2` in `config.h`, with `#define AUDIO_PIN_ALT_AS_NEGATIVE` - then the red lead could go to B1, the black to B2. | ||
| 88 | |||
| 89 | ### PWM (hardware) | ||
| 90 | STM32F1xx have to fall back to using PWM, but can do so in hardware; but again on currently only one speaker/pin. | ||
| 91 | |||
| 92 | `AUDIO_DRIVER = pwm_hardware` in `rules.mk`, and in `config.h`: | ||
| 93 | `#define AUDIO_PIN A8` | ||
| 94 | `#define AUDIO_PWM_DRIVER PWMD1` | ||
| 95 | `#define AUDIO_PWM_CHANNEL 1` | ||
| 96 | (as well as `#define AUDIO_PWM_PAL_MODE 42` if you are on STM32F2 or larger) | ||
| 97 | which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8). | ||
| 98 | Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 data-sheet to pick the right TIMx_CHy and pin-alternate function. | ||
| 99 | |||
| 100 | |||
| 101 | ## Tone Multiplexing | ||
| 102 | Since most drivers can only render one tone per speaker at a time (with the one exception: arm dac-additive) there also exists a "workaround-feature" that does time-slicing/multiplexing - which does what the name implies: cycle through a set of active tones (e.g. when playing chords in Music Mode) at a given rate, and put one tone at a time out through the one/few speakers that are available. | ||
| 103 | |||
| 104 | To enable this feature, and configure a starting-rate, add the following defines to `config.h`: | ||
| 105 | ```c | ||
| 106 | #define AUDIO_ENABLE_TONE_MULTIPLEXING | ||
| 107 | #define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 10 | ||
| 108 | ``` | ||
| 109 | |||
| 110 | The audio core offers interface functions to get/set/change the tone multiplexing rate from within `keymap.c`. | ||
| 111 | |||
| 112 | |||
| 113 | ## Songs | ||
| 114 | There's a couple of different sounds that will automatically be enabled without any other configuration: | ||
| 19 | ``` | 115 | ``` |
| 20 | STARTUP_SONG // plays when the keyboard starts up (audio.c) | 116 | STARTUP_SONG // plays when the keyboard starts up (audio.c) |
| 21 | GOODBYE_SONG // plays when you press the RESET key (quantum.c) | 117 | GOODBYE_SONG // plays when you press the RESET key (quantum.c) |
| @@ -67,15 +163,34 @@ The available keycodes for audio are: | |||
| 67 | * `AU_OFF` - Turn Audio Feature off | 163 | * `AU_OFF` - Turn Audio Feature off |
| 68 | * `AU_TOG` - Toggle Audio Feature state | 164 | * `AU_TOG` - Toggle Audio Feature state |
| 69 | 165 | ||
| 70 | !> These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely. | 166 | !> These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely. |
| 167 | |||
| 168 | ## Tempo | ||
| 169 | the 'speed' at which SONGs are played is dictated by the set Tempo, which is measured in beats-per-minute. Note lenghts are defined relative to that. | ||
| 170 | The initial/default tempo is set to 120 bpm, but can be configured by setting `TEMPO_DEFAULT` in `config.c`. | ||
| 171 | There is also a set of functions to modify the tempo from within the user/keymap code: | ||
| 172 | ```c | ||
| 173 | void audio_set_tempo(uint8_t tempo); | ||
| 174 | void audio_increase_tempo(uint8_t tempo_change); | ||
| 175 | void audio_decrease_tempo(uint8_t tempo_change); | ||
| 176 | ``` | ||
| 71 | 177 | ||
| 72 | ## ARM Audio Volume | 178 | ## ARM Audio Volume |
| 73 | 179 | ||
| 74 | For ARM devices, you can adjust the DAC sample values. If your board is too loud for you or your coworkers, you can set the max using `DAC_SAMPLE_MAX` in your `config.h`: | 180 | For ARM devices, you can adjust the DAC sample values. If your board is too loud for you or your coworkers, you can set the max using `AUDIO_DAC_SAMPLE_MAX` in your `config.h`: |
| 75 | 181 | ||
| 76 | ```c | 182 | ```c |
| 77 | #define DAC_SAMPLE_MAX 65535U | 183 | #define AUDIO_DAC_SAMPLE_MAX 4095U |
| 78 | ``` | 184 | ``` |
| 185 | the DAC usually runs in 12Bit mode, hence a volume of 100% = 4095U | ||
| 186 | |||
| 187 | Note: this only adjusts the volume aka 'works' if you stick to WAVEFORM_SQUARE, since its samples are generated on the fly - any other waveform uses a hardcoded/precomputed sample-buffer. | ||
| 188 | |||
| 189 | ## Voices | ||
| 190 | Aka "audio effects", different ones can be enabled by setting in `config.h` these defines: | ||
| 191 | `#define AUDIO_VOICES` to enable the feature, and `#define AUDIO_VOICE_DEFAULT something` to select a specific effect | ||
| 192 | for details see quantum/audio/voices.h and .c | ||
| 193 | |||
| 79 | 194 | ||
| 80 | ## Music Mode | 195 | ## Music Mode |
| 81 | 196 | ||
| @@ -215,12 +330,6 @@ This is still a WIP, but check out `quantum/process_keycode/process_midi.c` to s | |||
| 215 | AU_OFF, | 330 | AU_OFF, |
| 216 | AU_TOG, | 331 | AU_TOG, |
| 217 | 332 | ||
| 218 | #ifdef FAUXCLICKY_ENABLE | ||
| 219 | FC_ON, | ||
| 220 | FC_OFF, | ||
| 221 | FC_TOG, | ||
| 222 | #endif | ||
| 223 | |||
| 224 | // Music mode on/off/toggle | 333 | // Music mode on/off/toggle |
| 225 | MU_ON, | 334 | MU_ON, |
| 226 | MU_OFF, | 335 | MU_OFF, |
