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: 20
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: 20
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)

Who is online

Users browsing this forum: No registered users and 10 guests