Mozzi  version v2.0
sound synthesis library for Arduino
config_checks_esp8266.h
1 /*
2  * config_checks_esp8266.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2023-2024 Thomas Friedrichsmeier and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10 */
11 
12 #ifndef CONFIG_CHECK_ESP8266_H
13 #define CONFIG_CHECK_ESP8266_H
14 
15 /**
16  * @page hardware_esp8266 Mozzi on ESP32-based boards.
17  *
18  * port by Thomas Friedrichsmeier
19  *
20  * @section esp8266_status Port status and notes
21  * - Since flash memory is not built into the ESP8266, but connected, externally, it is much too slow for keeping wave tables, audio samples, etc. Instead, these are kept in RAM on this platform.
22  * - Asynchronous analog reads are not implemented. `mozziAnalogRead()` relays to `analogRead()`. @ref MOZZI_AUDIO_INPUT is not available
23  * - twi_nonblock is not ported
24  * - Note that the ESP8266 pins can output less current than the other supported CPUs. The maximum is 12mA, with a recommendation to stay below 6mA.
25  * - WHEN CONNECTING A HEADPHONE, DIRECTLY, USE APPROPRIATE CURRENT LIMITING RESISTORS (>= 500Ohms).
26  * - _Any_ WiFi-activity can cause severe spikes in power consumption. This can cause audible "ticking" artifacts, long before any other symptoms.
27  * - If you do not require WiFi in your sketch, you should turn it off, _explicitly_, using @code WiFi.mode(WIFI_OFF) @endcode.
28  * - A juicy enough, well regulated power supply, and a stabilizing capacitor between VCC and Gnd can help a lot.
29  * - As the (PDM) output signal is digital, a single (fast!) transistor can be used to amplify it to an independent voltage level.
30  * - audioHook() calls `yield()` once for every audio sample generated. Thus, as long as your audio output buffer does not run empty, you should not need any additional `yield()`s inside `loop()`.
31  *
32  * @section esp8266_output Output modes
33  * The following audio modes (see @ref MOZZI_AUDIO_MODE) are currently supported on this hardware:
34  * - MOZZI_OUTPUT_EXTERNAL_TIMED
35  * - MOZZI_OUTPUT_EXTERNAL_CUSTOM
36  * - MOZZI_OUTPUT_PDM_VIA_I2S
37  * - MOZZI_OUTPUT_PDM_VIA_SERIAL
38  * - MOZZI_OUTPUT_I2S_DAC
39  *
40  * The default mode is @ref esp8266_pdm_via_serial .
41  *
42  * @note
43  * This port really does not currently come with a PWM mode!
44  *
45  * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_SERIAL
46  * Output is coded using pulse density modulation, and sent via GPIO2 (Serial1 TX).
47  * - This output mode uses timer1 for queuing audio sample, so that timer is not available for other uses.
48  * - Note that this mode has slightly lower effective analog output range than @ref esp8266_pdm_via_i2s, due to start/stop bits being added to the output stream.
49  * - Supports mono output, only, pins not configurable.
50  *
51  * The option @ref MOZZI_PDM_RESOLTUON (default value 2, corresponding to 64 ones and zeros per audio sample) can be used to adjust the output resolution.
52  * Obviously higher values demand more computation power.
53  *
54  * @section esp8266_pdm_via_serial MOZZI_OUTPUT_PDM_VIA_I2S
55  * Output is coded using pulse density modulation, and sent via the I2S pins. The I2S data out pin (GPIO3, which is also "RX") will have the output,
56  * but *all* I2S output pins (RX, GPIO2 and GPIO15) will be affected. Mozzi tries to set GPIO2 and GPIO15 to input mode, and *at the time of this writing*, this allows
57  * I2S output on RX even on boards such as the ESP01 (where GPIO15 is tied to Ground). However, it seems safest to assume that this mode may not be useable on boards where
58  * GPIO2 or GPIO15 are not available as output pins.
59  *
60  * Supports mono output, only, pins not configurable.
61  *
62  * Resolution may be controlled using MOZZI_PDM_RESOLUTION (see above; default value is 2).
63  *
64  * @section esp8266_i2s_dac MOZZI_OUTPUT_I2S_DAC
65  * Output is sent to an external DAC (such as a PT8211), digitally coded. This is the only mode that supports stereo (@ref MOZZI_AUDIO_CHANNELS). It also needs the least processing power.
66  * The pins cannot be configured (GPIO3/RX, GPIO2, and GPIO15).
67  *
68  * @section esp8266_external MOZZI_OUTPUT_EXTERNAL_TIMED and MOZZI_OUTPUT_EXTERNAL_CUSTOM
69  * See @ref external_audio
70 */
71 
72 #if not IS_ESP8266()
73 #error This header should be included for ESP architecture, only
74 #endif
75 
77 #if !defined(MOZZI_AUDIO_MODE)
78 #define MOZZI_AUDIO_MODE MOZZI_OUTPUT_PDM_VIA_SERIAL
79 #endif
80 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL, MOZZI_OUTPUT_I2S_DAC)
81 
82 #if !defined(MOZZI_AUDIO_RATE)
83 #define MOZZI_AUDIO_RATE 32768
84 #endif
85 
86 #if !defined(MOZZI_AUDIO_BITS)
87 # define MOZZI_AUDIO_BITS 16
88 #endif
89 
90 #if !defined(MOZZI_ANALOG_READ)
91 # define MOZZI_ANALOG_READ MOZZI_ANALOG_READ_NONE
92 #endif
93 
94 MOZZI_CHECK_SUPPORTED(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
95 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE)
96 
97 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_PDM_VIA_SERIAL)
98 # if !defined(PDM_RESOLUTION)
99 # define MOZZI_PDM_RESOLUTION 2
100 # endif
101 # include "disable_stereo_on_github_workflow.h"
102 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_CHANNELS, 1)
103 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16)
104 #elif MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_I2S_DAC)
105 # define MOZZI_PDM_RESOLUTION 1 // DO NOT CHANGE THIS VALUE! Not actually PDM coded, but this define is useful to keep code simple.
106 MOZZI_CHECK_SUPPORTED(MOZZI_AUDIO_BITS, 16)
107 #endif
108 
109 #define PDM_RESOLUTION 2 // 1 corresponds to 32 PDM clocks per sample, 2 corresponds to 64 PDM clocks, etc. (and at some level you're going hit the hardware limits)
110 
111 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_PDM_VIA_I2S, MOZZI_OUTPUT_I2S_DAC)
112 // NOTE: On ESP / output via I2S, we simply use the I2S buffer as the output
113 // buffer, which saves RAM, but also simplifies things a lot
114 // esp. since i2s output already has output rate control -> no need for a
115 // separate output timer
116 #define BYPASS_MOZZI_OUTPUT_BUFFER true
117 #endif
118 
119 #define MOZZI__INTERNAL_ANALOG_READ_RESOLUTION 10
120 
121 #endif // #ifndef CONFIG_CHECK_ESP8266_H