pschatzmann / arduino-audio-tools

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

There is no audio or data from the I2S device. #351

Closed janczeresnia closed 2 years ago

janczeresnia commented 2 years ago

Hi, I have a problem with starting the I2S INMP441 microphone. None of the examples work. (streams-i2s-a2dp.ino streams-i2s-serial_16bit.ino streams-i2s-i2s.ino). I checked the electrical connections are ok. SCK - GPIO14 WS - GPIO15 DATA - GPIO32 (from microphone) DATA - GPIO13 (to DAC)

Serial log i2s to serial 16bit:

[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 16
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:0
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 14
[I] I2SConfig.h : 116 - pin_ws: 15
[I] I2SConfig.h : 117 - pin_data: 32

No data on serial.

Serial log from i2s to a2dp:

[I] AudioStreams.h : 1104 - setVolume: 0.500000
[I] AudioStreams.h : 1104 - setVolume: 0.500000
starting A2DP...
[I] AudioA2DP.h : 135 - Connecting to JBL Flip
[I] AudioA2DP.h : 142 - Starting a2dp_source...
[W] AudioA2DP.h : 302 - ==> state: Connecting
[W] AudioA2DP.h : 302 - ==> state: Connected

There is no sound.

Serial log from i2s to i2s:

starting I2S...
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 16
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:165
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 15
[I] I2SConfig.h : 116 - pin_ws: 14
[I] I2SConfig.h : 117 - pin_data: 13
[I] I2SConfig.h : 119 - pin_data_rx: 32
I2S started...
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
...

There is no sound.

In the i2s to i2s configuration, the RXTX_MODE mode is set but the log shows RX.

auto config = i2s.defaultConfig(RXTX_MODE);

The microphone INMP441 and DAC MAX98357 works, I tested with the example of I2S FullDuplex for the esp32-wroom-DA board and There is sound.

an example that works:

// I2S DAC MAX98357 and INMP441
#define DOUT_PIN 32   // DATA | SD_IN
#define DIN_PIN 13    // DATA | SD_OUT
#define BCLK_PIN 14   // BCK  | SCK
#define LRCLK_PIN 15  // WS   | FS

#include <I2S.h>
const long sampleRate = 16000;
const int bitsPerSample = 32;
uint8_t *buffer;

void setup() {
  Serial.begin(115200);
  while (!Serial && (millis() < 1000)) delay(1000);
  Serial.println(F("\nESP32 I2S FullDuplex\n"));
  // int setAllPins(int sckPin, int fsPin, int sdPin, int outSdPin, int inSdPin)
  I2S.setAllPins(BCLK_PIN, LRCLK_PIN, DIN_PIN, DIN_PIN, DOUT_PIN);
  if(!I2S.setDuplex()){
    Serial.println("ERROR - could not set duplex");
    while(true){
      vTaskDelay(10); // Cannot continue
    }
  }
  if (!I2S.begin(I2S_PHILIPS_MODE, sampleRate, bitsPerSample)) {
    Serial.println("Failed to initialize I2S!");
    while(true){
      vTaskDelay(10); // Cannot continue
    }
  }
  buffer = (uint8_t*) malloc(I2S.getBufferSize() * (bitsPerSample / 8));
  if(buffer == NULL){
    Serial.println("Failed to allocate buffer!");
    while(true){
      vTaskDelay(10); // Cannot continue
    }
  }
  Serial.println("I2S Setup done");
}

void loop() {
  // Buffer based implementation
  I2S.read(buffer, I2S.getBufferSize() * (bitsPerSample / 8));
  I2S.write(buffer, I2S.getBufferSize() * (bitsPerSample / 8));

  optimistic_yield(1000); // yield if last yield occurred before <parameter> CPU clock cycles ago
}

Regards.

pschatzmann commented 2 years ago

That's very strange! I don't see anything that could be wrong. What is the full output of the log for streams-i2s-serial.ino ? I expect that you see some [I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops lines just followed by csv data

janczeresnia commented 2 years ago

Serial log from i2s to serial 16bit:

[D] I2SStream.h : 92 - void audio_tools::I2SStream::begin(audio_tools::I2SConfig)
[D] I2SESP32.h : 42 - bool audio_tools::I2SBase::begin(audio_tools::I2SConfig)
[D] I2SESP32.h : 138 - bool audio_tools::I2SBase::begin(audio_tools::I2SConfig, int, int)
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 16
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:0
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 14
[I] I2SConfig.h : 116 - pin_ws: 15
[I] I2SConfig.h : 117 - pin_data: 32
[D] I2SESP32.h : 166 - i2s_driver_install
[D] I2SESP32.h : 183 - i2s_set_pin
[D] I2SESP32.h : 194 - i2s_zero_dma_buffer
[D] I2SESP32.h : 198 - begin - started
[D] AudioOutput.h : 112 - void audio_tools::CsvStream<T>::begin(audio_tools::AudioBaseInfo) [with T = short int]
[D] AudioCopy.h : 91 - size_t audio_tools::StreamCopyT<T>::copy() [with T = unsigned char; size_t = unsigned int]
[D] AudioCopy.h : 91 - size_t audio_tools::StreamCopyT<T>::copy() [with T = unsigned char; size_t = unsigned int]
...

Maybe the microphone I bought from china is broken. In the example for i2s FullDuplex for the esp32-wroom board which works and is sound. The sound is of very poor quality.

pschatzmann commented 2 years ago

Oh, recently I made a change to the AudioCopy logic to support a new scenario. Let me double check if I messed up! As far as the quality is concearned: with 16 bits there is usually noise on the empty channel. So I suggest that you use 32 bits or filter out the noisy channel...

I just undid my latest change to the StreamCopy!

janczeresnia commented 2 years ago

Now there is some data in the example i2s to serial:

[D] I2SStream.h : 92 - void audio_tools::I2SStream::begin(audio_tools::I2SConfig)
[D] I2SESP32.h : 42 - bool audio_tools::I2SBase::begin(audio_tools::I2SConfig)
[D] I2SESP32.h : 138 - bool audio_tools::I2SBase::begin(audio_tools::I2SConfig, int, int)
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 16
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:0
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 14
[I] I2SConfig.h : 116 - pin_ws: 15
[I] I2SConfig.h : 117 - pin_data: 32
[D] I2SESP32.h : 166 - i2s_driver_install
[D] I2SESP32.h : 183 - i2s_set_pin
[D] I2SESP32.h : 194 - i2s_zero_dma_buffer
[D] I2SESP32.h : 198 - begin - started
[D] AudioOutput.h : 112 - void audio_tools::CsvStream<T>::begin(audio_tools::AudioBaseInfo) [with T = short int]
[D] AudioCopy.h : 91 - size_t audio_tools::StreamCopyT<T>::copy() [with T = unsigned char; size_t = unsigned int]
[D] AudioOutput.h : 141 - size_t audio_tools::CsvStream<T>::write(const uint8_t*, size_t) [with T = short int; size_t = unsigned int; uint8_t = unsigned char]
0, 0
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
[D] AudioCopy.h : 91 - size_t audio_tools::StreamCopyT<T>::copy() [with T = unsigned char; size_t = unsigned int]
[D] AudioOutput.h : 141 - size_t audio_tools::CsvStream<T>::write(const uint8_t*, size_t) [with T = short int; size_t = unsigned int; uint8_t = unsigned char]
0, -928
-32768, -925
-32768, -925
-32768, -925
-32768, -925
-32768, -925
-32768, -925
0, -924
0, -924
...

example i2s to i2s not working:

[D] I2SStream.h : 92 - void audio_tools::I2SStream::begin(audio_tools::I2SConfig)
[D] I2SESP32.h : 42 - bool audio_tools::I2SBase::begin(audio_tools::I2SConfig)
[D] I2SESP32.h : 138 - bool audio_tools::I2SBase::begin(audio_tools::I2SConfig, int, int)
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 16
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:165
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 15
[I] I2SConfig.h : 116 - pin_ws: 14
[I] I2SConfig.h : 117 - pin_data: 13
[I] I2SConfig.h : 119 - pin_data_rx: 32
[D] I2SESP32.h : 166 - i2s_driver_install
[D] I2SESP32.h : 183 - i2s_set_pin
[D] I2SESP32.h : 194 - i2s_zero_dma_buffer
[D] I2SESP32.h : 198 - begin - started
I2S started...
[D] AudioCopy.h : 91 - size_t audio_tools::StreamCopyT<T>::copy() [with T = unsigned char; size_t = unsigned int]
[D] I2SStream.h : 125 - virtual size_t audio_tools::I2SStream::write(const uint8_t*, size_t)
[D] I2SESP32.h : 80 - size_t audio_tools::I2SBase::writeBytes(const void*, size_t)
[D] I2SESP32.h : 87 - i2s_write 1024 -> 1024 bytes
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
[D] AudioCopy.h : 91 - size_t audio_tools::StreamCopyT<T>::copy() [with T = unsigned char; size_t = unsigned int]
[D] I2SStream.h : 125 - virtual size_t audio_tools::I2SStream::write(const uint8_t*, size_t)
[D] I2SESP32.h : 80 - size_t audio_tools::I2SBase::writeBytes(const void*, size_t)
[D] I2SESP32.h : 87 - i2s_write 1024 -> 1024 bytes
...

In the i2s to i2s configuration, the RXTX_MODE is set but the log shows RX.

And i2s to a2dp:

[I] AudioStreams.h : 1104 - setVolume: 0.500000
[I] AudioStreams.h : 1104 - setVolume: 0.500000
starting A2DP...
[I] AudioA2DP.h : 135 - Connecting to JBL Flip
[I] AudioA2DP.h : 142 - Starting a2dp_source...
[D] AudioA2DP.h : 149 - waiting for connection
[D] AudioA2DP.h : 149 - waiting for connection
[D] AudioA2DP.h : 149 - waiting for connection
[D] AudioA2DP.h : 149 - waiting for connection
[D] AudioA2DP.h : 149 - waiting for connection
[D] AudioA2DP.h : 149 - waiting for connection
[D] AudioA2DP.h : 149 - waiting for connection
[D] AudioA2DP.h : 149 - waiting for connection
...
pschatzmann commented 2 years ago

Let's first finsh the Serial example to make sure that you get correct data: set the log level to Warning and look at the data in the Serial Plotter. The few data points that you have added to the log do not look promising... If you don't see proper sound waves there is no point to advance...

ps. looking at the log: i2s - i2s seems to be working. Just change the log level back to Info or for better audio quality to warning...

janczeresnia commented 2 years ago

On the plotter data is wrong:

0, 0
0, 0
0, 0
-32768, -773
-32768, -773
0, -776
0, -776
-32768, -773
-32768, -773
-32768, -773
-32768, -773
-32768, -773
-32768, -773
-32768, -769
-32768, -769
-32768, -769
-32768, -769
-32768, -769
-32768, -769
0, -768
0, -768
0, -768
0, -768
-32768, -769
-32768, -769
-32768, -769
-32768, -769
-32768, -769
-32768, -769
0, -768
0, -768
0, -768
0, -768
-32768, -765
-32768, -765
0, -768
0, -768
0, -768
0, -768
-32768, -765
-32768, -765
-32768, -765
-32768, -765
-32768, -765
-32768, -765
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
0, -764
-32768, -761
-32768, -761
-32768, -757
-32768, -757
-32768, -761
-32768, -761
-32768, -761
-32768, -761
0, -760
0, -760
0, -760
0, -760
-32768, -757
-32768, -757
0, -760
0, -760
0, -756
0, -756
0, -756
0, -756
-32768, -753
-32768, -753
0, -756
0, -756
0, -756
0, -756
-32768, -757
-32768, -757
-32768, -757
-32768, -757
-32768, -757
-32768, -757
-32768, -757
-32768, -757
0, -760
0, -760
0, -760
0, -760
0, -760
0, -760
-32768, -757
-32768, -757
0, -756
0, -756
-32768, -753
-32768, -753
-32768, -753
-32768, -753
-32768, -753
-32768, -753
0, -752
0, -752
-32768, -753
-32768, -753
-32768, -753
-32768, -753
0, -756
0, -756
-32768, -753
-32768, -753
-32768, -753
-32768, -753
-32768, -753
-32768, -753
-32768, -753
-32768, -753
-32768, -753
-32768, -753
0, -752
0, -752
-32768, -753
-32768, -753
0, -752
0, -752
-32768, -749
-32768, -749
-32768, -749
-32768, -749
-32768, -749
-32768, -749
0, -748
0, -748
0, -748
0, -748
0, -748
0, -748
-32768, -749
-32768, -749
0, -752
0, -752
-32768, -749
-32768, -749
-32768, -749
-32768, -749
-32768, -749
-32768, -749
0, -748
0, -748
-32768, -745
-32768, -745
-32768, -741
-32768, -741
0, -744
0, -744
0, -744
0, -744
0, -740
0, -740
0, -740
0, -740
-32768, -741
-32768, -741
-32768, -741
-32768, -741
-32768, -741
-32768, -741
-32768, -741
-32768, -741
0, -740
0, -740
0, -740
0, -740
-32768, -737
-32768, -737
-32768, -737
-32768, -737
-32768, -737
-32768, -737
-32768, -737
-32768, -737
0, -736
0, -736
-32768, -737
-32768, -737
0, -736
0, -736
0, -736
0, -736
0, -736
0, -736
0, -736
0, -736
-32768, -737
-32768, -737
-32768, -737
-32768, -737
0, -740
0, -740
-32768, -737
-32768, -737
0, -736
0, -736
0, -736
0, -736
0, -736
0, -736
0, -732
0, -732
0, -732
0, -732
pschatzmann commented 2 years ago

That's not valid audio! Did you try with 32 bits ?

janczeresnia commented 2 years ago

on the i2s to i2s Info log:

starting I2S...
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 16
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:165
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 15
[I] I2SConfig.h : 116 - pin_ws: 14
[I] I2SConfig.h : 117 - pin_data: 13
[I] I2SConfig.h : 119 - pin_data_rx: 32
I2S started...
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
over and over again.

there's no sound

janczeresnia commented 2 years ago

i2s to i2s 32bit:

starting I2S...
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 32
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:165
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 15
[I] I2SConfig.h : 116 - pin_ws: 14
[I] I2SConfig.h : 117 - pin_data: 13
[I] I2SConfig.h : 119 - pin_data_rx: 32
I2S started...
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops

there's no sound

pschatzmann commented 2 years ago

But do you get now proper sound waves in the Plotter ?

janczeresnia commented 2 years ago

Yes This looks good on a Plotter when I turned on 32bit. in the example, i2s to serial

pschatzmann commented 2 years ago

Cool! Now, Double check the example: I think for the I2S-I2S you opened with the wrong mode! auto config = i2s.defaultConfig(RXTX_MODE);

janczeresnia commented 2 years ago

example i2s to i2s:

/**
 * ESP32 i2s to i2s
 * https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-i2s-i2s/streams-i2s-i2s.ino
 */

#include "AudioTools.h"

uint16_t sample_rate=44100;
uint16_t channels = 2;
uint16_t bits_per_sample = 32; // or try with 24 or 32

I2SStream i2s;
StreamCopy copier(i2s, i2s); // copies sound into i2s

// Arduino Setup
void setup(void) {  
  // Open Serial 
  Serial.begin(115200);
  while (!Serial && (millis() < 1000)) delay(1000);
  Serial.println(F("Starting I2S to I2S one i2s ports"));
  AudioLogger::instance().begin(Serial, AudioLogger::Info);
  //AudioLogger::instance().begin(Serial, AudioLogger::Warning);
  //AudioLogger::instance().begin(Serial, AudioLogger::Debug); 

  // start I2S in Microphone and I2S DAC
  Serial.println("starting I2S...");
  auto config = i2s.defaultConfig(RXTX_MODE);
  config.sample_rate = sample_rate; 
  config.bits_per_sample = bits_per_sample; 
  config.channels = 2;
  config.i2s_format = I2S_STD_FORMAT;
  config.pin_ws = 14;
  config.pin_bck = 15;
  config.pin_data = 13;
  config.pin_data_rx = 32;
  //config.fixed_mclk = sample_rate * 256;
  // config.pin_mck = 3; // must be 0,1 or 3 - only for ESP_IDF_VERSION_MAJOR >= 4
  i2s.begin(config);

  Serial.println("I2S started...");
}

// Arduino loop - copy sound to out 
void loop() {
  copier.copy();
}

log:

Starting I2S to I2S one i2s ports
starting I2S...
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 32
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:165
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 15
[I] I2SConfig.h : 116 - pin_ws: 14
[I] I2SConfig.h : 117 - pin_data: 13
[I] I2SConfig.h : 119 - pin_data_rx: 32
I2S started...
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops

no sound

pschatzmann commented 2 years ago

Strange! I never tried MAX98357 with 32 bits however... I hope you don't have the Adafruit version which requires I2S_LSB_FORMAT

janczeresnia commented 2 years ago

I have an internet radio on an other micro-controller on your library with DAC MAX98357 works great, but the player is probably 16bit.

janczeresnia commented 2 years ago

I have a cheap Chinese board with DAC MAX98357

pschatzmann commented 2 years ago

I suggest that you test the output with a sine example... There you can also figure out if you can change it to 32 bits. https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-generator-i2s/streams-generator-i2s.ino

janczeresnia commented 2 years ago

16bit Generator to i2s work great.

janczeresnia commented 2 years ago

32bit generator to i2s work great

pschatzmann commented 2 years ago

Can it be that the MAX98357 only outputs one channel and by bad luck it is the silent one ? Did you tap on the mic ? maybe the volume is too low...

janczeresnia commented 2 years ago

I was screaming, tapping the microphone and nothing.

janczeresnia commented 2 years ago

In the example i2s to a2dp, I have a filler that copies the left channel to the right channel and nothing. I also checked right-to-left copying.

janczeresnia commented 2 years ago

But I will try to add a channel copy filler to the i2s to i2s example.

pschatzmann commented 2 years ago

ConverterFillLeftAndRight might help

janczeresnia commented 2 years ago

32 bit with filler ConverterFillLeftAndRight filler(LeftIsEmpty); // no sound ConverterFillLeftAndRight filler(RightIsEmpty); // no sound

sketch i2s to i2s:

/**
 * ESP32 i2s to i2s one port full-duplex
 * https://github.com/pschatzmann/arduino-audio-tools/blob/main/examples/examples-stream/streams-i2s-i2s/streams-i2s-i2s.ino
 */

#include "AudioTools.h"

uint16_t sample_rate=44100;
uint16_t channels = 2;
uint16_t bits_per_sample = 32; // or try with 24 or 32

I2SStream i2s;
StreamCopy copier(i2s, i2s); // copies sound into i2s
ConverterFillLeftAndRight<int32_t> filler(LeftIsEmpty); // fill both channels
//ConverterFillLeftAndRight<int32_t> filler(RightIsEmpty); // fill both channels

// Arduino Setup
void setup(void) {  
  // Open Serial 
  Serial.begin(115200);
  while (!Serial && (millis() < 1000)) delay(1000);
  Serial.println(F("Starting I2S to I2S one i2s ports"));
  AudioLogger::instance().begin(Serial, AudioLogger::Info);
  //AudioLogger::instance().begin(Serial, AudioLogger::Warning);
  //AudioLogger::instance().begin(Serial, AudioLogger::Debug); 

  // start I2S in Microphone and I2S DAC
  Serial.println("starting I2S...");
  auto config = i2s.defaultConfig(RXTX_MODE);
  config.sample_rate = sample_rate; 
  config.bits_per_sample = bits_per_sample; 
  config.channels = 2;
  config.i2s_format = I2S_STD_FORMAT;
  config.pin_ws = 14;
  config.pin_bck = 15;
  config.pin_data = 13;
  config.pin_data_rx = 32;
  //config.fixed_mclk = sample_rate * 256;
  // config.pin_mck = 3; // must be 0,1 or 3 - only for ESP_IDF_VERSION_MAJOR >= 4
  i2s.begin(config);

  Serial.println("I2S started...");
}

// Arduino loop - copy sound to out 
void loop() {
  copier.copy(filler);
  //copier.copy();
}

total silence

serial log:

Starting I2S to I2S one i2s ports
starting I2S...
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 32
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:165
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 15
[I] I2SConfig.h : 116 - pin_ws: 14
[I] I2SConfig.h : 117 - pin_data: 13
[I] I2SConfig.h : 119 - pin_data_rx: 32
I2S started...
[I] AudioCopy.h : 353 - StreamCopy::copy 1024 bytes - in 1 hops
[I] AudioCopy.h : 353 - StreamCopy::copy 1024 bytes - in 1 hops
pschatzmann commented 2 years ago

I assume you tried both LeftIsEmpty and RightIsEmpty. I currently don't see where the issue can be:

The only idea is, that you could try another sketch with the mic: https://github.com/pschatzmann/arduino-audio-tools/tree/main/examples/examples-webserver/streams-i2s-webserver_wav

janczeresnia commented 2 years ago

yes I tried both possibilities LeftIsEmpty and RightIsEmpty.

pschatzmann commented 2 years ago

The only thing which looks strange to me is [I] I2SConfig.h : 103 - auto_clear:165 Can you try to add
config.auto_clear = false;

janczeresnia commented 2 years ago

Ok i tried to add i2s to i2s config.auto_clear = false; nothing has changed.

I also checked i2s to webserver, there is no sound on 16bit and it does not compile on 32bit.

compile error when it changes to 32bit:

/root/Arduino/szkice/ESP32/ESP32-I2S-to-Webserver/ESP32-I2S-to-Webserver.ino: In function 'void setup()':
ESP32-I2S-to-Webserver:41:42: error: no matching function for call to 'audio_tools::AudioWAVServer::begin(audio_tools::I2SStream&, audio_tools::I2SConfig&, audio_tools::ConverterFillLeftAndRight<int>*)'
   server.begin(i2sStream, config, &filler);
                                          ^
In file included from /root/Arduino/libraries/arduino-audio-tools/src/AudioHttp/AudioHttp.h:4,
                 from /root/Arduino/libraries/arduino-audio-tools/src/AudioTools.h:30,
                 from /root/Arduino/szkice/ESP32/ESP32-I2S-to-Webserver/ESP32-I2S-to-Webserver.ino:10:
/root/Arduino/libraries/arduino-audio-tools/src/AudioHttp/AudioServer.h:271:14: note: candidate: 'void audio_tools::AudioEncoderServer::begin(Stream&, int, int, int, audio_tools::BaseConverter<short int>*)'
         void begin(Stream &in, int sample_rate, int channels, int bits_per_sample=16, BaseConverter<int16_t> *converter=nullptr) {
              ^~~~~
/root/Arduino/libraries/arduino-audio-tools/src/AudioHttp/AudioServer.h:271:14: note:   no known conversion for argument 2 from 'audio_tools::I2SConfig' to 'int'
/root/Arduino/libraries/arduino-audio-tools/src/AudioHttp/AudioServer.h:289:14: note: candidate: 'void audio_tools::AudioEncoderServer::begin(Stream&, audio_tools::AudioBaseInfo, audio_tools::BaseConverter<short int>*)'
         void begin(Stream &in, AudioBaseInfo info, BaseConverter<int16_t> *converter=nullptr) {
              ^~~~~
/root/Arduino/libraries/arduino-audio-tools/src/AudioHttp/AudioServer.h:289:14: note:   no known conversion for argument 3 from 'audio_tools::ConverterFillLeftAndRight<int>*' to 'audio_tools::BaseConverter<short int>*'
/root/Arduino/libraries/arduino-audio-tools/src/AudioHttp/AudioServer.h:306:14: note: candidate: 'void audio_tools::AudioEncoderServer::begin(audio_tools::AudioServerDataCallback, int, int, int)'
         void begin(AudioServerDataCallback cb, int sample_rate, int channels, int bits_per_sample=16) {
              ^~~~~
/root/Arduino/libraries/arduino-audio-tools/src/AudioHttp/AudioServer.h:306:14: note:   no known conversion for argument 1 from 'audio_tools::I2SStream' to 'audio_tools::AudioServerDataCallback' {aka 'void (*)(Print*)'}
exit status 1
no matching function for call to 'audio_tools::AudioWAVServer::begin(audio_tools::I2SStream&, audio_tools::I2SConfig&, audio_tools::ConverterFillLeftAndRight<int>*)'

sketch i2s to webserver:

#include "AudioTools.h"

//AudioEncodedServer server(new WAVEncoder(),"ssid","password");  
AudioWAVServer server("ssid","password"); // the same a above

I2SStream i2sStream;    // Access I2S as stream
//ConverterFillLeftAndRight<int32_t> filler(LeftIsEmpty); // fill both channels - or change to RightIsEmpty
ConverterFillLeftAndRight<int32_t> filler(RightIsEmpty); // fill both channels - or change to RightIsEmpty

void setup(){
  Serial.begin(115200);
  Serial.println(F("\nESP32 I2S to Webserver\n"));
  //AudioLogger::instance().begin(Serial, AudioLogger::Info);
  AudioLogger::instance().begin(Serial, AudioLogger::Warning);
  //AudioLogger::instance().begin(Serial, AudioLogger::Debug);

  // start i2s input with default configuration
  Serial.println("starting I2S...");
  auto config = i2sStream.defaultConfig(RX_MODE);
  config.i2s_format = I2S_STD_FORMAT; // if quality is bad change to I2S_LSB_FORMAT https://github.com/pschatzmann/arduino-audio-tools/issues/23
  config.sample_rate = 22050;
  config.channels = 2;
  config.bits_per_sample = 32;
  config.pin_ws = 14;
  config.pin_bck = 15;
  config.pin_data = 13;
  config.pin_data_rx = 32;
  i2sStream.begin(config);
  Serial.println("I2S started");

  // start data sink
  server.begin(i2sStream, config, &filler);
}

// Arduino loop  
void loop() {
  // Handle new connections
  server.copy();  
}

I receive the stream with mpv:

mpv http://192.168.22.111
 (+) Audio --aid=1 (pcm_s16le 2ch 22050Hz)
AO: [pulse] 22050Hz stereo 2ch float
A: 00:00:06 / 00:00:08 (73%) Cache: 2.0s/198KB
pschatzmann commented 2 years ago

Yes you would need to use 32 bits w/o converter or 16bits with converter and you can open it in the browser

janczeresnia commented 2 years ago

I tried both possibilities LeftIsEmpty and RightIsEmpty on i2s to webserwer on 32bit. No sound at all.

mpv http://192.168.22.111
 (+) Audio --aid=1 (pcm_s32le 2ch 22050Hz)
AO: [pulse] 22050Hz stereo 2ch float
A: 00:00:06 / 00:00:07 (84%) Cache: 0.9s/175KB
pschatzmann commented 2 years ago

You mean LeftIsEmpty and RightIsEmpty on i2s to webserwer on 16bit ? Converter with 32 bits are not supported on the webserver and should give compile errors

If you open the 32bits wihtout converter in the Browser, do you hear the microphone?

janczeresnia commented 2 years ago

I tried with such a sketch

#include "AudioTools.h"

//AudioEncodedServer server(new WAVEncoder(),"ssid","password");  
AudioWAVServer server("ssid","pass"); // the same a above

I2SStream i2sStream;    // Access I2S as stream
ConverterFillLeftAndRight<int16_t> filler(LeftIsEmpty); // fill both channels - or change to RightIsEmpty
//ConverterFillLeftAndRight<int16_t> filler(RightIsEmpty); // fill both channels - or change to RightIsEmpty

void setup(){
  Serial.begin(115200);
  Serial.println(F("\nESP32 I2S to Webserver\n"));
  AudioLogger::instance().begin(Serial, AudioLogger::Info);
  //AudioLogger::instance().begin(Serial, AudioLogger::Warning);
  //AudioLogger::instance().begin(Serial, AudioLogger::Debug);

  // start i2s input with default configuration
  Serial.println("starting I2S...");
  auto config = i2sStream.defaultConfig(RX_MODE);
  config.i2s_format = I2S_STD_FORMAT; // if quality is bad change to I2S_LSB_FORMAT https://github.com/pschatzmann/arduino-audio-tools/issues/23
  config.sample_rate = 22050;
  config.channels = 2;
  config.bits_per_sample = 32;
  config.pin_ws = 14;
  config.pin_bck = 15;
  config.pin_data = 32;
  config.auto_clear = false;
  i2sStream.begin(config);
  Serial.println("I2S started");

  // start data sink
  server.begin(i2sStream, config, &filler);
}

// Arduino loop  
void loop() {
  // Handle new connections
  server.copy();  
}

compiles without problems. I will check in a moment without a converter

pschatzmann commented 2 years ago

The above sketch destroys the audio signal and the browser will notice that this is not valid audio - therfore silence! Just noticed another issue. You would remove config.pin_data_rx = 32; and use config.pin_data = 32;

janczeresnia commented 2 years ago

without a converter sketch:

#include "AudioTools.h"

//AudioEncodedServer server(new WAVEncoder(),"ssid","password");  
AudioWAVServer server("ssid","pass"); // the same a above

I2SStream i2sStream;    // Access I2S as stream
//ConverterFillLeftAndRight<int16_t> filler(LeftIsEmpty); // fill both channels - or change to RightIsEmpty
//ConverterFillLeftAndRight<int16_t> filler(RightIsEmpty); // fill both channels - or change to RightIsEmpty

void setup(){
  Serial.begin(115200);
  Serial.println(F("\nESP32 I2S to Webserver\n"));
  AudioLogger::instance().begin(Serial, AudioLogger::Info);
  //AudioLogger::instance().begin(Serial, AudioLogger::Warning);
  //AudioLogger::instance().begin(Serial, AudioLogger::Debug);

  // start i2s input with default configuration
  Serial.println("starting I2S...");
  auto config = i2sStream.defaultConfig(RX_MODE);
  config.i2s_format = I2S_STD_FORMAT; // if quality is bad change to I2S_LSB_FORMAT https://github.com/pschatzmann/arduino-audio-tools/issues/23
  config.sample_rate = 22050;
  config.channels = 2;
  config.bits_per_sample = 32;
  config.pin_ws = 14;
  config.pin_bck = 15;
  config.pin_data = 32;
  config.auto_clear = false;
  i2sStream.begin(config);
  Serial.println("I2S started");

  // start data sink
  //server.begin(i2sStream, config, &filler);
  server.begin(i2sStream, config);
}

// Arduino loop  
void loop() {
  // Handle new connections
  server.copy();  
}

log:

starting I2S...
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 22050
[I] I2SConfig.h : 99 - bits per sample: 32
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_STD_FORMAT
[I] I2SConfig.h : 103 - auto_clear:0
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 15
[I] I2SConfig.h : 116 - pin_ws: 14
[I] I2SConfig.h : 117 - pin_data: 32
I2S started
[I] CodecWAV.h : 436 - is_streamed! because length is 2147418112
.
IP address: 192.168.22.111
[I] AudioServer.h : 200 - New Client.
[I] AudioServer.h : 340 - sendReply - Returning encoded stream...
[I] CodecWAV.h : 436 - is_streamed! because length is 4294967295
[I] AudioCopy.h : 66 - buffer_size=1024
[I] CodecWAV.h : 480 - Writing Header
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops
[I] AudioCopy.h : 135 - StreamCopy::copy 1024 -> 1024 -> 1024 bytes - in 1 hops

mpv log:

mpv http://192.168.22.111
 (+) Audio --aid=1 (pcm_s32le 2ch 22050Hz)
AO: [pulse] 22050Hz stereo 2ch float
A: 00:00:06 / 00:00:06 (99%) Cache: 0.0s
Audio device underrun detected.
A: 00:00:13 / 00:00:13 (100%) Cache: 0.0s
Audio device underrun detected.
A: 00:00:15 / 00:00:15 (94%) Cache: 0.6s/117KB

no sound.

pschatzmann commented 2 years ago

It's getting late. I will try to reproduce this tomorrow...

janczeresnia commented 2 years ago

Ok, have a nice night. I also have a job tomorrow. I need to get some sleep. Regards

janczeresnia commented 2 years ago

I found a problem, I need to change the i2s mode to I2S_RIGHT_JUSTIFIED_MODE then it works with all samples rates and all bits per sample. The sound quality is excellent. :) (there are no clicks or noises)

the sketch on which I tested all samples rates and bits per sample:

/*
 * ESP32 I2S FullDuplex i2s to i2s
 */

#include <I2S.h>

// I2S DAC MAX98357 and INMP441 Microphone
#define DOUT_PIN 32   // DATA | SD_IN
#define DIN_PIN 13    // DATA | SD_OUT
#define BCLK_PIN 14   // BCK  | SCK
#define LRCLK_PIN 15  // WS   | FS

const long sampleRate = 44100; // work witch rate: 8000, 16000, 22050, 32000, 44100, 48000
const int bitsPerSample = 16;  // work witch 16, 24 and 32 bits
uint8_t *buffer;

void setup() {
  Serial.begin(115200);
  while (!Serial && (millis() < 1000)) delay(1000);
  Serial.println(F("\nESP32 I2S FullDuplex\n"));
  // int setAllPins(int sckPin, int fsPin, int sdPin, int outSdPin, int inSdPin)
  I2S.setAllPins(BCLK_PIN, LRCLK_PIN, DIN_PIN, DIN_PIN, DOUT_PIN);
  if(!I2S.setDuplex()) {
    while(true) {
      Serial.println("ERROR - could not set duplex");
      vTaskDelay(1000);
    }
  }
  // I2S_PHILIPS_MODE / I2S_RIGHT_JUSTIFIED_MODE / I2S_LEFT_JUSTIFIED_MODE
  if (!I2S.begin(I2S_RIGHT_JUSTIFIED_MODE, sampleRate, bitsPerSample)) {
    while(true) {
      Serial.println("Failed to initialize I2S!");
      vTaskDelay(1000);
    }
  }
  buffer = (uint8_t*) malloc(I2S.getBufferSize() * (bitsPerSample / 8));
  if(buffer == NULL) {
    while(true){
      Serial.println("Failed to allocate buffer!");
      vTaskDelay(1000);
    }
  }
  Serial.println("I2S Setup done");
}

void loop() {
  // primitive implementation sample-by-sample are blocking
  //I2S.write(I2S.read());

  // Buffer based implementation
  I2S.read(buffer, I2S.getBufferSize() * (bitsPerSample / 8));
  I2S.write(buffer, I2S.getBufferSize() * (bitsPerSample / 8));
}
janczeresnia commented 2 years ago

But when i changed the mode/format in your examples i2s to i2s to I2S_RIGHT_JUSTIFIED_FORMAT and still no sound.

Starting I2S to I2S one i2s port
starting I2S...
[I] I2SConfig.h : 95 - rx/tx mode: RX
[I] I2SConfig.h : 96 - port_no: 0
[I] I2SConfig.h : 97 - is_master: Master
[I] I2SConfig.h : 98 - sample rate: 44100
[I] I2SConfig.h : 99 - bits per sample: 16
[I] I2SConfig.h : 100 - number of channels: 2
[I] I2SConfig.h : 101 - i2s_format: I2S_RIGHT_JUSTIFIED_FORMAT
[I] I2SConfig.h : 103 - auto_clear:0
[I] I2SConfig.h : 110 - buffer_count:10
[I] I2SConfig.h : 111 - buffer_size:512
[I] I2SConfig.h : 115 - pin_bck: 15
[I] I2SConfig.h : 116 - pin_ws: 14
[I] I2SConfig.h : 117 - pin_data: 13
[I] I2SConfig.h : 119 - pin_data_rx: 32
I2S started...
[I] AudioCopy.h : 353 - StreamCopy::copy 1024 bytes - in 1 hops
[I] AudioCopy.h : 353 - StreamCopy::copy 1024 bytes - in 1 hops
pschatzmann commented 2 years ago

I started with my tests: I was checking with the Serial output and for me only I2S_STD_FORMAT gives a stable signal. With 32 bits the right channel is filled, with 16bits for some strange reasons the right channel contains the signal. In the next step I will connect my MAX98357

The ConverterFillLeftAndRight works perfectly... If I whistle I get Screenshot 2022-09-15 at 15 05 35

The Web-Server example also works like a charm. Please note that there is some lag of a couple of seconds!

  auto config = out.defaultConfig(RX_MODE);
  config.sample_rate = 22050;
  config.channels = 2;
  config.bits_per_sample = 16;
   config.pin_ws = 15;
   config.pin_bck = 14;
   config.pin_data = 32;

Ouput test of sine was passing as well: I used

  auto config = out.defaultConfig(RXTX_MODE);
  config.pin_bck = 14;
  config.pin_ws = 15;
  config.pin_data = 13;
  config.pin_data_rx = 32;

so that I dont need to switch pins.

janczeresnia commented 2 years ago

My setup is:

MAX98357 LRC <-> GPIO15 BCLK <-> GPIO14 DIN <-> GPIO13 GAIN <-> GND SD <-> NC

INMP441 WS <-> GPIO15 SCK <-> GPIO14 SD <-> GPIO32 L/R <-> GND

pschatzmann commented 2 years ago

Double check the wiring in your sketch you have

    config.pin_ws = 14;
    config.pin_bck = 15;
    config.pin_data = 32;

This does not match!

janczeresnia commented 2 years ago

You're right, I rushed and didn't notice the badly configured pins. I just changed and your examples are working. I mean, I checked i2s to i2s 32bit with the converter. After lunch, I will check other examples. My mistake :( In the i2s to i2s example, Can hear sound but there is some trembling crackling. I tested with 44100 / 32bit

pschatzmann commented 2 years ago

Just double checked the i2s-i2s and it's also working for me! Uff, testing with the AudioKit is really much easier... But I found a couple of small issues that should be corrected: e.g. the mode is not logged properly...

If you plan to use RXTX_MODE in the end I suggest that you use it in all examples in this mode, so you can keep your pin config definitions the same...

janczeresnia commented 2 years ago

I have to buy an AudioKit board. I builds digital walkie-talkies on lora and codec2 with hardware encryption on esp32 and by the way tests your library taking the opportunity to have a microcontroller with an external DAC and microphone. Sorry to bother you because of my own oversight. You've written a great library and I've learned a lot from using it. Regards.

pschatzmann commented 2 years ago

Cool, it would be great if you could show your projects here https://github.com/pschatzmann/arduino-audio-tools/discussions/categories/show-and-tell

The VS1053 might also be interesting for your purpose...

janczeresnia commented 2 years ago

I already have a working code I need to add menu support. And I am designing a PCB. yes of course I will put everything on git. I'm using your codec2 library fork in my project I thought about adding internet radio, BT speaker and BT microphone to my project. And the KISS modem via LoRe over USB serial and BT Serial.

happytm commented 1 year ago

Did you finish your project ? if so can you share the sketch using codec2 for everyone please? You do not need to share your hardware design.

Thanks.