diff options
Diffstat (limited to 'docs/feature_audio.md')
-rw-r--r-- | docs/feature_audio.md | 143 |
1 files changed, 129 insertions, 14 deletions
diff --git a/docs/feature_audio.md b/docs/feature_audio.md index 68ba4477a..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 | ||