4 channels output from ESP32

MRamone
Posts: 13
Joined: Fri Jan 27, 2023 6:56 am

4 channels output from ESP32

Postby MRamone » Fri Jan 27, 2023 7:44 am

Hello,

I am a complete noob with ESP32, so please bear with me.

I understand that many ESP32 have 2 i2s that can be used simultaneously. I wonder if it is possible to get 4 channels of synchronized audio (final use is L+R speakers + two subwoofers). Ideally i would like to convert the two i2s output to two spdif going to two external stereo DACs. As you can imagine it is important that the two spdif signals share the same clock sync.

Has someone managed to do something like that or know of a source of information to achieve it?
4 channel interfaces with 2 spdif outputs are rare and expensive, if a ESP32 could do it, it would be great!!

Once solved, the next question would be how to process an incoming stereo signal to generate the 4 channels and apply the crossovers or alternatively to input (stream? via USB?) the 4 channels already processed. But that is another problem....

thanks a lot for any insight or clue.
M. Ramone

User avatar
thefury
Posts: 23
Joined: Thu Sep 05, 2019 5:25 pm

Re: 4 channels output from ESP32

Postby thefury » Wed Feb 08, 2023 9:34 pm

I'm working on a 2.1 system too. I leaned on ESP-ADF, in particular the pipeline_a2dp_sink_and_hfp demo (minus the HFP). That was the starting point for my code.

I run the I2S pair as either master + slave, or both as slave (if generating the clock somewhere else). The driver doesn't sync things automatically, but some ESP32 GPIO magic allows WS and BCLK to reside on the same pins for both, and in my experience this allows the second I2S signal to be close enough to "at the same time" to work. (I'm using a single 8-ch out DAC, but in theory it should be the same for two stereo DACs)

