Dual I2S Output With Different Sample Rates #330
-
Hello, I'm currently using the following code to achieve what I'm trying to do. To summarize: Things I tried:
A few questions:
THE CODE: /* Double Output -> Double Trouble */
/* This might work someday. Currently it is buggy AF */
#include <Arduino.h>
#include "driver/i2s.h"
#include <soc/i2s_reg.h>
#include "esp_intr_alloc.h"
#include "BluetoothA2DPSink.h"
#include "SoundData.h"
// Full output port
static const i2s_port_t PORT_DAC = I2S_NUM_0;
static const i2s_pin_config_t PINS_DAC = {
.bck_io_num = 18,
.ws_io_num = 19,
.data_out_num = 21,
.data_in_num = I2S_PIN_NO_CHANGE
};
static const i2s_config_t I2S_CONFIG_DAC = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = 44100,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 1024,
.use_apll = true,
//.tx_desc_auto_clear = true
};
// Limited output (mono + 22.05kHz)
static const i2s_port_t PORT_WLED = I2S_NUM_1;
static const i2s_pin_config_t PINS_WLED = {
.bck_io_num = 22,
.ws_io_num = 25,
.data_out_num = 27,
.data_in_num = I2S_PIN_NO_CHANGE
};
static const i2s_config_t I2S_CONFIG_WLED = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = 22050,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 768,
//.use_apll = true,
//.tx_desc_auto_clear = true
};
BluetoothA2DPSink a2dp_sink;
void data_received_callback(const uint8_t *data, uint32_t length) {
int bytesWritten;
esp_err_t err;
Frame *samples = (Frame *) data;
err = i2s_write_expand(PORT_DAC, data, length, 16, 32, (size_t*)&bytesWritten, portMAX_DELAY);
if(err != ESP_OK) {
Serial.println("Err: Could not write data to DAC I2S!");
}
// Super crude downsampling for second port
for(uint32_t i = 0; i < length / 4; i++) {
// int16_t leftSample = samples[i * 4].channel1;
// int16_t rightSample = samples[i * 4].channel2;
// samples[i] = (leftSample + rightSample) / 2;
samples[i] = samples[i * 4];
}
err = i2s_write_expand(PORT_WLED, data, length / 4, 16, 32, (size_t*)&bytesWritten, portMAX_DELAY);
if(err != ESP_OK) {
Serial.println("Err: Could not write data to WLED I2S!");
}
}
///////////
// SETUP //
///////////
void setup() {
// Serial.begin(115200);
esp_err_t err;
// Just in case ;)
i2s_driver_uninstall(I2S_NUM_0);
i2s_driver_uninstall(I2S_NUM_1);
// I2S drivers
err = i2s_driver_install(PORT_DAC, &I2S_CONFIG_DAC, 0, NULL);
if(err != ESP_OK) {
Serial.println("Setup of DAC I2S failed!");
}
err = i2s_driver_install(PORT_WLED, &I2S_CONFIG_WLED, 0, NULL);
if(err != ESP_OK) {
Serial.println("Setup of WLED I2S failed!");
}
// Pin config
err = i2s_set_pin(PORT_DAC, &PINS_DAC);
if(err != ESP_OK) {
Serial.println("Setup of DAC I2S pins failed!");
}
err = i2s_set_pin(PORT_WLED, &PINS_WLED);
if(err != ESP_OK) {
Serial.println("Setup of WLED I2S pins failed!");
}
// I2S0 MCLK -> GPIO0
REG_WRITE(PIN_CTRL, 0xFF0);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
a2dp_sink.set_stream_reader(data_received_callback, false);
a2dp_sink.start("Party", true);
}
//////////
// LOOP //
//////////
void loop() {
delay(50);
} |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 4 replies
-
I tend to think that it is a hardware problem and you don't provide enugh power for 2 output devices, I therefore suggest you try to power the two DACs from a separate source. |
Beta Was this translation helpful? Give feedback.
-
I really thought you were onto something. But sadly the issue persists. I'm now using a 5v 4A supply to power the ESP and dac on i2s1 and a 12v 3a power supply to power the dac on i2s0. The same distortion still happens. |
Beta Was this translation helpful? Give feedback.
-
If it is not hardware, then I would suggest to try 2 different ESP32 implementations: 2.0.4 and 1.0.6. |
Beta Was this translation helpful? Give feedback.
-
You were onto something. I needed to divide the samples by 2 since I'm using Frames now that are 32bit. Once I'd done that it worked while powering the ESP from USB with serial monitor, dac0 from 12v and dac1 from 5v external. I now also tried to memcpy the data and send the copy to the second dac. This also didn't help. |
Beta Was this translation helpful? Give feedback.
I tend to think that it is a hardware problem and you don't provide enugh power for 2 output devices, I therefore suggest you try to power the two DACs from a separate source.