pschatzmann / arduino-audio-tools

Arduino Audio Tools (a powerful Audio library not only for Arduino)
GNU General Public License v3.0
1.42k stars 222 forks source link

Getting two outputs I2S and Internal DAC from A2DP stream. #55

Closed dev-techshlok closed 2 years ago

dev-techshlok commented 2 years ago

Hello @pschatzmann

Is it possible to get two outputs from ESP32?

Example 1 in sink mode I am receiving audio from A2DP to my esp32 board. Now usually I can either pass it to internal DAC or External DAC using I2S. Is it possible to use both same times?

Example 2 in source mode Receiving audio from I2S and passing it to A2DP stream, meanwhile also pass the I2S output to internal DAC too.

Please let me know your thoughts.

Thank You.

pschatzmann commented 2 years ago

I have never tried, but it should be possible. My default the I2SConfig is using the port_no=0. You can create another I2SStream on port 1 for doing input or output

dev-techshlok commented 2 years ago

Can you give me a small example, hint on how to set up I2S on internal DAC and how to set up seconds port for I2S?

How to copy these settings

////default see below (can be changed) //i2s_pin_config_t my_pin_config = { // .bck_io_num = 26,//dac // .ws_io_num = 25,//dac // .data_out_num = 22,//clk // .data_in_num = I2S_PIN_NO_CHANGE//sda //};

//a2dp_sink.set_pin_config(my_pin_config); //i2s.

//static const i2s_config_t i2s_config = { //.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX), //.sample_rate = 44100, // corrected by info from bluetooth //.bits_per_sample = (i2s_bits_per_sample_t)16, / the DAC module will only take the 8bits from MSB / //.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //.communication_format = I2S_COMM_FORMAT_I2S_MSB, //.intr_alloc_flags = 0, // default interrupt priority //.dma_buf_count = 8, //.dma_buf_len = 64, //.use_apll = false //};

to this type one.

auto cfg = i2sStream.defaultConfig(RX_MODE);
  cfg.is_master = false;
  cfg.use_apll = true;
  cfg.sample_rate = 44100;
  cfg.bits_per_sample = (i2s_bits_per_sample_t)16;
  i2sStream.begin(cfg);
pschatzmann commented 2 years ago

Port 0:

auto cfg = i2sStream1.defaultConfig(RX_MODE);
 cfg.port_no=0
 cfg.is_master = false;
 cfg.use_apll = true;
 cfg.sample_rate = 44100;
 cfg.bits_per_sample = (i2s_bits_per_sample_t)16;
 i2sStream1.begin(cfg);

Port 1

auto cfg = i2sStream2.defaultConfig(TX_MODE);
 cfg.port_no=1
 cfg.is_master = true;
 cfg.use_apll = true;
 cfg.sample_rate = 44100;
 cfg.bits_per_sample = (i2s_bits_per_sample_t)16;
 i2sStream2.begin(cfg);

Please note that in case you use the internal DAC or ADC they need to be on port 0.

dev-techshlok commented 2 years ago

Hello Thank you for the quick response.

This is the output for the above help.

starting I2S...
[I] I2SConfig.h : 63 - rx/tx mode: RX
[I] I2SConfig.h : 64 - port_no: 1
[I] I2SConfig.h : 65 - is_master: Slave
[I] I2SConfig.h : 66 - sample rate: 44100
[I] I2SConfig.h : 67 - bits per sample: 16
[I] I2SConfig.h : 68 - number of channels: 2
[I] I2SConfig.h : 69 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 72 - use_apll: true
[I] I2SConfig.h : 73 - apll_frequency_factor: 0
[I] I2SConfig.h : 77 - pin_ws: 15
[I] I2SConfig.h : 78 - pin_bck: 14
[I] I2SConfig.h : 79 - pin_data: 32
[I] I2SConfig.h : 63 - rx/tx mode: TX
[I] I2SConfig.h : 64 - port_no: 0
[I] I2SConfig.h : 65 - is_master: Master
[I] I2SConfig.h : 66 - sample rate: 44100
[I] I2SConfig.h : 67 - bits per sample: 16
[I] I2SConfig.h : 68 - number of channels: 2
[I] I2SConfig.h : 69 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 72 - use_apll: true
[I] I2SConfig.h : 73 - apll_frequency_factor: 0
[I] I2SConfig.h : 77 - pin_ws: 15
[I] I2SConfig.h : 78 - pin_bck: 14
[I] I2SConfig.h : 79 - pin_data: 22

I have two doubts.

  1. How to configure port0 to internal DAC output.
  2. What pins can I use for port0 for I2S when set to internal.

I have used these

 auto cfg = i2sStream1.defaultConfig(RX_MODE);
  cfg.port_no = 1;
  cfg.pin_ws = 15;
  cfg.pin_bck = 14;
  cfg.pin_data = 32;
  cfg.is_master = false;
  cfg.use_apll = true;
  cfg.sample_rate = 44100;
  cfg.bits_per_sample = (i2s_bits_per_sample_t)16;
  i2sStream1.begin(cfg);

  auto cfg1 = i2sStream2.defaultConfig(TX_MODE);
  cfg1.port_no = 0;
  cfg.pin_ws = 22;
  cfg.pin_bck = 26;
  cfg.pin_data = 25;
  cfg1.is_master = true;
  cfg1.use_apll = true;
  cfg1.sample_rate = 44100;
  cfg1.bits_per_sample = (i2s_bits_per_sample_t)16;
  i2sStream2.begin(cfg1);
pschatzmann commented 2 years ago

Check out the examples for AnalogAudioStream. This is using I2S with the internal DAC and ADC

dev-techshlok commented 2 years ago

Hello,

I tried using the above method. Worked fine.

The only problem is that I am receiving broken signals on Bluetooth headphones. I think it is because these streams are causing delays, which leads to problems with sound.

I even tried to run the code in the second core of ESP too. But that also works the same.

Right now just going with parallel I2S using external IC. You can close this issue after your views on the same.

Thank you for all the help on this topic.

pschatzmann commented 2 years ago

In AudioConfig.h there are a couple of buffer parameters that might maybe help: I2S_BUFFER_SIZE I2S_BUFFER_COUNT A2DP_BUFFER_SIZE A2DP_BUFFER_COUnT

dev-techshlok commented 2 years ago

Hello,

Thank you I'll try this and let you also know what worked. I was looking for something real-time for both DAC and I2S A2dp. As this is not possible with buffer.