arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
AnalogDriverESP32.h
1#pragma once
2
3#include "AudioToolsConfig.h"
4#if defined(ESP32) && defined(USE_ANALOG) && ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0 , 0) || defined(DOXYGEN)
5#include "AudioTools/CoreAudio/AudioAnalog/AnalogDriverBase.h"
6#include "driver/i2s.h"
7#include "driver/adc.h"
8#include "soc/dac_channel.h"
9#include "soc/adc_channel.h"
10#include "soc/rtc.h"
11#include "AudioTools/CoreAudio/AudioStreams.h"
12
13namespace audio_tools {
14
15// Output I2S data to built-in DAC, no matter the data format is 16bit or 32 bit, the DAC module will only take the 8bits from MSB
16// so we convet it to a singed 16 bit value
17static inline uint16_t convert8DAC(int64_t value, int value_bits_per_sample){
18 uint16_t result = value;
19 if (value_bits_per_sample!=16){
20 // convert to 16 bit value
21 result = (value * NumberConverter::maxValue(16) / NumberConverter::maxValue(value_bits_per_sample));
22 }
23 // uint_t positive range
24 result+= 32768;
25 return result;
26}
27
28
36 public:
38 AnalogDriverESP32() = default;
39
42 end();
43 }
44
47 TRACEI();
48 cfg.logInfo();
49
50 if (adc_config.is_auto_center_read){
51 LOGI("auto_center")
52 auto_center.begin(cfg.channels, cfg.bits_per_sample);
53 }
54
55 if (!is_driver_installed){
56 port_no = (i2s_port_t) cfg.port_no;
57
58 adc_config = cfg;
59 i2s_config_t i2s_config = {
60 .mode = (i2s_mode_t)cfg.mode_internal,
61 .sample_rate = (eps32_i2s_sample_rate_type)cfg.sample_rate,
62 .bits_per_sample = (i2s_bits_per_sample_t)cfg.bits_per_sample,
63 .channel_format = (cfg.channels == 1 && cfg.rx_tx_mode == RX_MODE) ? I2S_CHANNEL_FMT_ONLY_LEFT :I2S_CHANNEL_FMT_RIGHT_LEFT,
64 .communication_format = (i2s_comm_format_t)0,
65 .intr_alloc_flags = 0,
66 .dma_buf_count = cfg.buffer_count,
67 .dma_buf_len = cfg.buffer_size,
68 .use_apll = cfg.use_apll,
69 .tx_desc_auto_clear = cfg.auto_clear,
70#if ESP_IDF_VERSION_MAJOR >= 4
71 .fixed_mclk = 0,
72 .mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT,
73 .bits_per_chan = I2S_BITS_PER_CHAN_DEFAULT,
74#endif
75 };
76
77 // setup config
78 if (i2s_driver_install(port_no, &i2s_config, 0, nullptr)!=ESP_OK){
79 LOGE( "%s - %s", __func__, "i2s_driver_install");
80 return false;
81 }
82
83 // record driver as installed
84 is_driver_installed = true;
85
86 // clear i2s buffer
87 if (i2s_zero_dma_buffer(port_no)!=ESP_OK) {
88 LOGE( "%s - %s", __func__, "i2s_zero_dma_buffer");
89 return false;
90 }
91
92 switch (cfg.rx_tx_mode) {
93 case RX_MODE:
94 LOGI("RX_MODE");
95
96 setupInputPin(cfg.adc_pin);
97
98 if (i2s_set_adc_mode(adc_unit, adc_channel)!=ESP_OK) {
99 LOGE( "%s - %s", __func__, "i2s_driver_install");
100 return false;
101 }
102
103 // enable the ADC
104 if (i2s_adc_enable(port_no)!=ESP_OK) {
105 LOGE( "%s - %s", __func__, "i2s_adc_enable");
106 return false;
107 }
108
109 break;
110
111 case TX_MODE:
112 LOGI("TX_MODE");
113 if (i2s_set_pin(port_no, nullptr) != ESP_OK) LOGE("i2s_set_pin");
114 if (i2s_set_dac_mode( I2S_DAC_CHANNEL_BOTH_EN) != ESP_OK) LOGE("i2s_set_dac_mode");
115 if (i2s_set_sample_rates(port_no, cfg.sample_rate) != ESP_OK) LOGE("i2s_set_sample_rates");
116 //if (i2s_set_clk(port_no, cfg.sample_rate, cfg.bits_per_sample, I2S_CHANNEL_STEREO)) LOGE("i2s_set_clk");
117
118 break;
119
120 default:
121 LOGE( "Unsupported MODE: %d", cfg.rx_tx_mode);
122 return false;
123 break;
124
125 }
126 } else {
127 i2s_start(port_no);
128 if (adc_config.rx_tx_mode == RX_MODE){
129 i2s_adc_enable(port_no);
130 }
131 }
132 active = true;
133 return true;
134 }
135
137 void end() override {
138 LOGI(__func__);
139 if (active) {
140 i2s_zero_dma_buffer(port_no);
141 }
142
143 // close ADC
144 if (adc_config.rx_tx_mode == RX_MODE){
145 i2s_adc_disable(port_no);
146 }
147 if (adc_config.uninstall_driver_on_end){
148 i2s_driver_uninstall(port_no);
149 is_driver_installed = false;
150 } else {
151 i2s_stop(port_no);
152 }
153 active = false;
154 }
155
156 // /// Overides the sample rate and uses the max value which is around ~13MHz. Call this methd after begin();
157 // void setMaxSampleRate() {
158 // //this is the hack that enables the highest sampling rate possible ~13MHz, have fun
159 // SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_A_V, 1, I2S_CLKM_DIV_A_S);
160 // SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_B_V, 1, I2S_CLKM_DIV_B_S);
161 // SET_PERI_REG_BITS(I2S_CLKM_CONF_REG(0), I2S_CLKM_DIV_NUM_V, 1, I2S_CLKM_DIV_NUM_S);
162 // SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_TX_BCK_DIV_NUM_V, 1, I2S_TX_BCK_DIV_NUM_S);
163 // }
164
166 size_t write(const uint8_t *src, size_t size_bytes) override {
167 TRACED();
168
169 size_t result = 0;
170 if (size_bytes>0 && src!=nullptr){
171 switch(adc_config.channels){
172 case 1:
173 result = outputMono(src, size_bytes);
174 break;
175 case 2:
176 result = outputStereo(src, size_bytes);
177 break;
178 default:
179 LOGE("Unsupported number of channels: %d", adc_config.channels);
180 stop();
181 }
182 LOGD("converted write size: %d",result);
183 }
184 return size_bytes;
185 }
186
187 size_t readBytes(uint8_t *dest, size_t size_bytes) override {
188 TRACED();
189 size_t result = 0;
190 if (i2s_read(port_no, dest, size_bytes, &result, adc_config.timeout)!=ESP_OK){
191 TRACEE();
192 }
193 // make sure that the center is at 0
194 if (adc_config.is_auto_center_read){
195 auto_center.convert(dest, result);
196 }
197 LOGD( "%s - len: %d -> %d", __func__, size_bytes, result);
198 return result;
199 }
200
201 virtual int available() override {
202 return active ? adc_config.buffer_size*adc_config.buffer_count : 0;
203 }
204
205 protected:
206 AnalogConfigESP32 adc_config;
207 ConverterAutoCenter auto_center;
208 i2s_port_t port_no;
209 bool active = false;
210 bool is_driver_installed = false;
211 size_t result=0;
212
213 // input values
214 adc_unit_t adc_unit;
215 adc1_channel_t adc_channel;
216
218 void setupInputPin(int gpio){
219 TRACED();
220
221 switch(gpio){
222 case 32:
223 adc_unit = ADC_UNIT_1;
224 adc_channel = ADC1_GPIO32_CHANNEL;
225 break;
226 case 33:
227 adc_unit = ADC_UNIT_1;
228 adc_channel = ADC1_GPIO33_CHANNEL;
229 break;
230 case 34:
231 adc_unit = ADC_UNIT_1;
232 adc_channel = ADC1_GPIO34_CHANNEL;
233 break;
234 case 35:
235 adc_unit = ADC_UNIT_1;
236 adc_channel = ADC1_GPIO35_CHANNEL;
237 break;
238 case 36:
239 adc_unit = ADC_UNIT_1;
240 adc_channel = ADC1_GPIO36_CHANNEL;
241 break;
242 case 37:
243 adc_unit = ADC_UNIT_1;
244 adc_channel = ADC1_GPIO37_CHANNEL;
245 break;
246 case 38:
247 adc_unit = ADC_UNIT_1;
248 adc_channel = ADC1_GPIO38_CHANNEL;
249 break;
250 case 39:
251 adc_unit = ADC_UNIT_1;
252 adc_channel = ADC1_GPIO39_CHANNEL;
253 break;
254
255 default:
256 LOGE( "%s - pin GPIO%d is not supported", __func__,gpio);
257 }
258 }
259
260 // The internal DAC only supports 8 bit values - so we need to convert the data
261 size_t outputStereo(const void *src, size_t size_bytes) {
262 TRACED();
263 size_t output_size = 0;
264 size_t result;
265 uint16_t *dst = (uint16_t *)src;
266 switch(adc_config.bits_per_sample){
267 case 16: {
268 int16_t *data=(int16_t *)src;
269 output_size = size_bytes;
270 for (int j=0;j<size_bytes/2;j++){
271 dst[j] = convert8DAC(data[j], adc_config.bits_per_sample);
272 }
273 } break;
274 case 24: {
275 int24_t *data=(int24_t *)src;
276 output_size = (size_bytes/3) * 2;
277 for (int j=0;j<size_bytes/3;j++){
278 dst[j] = (uint32_t)convert8DAC(data[j], adc_config.bits_per_sample);
279 }
280 } break;
281 case 32: {
282 int32_t *data=(int32_t *)src;
283 output_size = (size_bytes/4) * 2;
284 for (int j=0;j<size_bytes/4;j++){
285 dst[j] = convert8DAC(data[j], adc_config.bits_per_sample);
286 }
287 } break;
288 }
289
290 if (output_size>0){
291 if (i2s_write(port_no, src, output_size, &result, adc_config.timeout)!=ESP_OK){
292 LOGE("%s: %d", LOG_METHOD, output_size);
293 }
294 }
295
296 LOGD("i2s_write %d -> %d bytes", size_bytes, result);
297 return result;
298
299 }
300
301 // I2S requires stereo so we convert mono to stereo
302 size_t outputMono(const void *src, size_t size_bytes) {
303 TRACED();
304 size_t output_size = 0;
305 uint16_t out[2];
306 size_t resultTotal = 0;
307 switch(adc_config.bits_per_sample){
308 case 16: {
309 int16_t *data=(int16_t *)src;
310 for (int j=0;j<size_bytes/2;j++){
311 out[0] = convert8DAC(data[j], adc_config.bits_per_sample);
312 out[1] = out[0];
313 if (i2s_write(port_no, out, 4, &result, portMAX_DELAY)!=ESP_OK){
314 LOGE("%s: %d", LOG_METHOD, output_size);
315 }
316 resultTotal += result;
317 }
318 }break;
319 case 24: {
320 int24_t *data=(int24_t*)src;
321 for (int j=0;j<size_bytes/3;j++){
322 out[0] = convert8DAC(data[j], adc_config.bits_per_sample);
323 out[1] = out[0];
324 if (i2s_write(port_no, out, 4, &result, portMAX_DELAY)!=ESP_OK){
325 LOGE("%s: %d", LOG_METHOD, output_size);
326 }
327 resultTotal += result;
328 }
329 } break;
330 case 32: {
331 int32_t *data=(int32_t *)src;
332 for (int j=0;j<size_bytes/4;j++){
333 out[0] = convert8DAC(data[j], adc_config.bits_per_sample);
334 out[1] = out[0];
335 if (i2s_write(port_no, out, 4, &result, portMAX_DELAY)!=ESP_OK){
336 LOGE("%s: %d", LOG_METHOD, output_size);
337 }
338 resultTotal += result;
339 }
340 } break;
341 }
342
343 LOGD("i2s_write %d -> %d bytes", size_bytes, resultTotal);
344 return resultTotal;
345 }
346};
348using AnalogDriver = AnalogDriverESP32;
349
350} // namespace
351
352#endif
ESP32 specific configuration for i2s input via adc. The default input pin is GPIO34....
Definition AnalogConfigESP32.h:22
Definition AnalogDriverBase.h:13
Please use AnalogAudioStream: A very fast ADC and DAC using the ESP32 I2S interface.
Definition AnalogDriverESP32.h:35
void setupInputPin(int gpio)
Defines the current ADC pin. The following GPIO pins are supported: GPIO32-GPIO39.
Definition AnalogDriverESP32.h:218
bool begin(AnalogConfigESP32 cfg)
starts the DAC
Definition AnalogDriverESP32.h:46
size_t write(const uint8_t *src, size_t size_bytes) override
writes the data to the I2S interface
Definition AnalogDriverESP32.h:166
AnalogDriverESP32()=default
Default constructor.
void end() override
stops the I2S and unistalls the driver
Definition AnalogDriverESP32.h:137
virtual ~AnalogDriverESP32()
Destructor.
Definition AnalogDriverESP32.h:41
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:299
void stop()
Public generic methods.
Definition AudioRuntime.h:14
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
AnalogDriverArduino AnalogDriver
AnalogAudioStream.
Definition AnalogDriverArduino.h:48
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:55
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:57
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:59