-
-
Notifications
You must be signed in to change notification settings - Fork 309
24 Bit Audio ESP32-WROOM-32 I2S (MCLK)Clock Generation Issues With mclk.multiplier and apll #2192
-
Right now, I have configured the following code, using 24 bits (what I think the issue is), at 44.1kHz. I calculated that LRCLK, BCLK, and MCLK generated should be 44.1kHz, 2.1186MHz, and 11.2896MHz, respectively. Attached are the readings for each clock, and I have come to find that in the I2SESP32V1 header file, if there is a 24 bit resolution, the mclk multiplier is to be automatically set to 384. This is fine, but the boolean apll doubles to clock for some reason, going outside of the range of my PCM1808 ADC. The MCLK I'm seeing is also always analog for whatever reason. I have tried changing the mclk multiplier, but that absolutely destroys the other clocks and the MCLK, making them unmeasurable.
I was wondering if anyone had anything you found using the AudioTools Library, and generating MCLK on the ESP32 with a 24 bit resolution.
#include "AudioTools.h"
#define I2S_BCLK 21
#define I2S_LRCLK 19
#define I2S_DIN 22
#define I2S_DOUT 27
#define I2S_MCLK 3
const int SAMPLE_RATE = 44100;
const int BITS_PER_SAMPLE = 24;
//Uses one I2S instance to do both input and output
//It talks to ESP-IDF’s i2s_driver_install(), sets up DMA buffers, and handles timing for full-duplex communication
//It’s the same object, but two separate hardware buffers inside
I2SStream i2sStream;
//Basically set up as StreamCopy copier(source, destination)
//Utility to move data between two streams
StreamCopy copier(i2sStream, i2sStream); // copies sound into i2s
void setup(void) {
Serial.begin(115200);
//debugger
AudioLogger::instance().begin(Serial, AudioLogger::Warning);
// start I2S in
Serial.println("starting I2S...");
// start I2S in
auto config = i2sStream.defaultConfig(RXTX_MODE);
config.sample_rate = SAMPLE_RATE;
config.bits_per_sample = BITS_PER_SAMPLE;
config.i2s_format = I2S_STD_FORMAT;
config.is_master = true;
//set to use I2S_NUM_0 ESP32 I2S peripheral
config.port_no = 0;
config.pin_ws = I2S_LRCLK;
config.pin_bck = I2S_BCLK;
config.pin_data = I2S_DOUT;
config.pin_data_rx = I2S_DIN;
config.pin_mck = I2S_MCLK;
config.use_apll = true;
i2sStream.begin(config);
Serial.println("I2S started...");
}
void loop() {
//copies data from the RX DMA buffer (data from DIN) to the TX DMA buffer (data on DOUT)
copier.copy();
}
Beta Was this translation helpful? Give feedback.
All reactions
As you can read in the IDF documentation for 24 bits the the multiples need to be divisible by 3.
I would suggest to try with 32 bits which does not have this restriction.
After all 24 bits is also represented by a int32_t!
If you get a wrong frequency when using the apll, then I guess this might be a bug in the IDF core. So if it is doubled, did you try to set the the mclk_multiple to 192 ?
Replies: 1 comment 3 replies
-
As you can read in the IDF documentation for 24 bits the the multiples need to be divisible by 3.
I would suggest to try with 32 bits which does not have this restriction.
After all 24 bits is also represented by a int32_t!
If you get a wrong frequency when using the apll, then I guess this might be a bug in the IDF core. So if it is doubled, did you try to set the the mclk_multiple to 192 ?
Beta Was this translation helpful? Give feedback.
All reactions
-
I committed a correction as a response to this bug to use 192 when apll is set.
Beta Was this translation helpful? Give feedback.
All reactions
-
Okay perfect, that works and gives the 384*44.1khz that I'm looking for. Thank you so much.
I am also wondering why the MCLK looks analog, is it just due to the ESP32 and the GPIO3 pin?
Beta Was this translation helpful? Give feedback.
All reactions
-
Updated MCLK using 192 multiplier (doubling occurs still) using 44.1kHz.
Beta Was this translation helpful? Give feedback.