4 #include "AudioI2S/I2SConfig.h"
46 LOGI(
"buffer_size: %d", cfg.buffer_size);
47 LOGI(
"buffer_count: %d", cfg.buffer_count);
50 LOGE(
"Channels not supported: %d", cfg.
channels);
54 setupDefaultI2SParameters();
55 result = use_dma ? startI2SDMA() : startI2S();
56 this->active = result;
70 if (!active)
return 0;
71 if (use_dma)
return p_rx_buffer ==
nullptr ? 0 : cfg.buffer_size;
72 return cfg.buffer_size;
77 if (!active)
return 0;
78 if (use_dma)
return p_tx_buffer ==
nullptr ? 0 : cfg.buffer_size;
79 return cfg.buffer_size;
89 result = stm32_i2s::I2S.write((uint8_t *)src, size_bytes);
92 if (p_dma_in !=
nullptr) {
99 result = writeBytesDMA(src, size_bytes);
105 size_t readBytes(
void *dest,
size_t size_bytes) {
108 return stm32_i2s::I2S.readBytes((uint8_t *)dest, size_bytes);
111 return p_rx_buffer->
readArray((uint8_t *)dest, size_bytes);
113 return readBytesDMA(dest, size_bytes);
122 uint16_t written = 0;
123 if (self->p_dma_out !=
nullptr)
124 written =
self->p_dma_out->write(buffer, byteCount);
126 written =
self->p_rx_buffer->writeArray(buffer, byteCount);
129 if (written != byteCount) {
130 LOGW(
"Buffer overflow: written %d of %d", written, byteCount);
138 static size_t count = 0;
140 memset(buffer, 0, byteCount);
141 if (self->p_dma_in !=
nullptr) {
143 if (self->isWriteTimedOut()) {
148 read =
self->p_dma_in->readBytes(buffer, byteCount);
152 if (self->stm32_write_active) {
154 if (self->p_tx_buffer->available() < byteCount) {
157 read =
self->p_tx_buffer->readArray(buffer, byteCount);
166 if (read != byteCount) {
167 LOGW(
"Buffer undeflow at %lu: %d for %d", count, read, byteCount);
173 return last_write_ms != 0 && last_write_ms + 500 <
millis();
194 stm32_i2s::I2SSettingsSTM32 i2s_stm32;
198 bool stm32_write_active =
false;
200 Print *p_dma_out =
nullptr;
201 Stream *p_dma_in =
nullptr;
202 uint32_t last_write_ms = 0;
204 size_t writeBytesDMA(
const void *src,
size_t size_bytes) {
207 int open = size_bytes;
209 int actual_written = writeBytesExt(src, size_bytes);
210 result += actual_written;
211 open -= actual_written;
219 stm32_write_active =
true;
220 LOGI(
"Buffer is full->starting i2s output");
225 size_t readBytesDMA(
void *dest,
size_t size_bytes) {
227 int req_bytes = size_bytes * 2;
228 uint8_t tmp[req_bytes];
229 int16_t *tmp_16 = (int16_t *)tmp;
230 int eff_bytes = p_rx_buffer->
readArray((uint8_t *)tmp, req_bytes);
232 int16_t *dest_16 = (int16_t *)dest;
233 int16_t eff_samples = eff_bytes / 2;
235 for (
int j = 0; j < eff_samples; j += 2) {
236 dest_16[idx++] =
static_cast<float>(tmp_16[j]) + tmp_16[j + 1] / 2.0;
238 return eff_bytes / 2;
244 result = stm32_i2s::I2S.begin(i2s_stm32,
false,
true);
247 result = stm32_i2s::I2S.begin(i2s_stm32,
true,
false);
251 result = stm32_i2s::I2S.begin(i2s_stm32,
true,
true);
260 if (use_dma && p_rx_buffer ==
nullptr)
261 p_rx_buffer =
new NBuffer<uint8_t>(cfg.buffer_size, cfg.buffer_count);
265 stm32_write_active =
false;
266 if (use_dma && p_tx_buffer ==
nullptr)
267 p_tx_buffer =
new NBuffer<uint8_t>(cfg.buffer_size, cfg.buffer_count);
272 stm32_write_active =
false;
273 if (p_rx_buffer ==
nullptr)
275 new NBuffer<uint8_t>(cfg.buffer_size, cfg.buffer_count);
276 if (p_tx_buffer ==
nullptr)
278 new NBuffer<uint8_t>(cfg.buffer_size, cfg.buffer_count);
280 result = stm32_i2s::I2S.beginReadWriteDMA(
284 LOGE(
"Unsupported mode");
290 uint32_t toDataFormat(
int bits_per_sample) {
291 switch (bits_per_sample) {
293 return I2S_DATAFORMAT_16B;
295 return I2S_DATAFORMAT_24B;
297 return I2S_DATAFORMAT_32B;
299 return I2S_DATAFORMAT_16B;
302 void deleteBuffers() {
303 if (p_rx_buffer !=
nullptr) {
305 p_rx_buffer =
nullptr;
307 if (p_tx_buffer !=
nullptr) {
309 p_tx_buffer =
nullptr;
313 void setupDefaultI2SParameters() {
314 i2s_stm32.sample_rate = getSampleRate(cfg);
316 i2s_stm32.mode = getMode(cfg);
317 i2s_stm32.standard = getStandard(cfg);
318 i2s_stm32.fullduplexmode = cfg.
rx_tx_mode == RXTX_MODE
319 ? I2S_FULLDUPLEXMODE_ENABLE
320 : I2S_FULLDUPLEXMODE_DISABLE;
321 i2s_stm32.hardware_config.buffer_size = cfg.buffer_size;
323 i2s_stm32.ref =
this;
326 uint32_t getMode(I2SConfigStd &cfg) {
328 switch (cfg.rx_tx_mode) {
330 return I2S_MODE_MASTER_RX;
332 return I2S_MODE_MASTER_TX;
334 LOGE(
"RXTX_MODE not supported");
335 return I2S_MODE_MASTER_TX;
338 switch (cfg.rx_tx_mode) {
340 return I2S_MODE_SLAVE_RX;
342 return I2S_MODE_SLAVE_TX;
344 LOGE(
"RXTX_MODE not supported");
345 return I2S_MODE_SLAVE_TX;
350 uint32_t getStandard(I2SConfigStd &cfg) {
352 switch (cfg.i2s_format) {
353 case I2S_PHILIPS_FORMAT:
354 return I2S_STANDARD_PHILIPS;
357 case I2S_RIGHT_JUSTIFIED_FORMAT:
358 return I2S_STANDARD_MSB;
360 case I2S_LEFT_JUSTIFIED_FORMAT:
361 return I2S_STANDARD_LSB;
363 return I2S_STANDARD_PHILIPS;
366 uint32_t getSampleRate(I2SConfigStd &cfg) {
367 switch (cfg.sample_rate) {
368 case I2S_AUDIOFREQ_192K:
369 case I2S_AUDIOFREQ_96K:
370 case I2S_AUDIOFREQ_48K:
371 case I2S_AUDIOFREQ_44K:
372 case I2S_AUDIOFREQ_32K:
373 case I2S_AUDIOFREQ_22K:
374 case I2S_AUDIOFREQ_16K:
375 case I2S_AUDIOFREQ_11K:
376 case I2S_AUDIOFREQ_8K:
377 return cfg.sample_rate;
379 LOGE(
"Unsupported sample rate: %u", cfg.sample_rate);
380 return cfg.sample_rate;
384 size_t writeBytesExt(
const void *src,
size_t size_bytes) {
386 if (cfg.channels == 2) {
387 result = p_tx_buffer->
writeArray((uint8_t *)src, size_bytes);
390 int samples = size_bytes / 2;
391 int16_t *src_16 = (int16_t *)src;
394 for (
int j = 0; j < samples; j++) {
406 LOGD(
"writeBytesExt: %u", result)
411 using I2SDriver = I2SDriverSTM32;
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition: AudioTypes.h:26