arduino-audio-tools
Loading...
Searching...
No Matches
AnalogDriverESP32.h
Go to the documentation of this file.
1#pragma once
2
3#include "AudioToolsConfig.h"
4#if (defined(ESP32) && defined(USE_ANALOG) && USE_LEGACY_I2S) || defined(DOXYGEN)
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"
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
18 uint16_t result = value;
19 if (value_bits_per_sample!=16){
20 // convert to 16 bit value
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
51 LOGI("auto_center")
53 }
54
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,
67 .dma_buf_len = cfg.buffer_size,
68 .use_apll = cfg.use_apll,
69 .tx_desc_auto_clear = cfg.auto_clear,
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
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
97
99 LOGE( "%s - %s", __func__, "i2s_driver_install");
100 return false;
101 }
102
103 // enable the ADC
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 {
130 }
131 }
132 active = true;
133 return true;
134 }
135
137 void end() override {
138 LOGI(__func__);
139 if (active) {
141 }
142
143 // close ADC
146 }
149 is_driver_installed = false;
150 } else {
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
196 }
197 LOGD( "%s - len: %d -> %d", __func__, size_bytes, result);
198 return result;
199 }
200
201 virtual int available() override {
203 }
204
205 protected:
209 bool active = false;
211 size_t result=0;
212
213 // input values
216
218 void setupInputPin(int gpio){
219 TRACED();
220
221 switch(gpio){
222 case 32:
225 break;
226 case 33:
229 break;
230 case 34:
233 break;
234 case 35:
237 break;
238 case 36:
241 break;
242 case 37:
245 break;
246 case 38:
249 break;
250 case 39:
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;
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++){
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++){
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++){
286 }
287 } break;
288 }
289
290 if (output_size>0){
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;
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 }
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 }
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 }
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
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define TRACEE()
Definition AudioLoggerIDF.h:34
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define LOG_METHOD
Definition AudioToolsConfig.h:64
#define I2S_MCLK_MULTIPLE_DEFAULT
Definition I2SESP32.h:11
ESP32 specific configuration for i2s input via adc. The default input pin is GPIO34....
Definition AnalogConfigESP32.h:22
int buffer_count
Definition AnalogConfigESP32.h:25
void logInfo()
Definition AnalogConfigESP32.h:62
int adc_pin
Definition AnalogConfigESP32.h:40
bool uninstall_driver_on_end
Definition AnalogConfigESP32.h:38
RxTxMode rx_tx_mode
Definition AnalogConfigESP32.h:27
bool is_auto_center_read
Definition AnalogConfigESP32.h:29
TickType_t timeout
Definition AnalogConfigESP32.h:24
bool auto_clear
Definition AnalogConfigESP32.h:37
int mode_internal
Definition AnalogConfigESP32.h:39
bool use_apll
Definition AnalogConfigESP32.h:33
int port_no
Definition AnalogConfigESP32.h:36
int buffer_size
Definition AnalogConfigESP32.h:26
Definition AnalogDriverBase.h:13
Please use AnalogAudioStream: A very fast ADC and DAC using the ESP32 I2S interface.
Definition AnalogDriverESP32.h:35
size_t result
Definition AnalogDriverESP32.h:211
bool active
Definition AnalogDriverESP32.h:209
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
bool is_driver_installed
Definition AnalogDriverESP32.h:210
adc1_channel_t adc_channel
Definition AnalogDriverESP32.h:215
size_t readBytes(uint8_t *dest, size_t size_bytes) override
Definition AnalogDriverESP32.h:187
adc_unit_t adc_unit
Definition AnalogDriverESP32.h:214
AnalogDriverESP32()=default
Default constructor.
void end() override
stops the I2S and unistalls the driver
Definition AnalogDriverESP32.h:137
AnalogConfigESP32 adc_config
Definition AnalogDriverESP32.h:206
i2s_port_t port_no
Definition AnalogDriverESP32.h:208
size_t outputMono(const void *src, size_t size_bytes)
Definition AnalogDriverESP32.h:302
ConverterAutoCenter auto_center
Definition AnalogDriverESP32.h:207
virtual ~AnalogDriverESP32()
Destructor.
Definition AnalogDriverESP32.h:41
size_t outputStereo(const void *src, size_t size_bytes)
Definition AnalogDriverESP32.h:261
virtual int available() override
Definition AnalogDriverESP32.h:201
Makes sure that the avg of the signal is set to 0.
Definition BaseConverter.h:198
bool begin(AudioInfo info, bool isDynamic=false)
Definition BaseConverter.h:218
size_t convert(uint8_t *src, size_t size) override
Definition BaseConverter.h:254
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:301
24bit integer which is used for I2S sound processing. The values are represented as int32_t,...
Definition Int24_4bytes_t.h:16
void stop()
stops any further processing by spinning in an endless loop
Definition AudioRuntime.h:12
@ TX_MODE
Definition AudioTypes.h:30
@ RX_MODE
Definition AudioTypes.h:30
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
static uint16_t convert8DAC(int64_t value, int value_bits_per_sample)
Definition AnalogDriverESP32.h:17
AnalogDriverArduino AnalogDriver
AnalogAudioStream.
Definition AnalogDriverArduino.h:48
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:57
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:61