spawn451 / ESP32-CAM_Audio

Stream video and audio with ESP32-CAM
42 stars 5 forks source link

not really an issue, but some questions #7

Open philippedc opened 3 months ago

philippedc commented 3 months ago

Hi, first many thanks for sharing this project. it is the only one I succeed to make working., as I'm trying to build a kind of baby monitor and I get many difficulties to make inmp441 working. I'm trying to get a loader audio channel. (I use Arduino IDE version 1.8.16 with Expressif Sytems (ESP32) version 2.0.3)

There are not many information how to use i2s parameters, I have some questions, if I can get any answer to improve my knowledge:

philippedc commented 2 months ago

I've found a solution. However the sound quality is quite ugly. But in fact the web audio transfer must be under 8 bits, so.... It is just good enough for a baby monitor. The key is to convert the 32 bits (in fact 24 bits) microphone to 16 bits, and keep the MSB only to 8 bits.

` uint8_t buffer32[bufferSize]; uint8_t buffer16[bufferSize/4]; size_t bytesRead = 0;

while(true) { if(!Audioclient.connected()) { Serial.println("Audioclient disconnected"); break; } // Read audio data from I2S DMA i2s_read(I2S_PORT, &buffer32, bufferSize, &bytesRead, 1000);

// convert 32 bits (in fact 24 bits inmp441) to 16 bits
// then truncated to 8 bits value for Audiclient web format
// Offset + 0 is always E0 or 00, so discard it.
// Offset + 1 is the LSB of the sample, but is just fuzz, discard it.
// https://esp32.com/viewtopic.php?t=15185
int samplesRead = bytesRead /4;
for(int i=0; i<samplesRead; i++) {
  uint8_t mid = buffer32[i*4 +2];
  uint8_t msb = buffer32[i*4 +3];
  uint16_t raw = (msb << 8) + mid;
  if( raw > 255 ) raw = 255;
  memcpy(&buffer16[i], &raw, sizeof(uint8_t));  //buffer16[i] = raw; 
}  // end of for

// Send audio data
if(samplesRead > 0) Audioclient.write(buffer16, samplesRead);

} // end of while`

spawn451 commented 2 months ago

Hello @philippedc sorry been a while i didn't get here. I will check this out when I have some time.

philippedc commented 2 months ago

Hi @spawn451 in fact the result is much better like this: int samplesRead = bytesRead /4; for(int i=0; i<samplesRead; i++) { //uint8_t mid = buffer32[i4 +2]; //uint8_t msb = buffer32[i4 +3]; //uint16_t raw = (msb << 8) + mid; //if( raw > 255 ) raw = 255; uint8_t raw = buffer32[i*4 +2]; memcpy(&buffer16[i], &raw, sizeof(uint8_t)); //buffer16[i] = raw; } // end of for

// Send audio data if(samplesRead > 0) Audioclient.write(buffer16, samplesRead);

Now the inmp441 is very sensitive, even too much. It is OK for a baby monitor for instance. However as the sound is very load it quickly enter in saturation. I'm trying reading i2s documentation how to get data directly in 8 bits (there is Philips and PCM 8bits) but for the moment I cannot figure how to implement. The i2s library changes a lot for a version to another.....