Mozzi  version v2.0
sound synthesis library for Arduino
config_checks_generic.h
1 /*
2  * config_checks_generic.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 /** @page hardware Hardware and configuration
13  *
14  * Mozzi works on many different platforms, but not the same output modes are available on all hardware. For boards specific notes
15  * and configuration options, see the relevant sub-pages in this section:
16  *
17  * - @subpage hardware_avr
18  * - @subpage hardware_esp32
19  * - @subpage hardware_esp8266
20  * - @subpage hardware_mbed
21  * - @subpage hardware_renesas
22  * - @subpage hardware_rp2040
23  * - @subpage hardware_samd
24  * - @subpage hardware_stm32duino
25  * - @subpage hardware_stm32_maple
26  * - (@subpage hardware_stm32_disambiguation)
27  * - @subpage hardware_teensy3
28  * - @subpage hardware_teensy4
29 */
30 
31 /** For Mozzi-internal use: Check configuration options for (some) invalid settings, and apply default for options that have not been set, so far.
32  * */
33 
34 #ifndef MOZZI_CONFIG_CHECK_GENERIC_H
35 #define MOZZI_CONFIG_CHECK_GENERIC_H
36 
37 #include "../MozziConfigValues.h" // in case not user-included
38 #include "mozzi_macros.h"
39 
40 /// Step 0: Check for some stuff that user should never configure directly (but may be set, indirectly from the hardware-specific setups)
41 #if defined(BYPASS_MOZZI_OUTPUT_BUFFER)
42 #error "BYPASS_MOZZI_OUTPUT_BUFFER may not be customized via config"
43 #endif
44 
45 
46 //// Step 1: Apply missing defaults for generic config options (not the hardware specific ones)
47 #if not defined(MOZZI_COMPATIBILITY_LEVEL)
48 #define MOZZI_COMPATIBILITY_LEVEL MOZZI_COMPATIBILITY_2_0
49 #endif
50 
51 #if not defined(MOZZI_AUDIO_CHANNELS)
52 #define MOZZI_AUDIO_CHANNELS MOZZI_MONO
53 #endif
54 
55 //MOZZI_AUDIO_MODE -> hardware specific
56 //MOZZI_AUDIO_RATE -> hardware specific
57 
58 #if not defined(MOZZI_CONTROL_RATE)
59 # if defined(CONTROL_RATE) && (MOZZI_COMPATIBILITY_LEVEL < MOZZI_COMPATIBILITY_LATEST)
60 # warning Please change CONTROL_RATE to MOZZI_CONTROL_RATE
61 # define MOZZI_CONTROL_RATE CONTROL_RATE
62 # else
63 # define MOZZI_CONTROL_RATE 64
64 # endif
65 #endif
66 
67 //MOZZI_ANALOG_READ -> hardware specific, but we want to insert a warning, if not supported, and user has not explicitly configured anything
68 #if not defined(MOZZI_ANALOG_READ)
69 #define MOZZI__ANALOG_READ_NOT_CONFIGURED
70 #endif
71 
72 #if not defined(MOZZI_AUDIO_INPUT)
73 #define MOZZI_AUDIO_INPUT MOZZI_AUDIO_INPUT_NONE
74 #endif
75 
76 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && !defined(MOZZI_AUDIO_INPUT_PIN)
77 #warning Using audio input, but no audio input pin defined, explicitly. Defaulting to pin 0.
78 #define MOZZI_AUDIO_INPUT_PIN 0
79 #endif
80 
81 //MOZZI_PWM_RATE -> hardware specific
82 //MOZZI_AUDIO_PIN_1 -> hardware specific
83 //MOZZI_AUDIO_PIN_1_LOW -> hardware specific
84 //MOZZI_AUDIO_PIN_2 -> hardware specific
85 //MOZZI_AUDIO_PIN_2_LOW -> hardware specific
86 
87 
88 /// Step 2: Include the hardware specific checks-and-defaults-header
89 #if IS_AVR()
90 #include "config_checks_avr.h"
91 #elif IS_ESP32()
92 #include "config_checks_esp32.h"
93 #elif IS_ESP8266()
94 #include "config_checks_esp8266.h"
95 #elif IS_MBED()
96 #include "config_checks_mbed.h"
97 #elif IS_RENESAS()
98 #include "config_checks_renesas.h"
99 #elif IS_RP2040()
100 #include "config_checks_rp2040.h"
101 #elif IS_SAMD21()
102 #include "config_checks_samd21.h"
103 #elif IS_STM32DUINO()
104 #include "config_checks_stm32duino.h"
105 #elif IS_STM32MAPLE()
106 #include "config_checks_stm32maple.h"
107 #elif (IS_TEENSY3() || IS_TEENSY4())
108 #include "config_checks_teensy.h"
109 #else
110 #error Problem detecting hardware
111 #endif
112 
113 
114 /// Step 2b: Minimal special handling for MOZZI_OUTPUT_EXTERNAL_TIMED/CUSTOM
115 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED, MOZZI_OUTPUT_EXTERNAL_CUSTOM) && !defined(MOZZI_AUDIO_BITS)
116 # define MOZZI_AUDIO_BITS 16
117 #endif
118 
119 
120 
121 /// Step 3: Apply various generic checks that make sense on more than one platform
122 MOZZI_CHECK_POW2(MOZZI_AUDIO_RATE)
124 
126 #error "MOZZI_AUDIO_INPUT depends on MOZZI_ANALOG_READ option"
127 #endif
128 
129 #if !MOZZI_IS(MOZZI_AUDIO_INPUT, MOZZI_AUDIO_INPUT_NONE) && defined(MOZZI_AUDIO_INPUT_PIN)
130 #warning "MOZZI_AUDIO_INPUT_PIN defined without MOZZI_AUDIO_INPUT"
131 #endif
132 
134 #error "MOZZI_AUDIO_CHANNELS outside of (currently) supported range"
135 #endif
136 
137 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_TIMED) || MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
138 #warning "Mozzi is configured to use an external void 'audioOutput(const AudioOutput f)' function. Please define one in your sketch"
139 #endif
140 
141 // Hardware-specific checks file should have more narrow checks for most options, below, but is not required to, so let's check for anything that is wildly out of scope:
144 
145 #if defined(MOZZI__ANALOG_READ_NOT_CONFIGURED)
146 # if MOZZI_IS(MOZZI_ANALOG_READ, MOZZI_ANALOG_READ_NONE)
147 # warning Asynchronous analog reads not implemented on this platform
148 # endif
149 # undef MOZZI__ANALOG_READ_NOT_CONFIGURED
150 #endif
151 
152 #if defined(MOZZI_ANALOG_READ_RESOLUTION)
153 # if (MOZZI_ANALOG_READ_RESOLUTION < 1) || (MOZZI_ANALOG_READ_RESOLUTION > 16)
154 // NOTE: We could certainly allow more than 16 bits, but then the data type would need to be adjusted/adjustable, accrodingly.
155 # error MOZZI_ANALOG_READ_RESOLUTION must be between 1 and 16 bits
156 # endif
157 #endif
158 
159 /// Step 4: Init Read-only defines that depend on other values
160 #if !defined(MOZZI_AUDIO_BIAS)
161 #define MOZZI_AUDIO_BIAS ((uint16_t) 1<<(MOZZI_AUDIO_BITS-1))
162 #endif
163 
164 #if !defined(MOZZI_AUDIO_BITS_OPTIMISTIC)
165 #define MOZZI_AUDIO_BITS_OPTIMISTIC MOZZI_AUDIO_BITS
166 #endif
167 
168 // TODO: Rename these defines
169 #if MOZZI_AUDIO_RATE == 8192
170 #define AUDIO_RATE_AS_LSHIFT 13
171 #define MICROS_PER_AUDIO_TICK 122
172 #elif MOZZI_AUDIO_RATE == 16384
173 #define AUDIO_RATE_AS_LSHIFT 14
174 #define MICROS_PER_AUDIO_TICK 61 // 1000000 / 16384 = 61.035, ...* 256 = 15625
175 #elif MOZZI_AUDIO_RATE == 32768
176 #define AUDIO_RATE_AS_LSHIFT 15
177 #define MICROS_PER_AUDIO_TICK 31 // = 1000000 / 32768 = 30.518, ...* 256 = 7812.6
178 #elif MOZZI_AUDIO_RATE == 65336
179 #define AUDIO_RATE_AS_LSHIFT 16
180 #define MICROS_PER_AUDIO_TICK 15
181 #else
182 #error Whoopsie, not LSHIFT defined for this audio rate. Please report and/or fix
183 #endif
184 
185 #if MOZZI_IS(MOZZI_AUDIO_MODE, MOZZI_OUTPUT_EXTERNAL_CUSTOM)
186 #define BYPASS_MOZZI_OUTPUT_BUFFER true
187 #endif
188 
189 /// Step 5: Patch up some backwards compatibility issues as far as config-related
191 # define AUDIO_RATE MOZZI_AUDIO_RATE
192 # if !defined(CONTROL_RATE)
193 # define CONTROL_RATE MOZZI_CONTROL_RATE
194 # endif
195 #endif
196 
197 /// Step 6: Some more checks that need to be at the end, because of requiring end of the foodchain headers
198 // TODO: Rather move this up again, and make AudioOutputStorage_t a primary config option
199 #include "../AudioOutput.h"
200 static_assert(MOZZI_AUDIO_BITS <= (8*sizeof(AudioOutputStorage_t)), "Configured MOZZI_AUDIO_BITS is too large for the internal storage type");
201 
202 #endif