5#if defined(RP2040_HOWER)
8#define IS_I2S_IMPLEMENTED
20 friend class I2SStream;
24 I2SConfigStd defaultConfig(
RxTxMode mode) {
29 bool setAudioInfo(AudioInfo info) {
30 if (info.sample_rate != cfg.sample_rate && !i2s.setFrequency(info.sample_rate)) {
31 LOGI(
"i2s.setFrequency %d failed", info.sample_rate);
34 if (info.bits_per_sample != cfg.bits_per_sample && !i2s.setBitsPerSample(info.bits_per_sample)) {
35 LOGI(
"i2s.setBitsPerSample %d failed", info.bits_per_sample);
38 cfg.sample_rate = info.sample_rate;
39 cfg.bits_per_sample = info.bits_per_sample;
40 cfg.channels = info.channels;
47 return begin(defaultConfig(mode));
51 bool begin(I2SConfigStd cfg) {
56 has_input[0] = has_input[1] =
false;
60 if (!setupMode())
return false;
67 if (!i2s.begin(cfg.sample_rate)) {
68 LOGE(
"Could not start I2S");
83 I2SConfigStd config() {
return cfg; }
86 size_t writeBytes(
const void *
src,
size_t size_bytes) {
87 LOGD(
"writeBytes(%d)", size_bytes);
90 if (cfg.channels == 1) {
91 result = writeExpandChannel(
src, size_bytes);
92 }
else if (cfg.channels == 2) {
94 while (size_bytes >=
sizeof(
int32_t)) {
109 size_t readBytes(
void *
dest,
size_t size_bytes) {
111 switch (cfg.channels) {
120 int availableForWrite() {
121 if (cfg.channels == 1) {
122 return cfg.buffer_size;
124 return i2s.availableForWrite();
128 int available() {
return min(i2s.available(), cfg.buffer_size); }
130 void flush() { i2s.flush(); }
133 return i2s.getOverUnderflow() ;
140 bool is_active =
false;
144 switch (cfg.rx_tx_mode) {
155 LOGE(
"Unsupported mode");
163#if (ARDUINO_PICO_MAJOR >= 5 && ARDUINO_PICO_MINOR >= 3)
164 if (!cfg.is_master) {
165 if (!i2s.setSlave()) {
166 LOGE(
"Could not set slave mode");
176 if (cfg.pin_ws == cfg.pin_bck + 1) {
177 if (!i2s.setBCLK(cfg.pin_bck)) {
178 LOGE(
"Could not set bck pin: %d", cfg.pin_bck);
181 }
else if (cfg.pin_ws == cfg.pin_bck - 1) {
182 if (!i2s.swapClocks() ||
185 LOGE(
"Could not set bck pin: %d", cfg.pin_bck);
189 LOGE(
"pins bck: '%d' and ws: '%d' must be next to each other",
190 cfg.pin_bck, cfg.pin_ws);
199 if (!i2s.setDOUT(cfg.pin_data)) {
200 LOGE(
"Could not set pin_data: %d with setDOUT()", cfg.pin_data);
203 if (!i2s.setDIN(cfg.pin_data_rx)) {
204 LOGE(
"Could not set pin_data_rx: %d with setDIN()", cfg.pin_data);
209 int pin = cfg.pin_data;
210 if (pin == -1) pin = cfg.pin_data_rx;
211 if (!i2s.setDATA(pin)) {
212 LOGE(
"Could not set pin_data: %d with pin_data()", pin);
221 if (cfg.pin_mck != -1) {
222 LOGI(
"Using MCK pin: %d with multiplier %d", cfg.pin_mck,
224 i2s.setMCLKmult(cfg.mck_multiplier);
225 if (!i2s.setMCLK(cfg.pin_mck)) {
226 LOGE(
"Could not set data pin: %d", cfg.pin_mck);
235 if (cfg.bits_per_sample == 8 ||
236 !i2s.setBitsPerSample(cfg.bits_per_sample)) {
237 LOGE(
"Could not set bits per sample: %d", cfg.bits_per_sample);
241 if (!i2s.setBuffers(cfg.buffer_count, cfg.buffer_size)) {
242 LOGE(
"Could not set buffers: Count: '%d', size: '%d'", cfg.buffer_count,
253 if (!i2s.setLSBJFormat()) {
254 LOGE(
"Could not set LSB Format")
258 LOGE(
"Unsupported I2S format");
262 if (cfg.signal_type !=
TDM && (cfg.channels < 1 || cfg.channels > 2)) {
263 LOGE(
"Unsupported channels: '%d'", cfg.channels);
267 if (cfg.signal_type ==
TDM) {
269 i2s.setTDMChannels(cfg.channels);
276 size_t writeExpandChannel(
const void *
src,
size_t size_bytes) {
277 switch (cfg.bits_per_sample) {
289 for (
int j = 0;
j < size_bytes /
sizeof(
int16_t);
j++) {
295 for (
int j = 0;
j < size_bytes /
sizeof(
int32_t);
j++) {
301 for (
int j = 0;
j < size_bytes /
sizeof(
int32_t);
j++) {
313 switch (cfg.bits_per_sample) {
327 for (
int j = 0;
j < size_bytes /
sizeof(
int16_t);
j += 2) {
328 if (i2s.read16(data +
j, data +
j + 1)) {
338 for (
int j = 0;
j < size_bytes /
sizeof(
int32_t);
j += 2) {
339 if (i2s.read24(data +
j, data +
j + 1)) {
349 for (
int j = 0;
j < size_bytes /
sizeof(
int32_t);
j += 2) {
350 if (i2s.read32(data +
j, data +
j + 1)) {
366 switch (cfg.bits_per_sample) {
383 for (
int j = 0;
j < size_bytes /
sizeof(
int16_t);
j++) {
384 if (i2s.read16(tmp, tmp + 1)) {
385 data[
j] =
mix(tmp[0], tmp[1]);
396 for (
int j = 0;
j < size_bytes /
sizeof(
int32_t);
j++) {
397 if (i2s.read24(tmp, tmp + 1)) {
398 data[
j] =
mix(tmp[0], tmp[1]);
409 for (
int j = 0;
j < size_bytes /
sizeof(
int32_t);
j++) {
410 if (i2s.read32(tmp, tmp + 1)) {
411 data[
j] =
mix(tmp[0], tmp[1]);
425 if (left != 0) has_input[0] =
true;
426 if (right != 0) has_input[1] =
true;
429 if (has_input[0] && !has_input[1]) {
434 if (!has_input[0] && has_input[1]) {
438 return (left / 2) + (right / 2);
#define INPUT
Definition Arduino.h:34
#define OUTPUT
Definition Arduino.h:38
#define INPUT_PULLUP
Definition Arduino.h:42
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26
constexpr const _Ep * end(initializer_list< _Ep > __il) noexcept
Definition InitializerList.h:63
constexpr const _Ep * begin(initializer_list< _Ep > __il) noexcept
Definition InitializerList.h:55