I have some audio DSP code in another ADF audio element that I placed in the pipeline between the bluetooth service and the i2s_w. This is where I convert from 2 channels 16-bit signed int PCM input to 4 channels 32-bit float, do EQ biquads, crossovers, volume, etc. and turn the final results into 32-bit signed int PCM. (The DAC I'm using expects 24 bits, I just do 32 bits and it uses the first 24)

For the last part of the pipeline, I'm using a custom dual_i2s_stream.c that is based on ESP-ADF's i2s_stream.c, taking the combined audio data that the DSP code created and splitting it back out for writing to each of the i2s peripherals.

I did this already on an ESP32-S3 with a dual-4ch I2S pair to create an 8ch system, but have to wait a bit before I can test the dual-stereo config on ESP32. But it should work fine

MRamone
Posts: 13
Joined: Fri Jan 27, 2023 6:56 am

Re: 4 channels output from ESP32

Postby MRamone » Thu Feb 09, 2023 6:02 am

Wow!
Thank you for your answer, that is exactly what I would like to achieve.
Do you have your project documented somewhere? I would be very interested in having a look at the details,
Thanks!

TVA_VAE
Posts: 5
Joined: Sun Nov 29, 2020 3:15 pm

Re: 4 channels output from ESP32

Postby TVA_VAE » Tue May 21, 2024 3:05 pm

MRamone wrote:
Thu Feb 09, 2023 6:02 am
Wow!
Thank you for your answer, that is exactly what I would like to achieve.
Do you have your project documented somewhere? I would be very interested in having a look at the details,
Thanks!
Any update from someone on this topic?

bubblesnake
Posts: 1
Joined: Thu Aug 04, 2022 6:07 am

Re: 4 channels output from ESP32

Postby bubblesnake » Wed May 29, 2024 8:09 am

One way to do it (might be the same as @thefury) is:

Configure one of the I2S as slave then share the clock signal.

The GPIO trick can be referred to from

Code: Select all

components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c:
i2s_test_io_config
. After I2S finishes initializing GPIO, use

Code: Select all

esp_rom_gpio_connect_out_signal
and

Code: Select all

esp_rom_gpio_connect_in_signal
to connect the clock signals of I2S0 and I2S1 on the same GPIO. This way, the clock output from the master can be directly passed to the slave.

The downside of this approach is that the write interfaces for both I2S still need to be called separately, meaning you have to perform write operations for I2S0 and I2S1 individually.

TVA_VAE
Posts: 5
Joined: Sun Nov 29, 2020 3:15 pm

Re: 4 channels output from ESP32

Postby TVA_VAE » Wed May 29, 2024 8:23 pm

bubblesnake wrote:
Wed May 29, 2024 8:09 am
One way to do it (might be the same as @thefury) is:

Configure one of the I2S as slave then share the clock signal.

The GPIO trick can be referred to from

Code: Select all

components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c:
i2s_test_io_config
. After I2S finishes initializing GPIO, use

Code: Select all

esp_rom_gpio_connect_out_signal
and

Code: Select all

esp_rom_gpio_connect_in_signal
to connect the clock signals of I2S0 and I2S1 on the same GPIO. This way, the clock output from the master can be directly passed to the slave.

The downside of this approach is that the write interfaces for both I2S still need to be called separately, meaning you have to perform write operations for I2S0 and I2S1 individually.
Thanks, we will test! But isn't the write function blocking? Meaning that it would be hard to send data synchronious over both data lines?

User avatar
thefury
Posts: 23
Joined: Thu Sep 05, 2019 5:25 pm

Re: 4 channels output from ESP32

Postby thefury » Fri Jul 12, 2024 6:15 am

bubblesnake wrote:
Wed May 29, 2024 8:09 am
One way to do it (might be the same as @thefury) is:

Configure one of the I2S as slave then share the clock signal.

The GPIO trick can be referred to from

Code: Select all

components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c:
i2s_test_io_config
. After I2S finishes initializing GPIO, use

Code: Select all

esp_rom_gpio_connect_out_signal
and

Code: Select all

esp_rom_gpio_connect_in_signal
to connect the clock signals of I2S0 and I2S1 on the same GPIO. This way, the clock output from the master can be directly passed to the slave.

The downside of this approach is that the write interfaces for both I2S still need to be called separately, meaning you have to perform write operations for I2S0 and I2S1 individually.
Yep, this is the way L-KAYA guided me to on GitHub https://github.com/espressif/esp-idf/is ... 1033331842

The problem with using two separate I2S peripherals is you can't guarantee them starting the data at the same time even if they're sharing clock, so the second pair will be out of phase by a nondeterministic amount that you would have to correct for with some other thing reinterpreting your audio on the other end (use 8 bits for channel number and 24 bits of data for example, read them and determine the phase alignment and adjust sample by sample til they're aligned, don't know if this could be done on esp32 alone by the same pin reuse trick)

qniens
Posts: 2
Joined: Mon Feb 10, 2025 11:12 am

Re: 4 channels output from ESP32

Postby qniens » Tue Feb 11, 2025 8:57 am

thefury wrote:
Fri Jul 12, 2024 6:15 am
bubblesnake wrote:
Wed May 29, 2024 8:09 am
One way to do it (might be the same as @thefury) is:

Configure one of the I2S as slave then share the clock signal.

The GPIO trick can be referred to from

Code: Select all

components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c:
i2s_test_io_config
. After I2S finishes initializing GPIO, use

Code: Select all

esp_rom_gpio_connect_out_signal
and

Code: Select all

esp_rom_gpio_connect_in_signal
to connect the clock signals of I2S0 and I2S1 on the same GPIO. This way, the clock output from the master can be directly passed to the slave.

The downside of this approach is that the write interfaces for both I2S still need to be called separately, meaning you have to perform write operations for I2S0 and I2S1 individually.
Yep, this is the way L-KAYA guided me to on GitHub https://github.com/espressif/esp-idf/is ... 1033331842

The problem with using two separate I2S peripherals is you can't guarantee them starting the data at the same time even if they're sharing clock, so the second pair will be out of phase by a nondeterministic amount that you would have to correct for with some other thing reinterpreting your audio on the other end (use 8 bits for channel number and 24 bits of data for example, read them and determine the phase alignment and adjust sample by sample til they're aligned, don't know if this could be done on esp32 alone by the same pin reuse trick)
Hi thefury, did you manage to get it working on the ESP32-S3? I’ve tried it on the ESP32 with an ADAU1701 DSP, but without success. The slave I2S peripheral is indeed out of phase, and while the audio is recognizable, it’s heavily distorted. In SigmaStudio, there’s no option to adjust the timing for individual serial inputs, as they all share the same clocks. Before I redesign my entire board, I wanted to check if you’ve had better results with the ESP32-S3.

User avatar
thefury
Posts: 23
Joined: Thu Sep 05, 2019 5:25 pm

Re: 4 channels output from ESP32

Postby thefury » Wed Feb 12, 2025 3:11 pm

I never arrived at a satisfactory solution for the S3. My next idea would've involved an intermediary between the S3's dual I2S and the codec to translate it to one single data line.

I'm now using the P4 with TDM8 32-bit on a single data wire.

qniens
Posts: 2
Joined: Mon Feb 10, 2025 11:12 am

Re: 4 channels output from ESP32

Postby qniens » Wed Feb 12, 2025 3:32 pm

thefury wrote:
Wed Feb 12, 2025 3:11 pm
I never arrived at a satisfactory solution for the S3. My next idea would've involved an intermediary between the S3's dual I2S and the codec to translate it to one single data line.

I'm now using the P4 with TDM8 32-bit on a single data wire.
Thanks for the quick response! Too bad, I was hoping the S3 would perform better, but at least this saves me a lot of design work.

The DSP on my amplifier board already uses TDM serial input for another function, so I’m stuck with multiple I2S streams… Maybe Teensy could be an option.

P4 sounds great! I assume you're using it on an eval board or one from Waveshare/Olimex?

Who is online

Users browsing this forum: No registered users and 81 guests