// SPDX-License-Identifier: GPL-3.0-only #include "audio.h" #include // bundled with Arduino-ESP32 3.x #include "audio_config.h" #include "pins.h" namespace { I2SClass i2s; } namespace audio { bool begin() { #if defined(OPENSCRIBE_BOARD_XIAO) // XIAO ESP32-S3 Sense onboard PDM microphone. i2s.setPinsPdmRx(PIN_PDM_CLK, PIN_PDM_DIN); return i2s.begin(I2S_MODE_PDM_RX, OSC_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); #else // I2S standard mode from an external MEMS mic (INMP441 / ICS-43434). // Args: bclk, ws, dout(unused for RX = -1), din, mclk(unused = -1). i2s.setPins(PIN_I2S_BCLK, PIN_I2S_WS, -1, PIN_I2S_DIN, -1); return i2s.begin(I2S_MODE_STD, OSC_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); #endif } size_t audio::read(uint8_t *dst, size_t maxBytes) { // I2SClass::readBytes blocks until data is available or the DMA times out. int n = i2s.readBytes(reinterpret_cast(dst), maxBytes); return n < 0 ? 0 : static_cast(n); } void end() { i2s.end(); } } // namespace audio // NOTE (calibration, revisit with hardware): INMP441 emits 24-bit samples in a 32-bit // slot. Reading in 16-bit mode captures the top bits and is usable for speech but may be // quiet. If levels are low on the dev build, switch to 32-bit capture and right-shift into // int16 here. Tracked in state/TODO.md.