Hello,
can someone please provide working code? I tried for weeks recording from an I2S MEMS microphone and writing it to an SD card.
My code "works", but the output WAV is wayy to sped up, it sounds like chipmunk noises and is very quiet.
What do I do wrong? Can someone just give me their working code, outputting into a 16 bit linear PCM WAV file?
Thank you
Here are code snippets, that should give an overview over the issue, hopefully:
Code: Select all
void I2S_Init(i2s_mode_t MODE, i2s_bits_per_sample_t BPS) {
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),// | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN),
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,//I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = 0,
.dma_buf_count = 16,
.dma_buf_len = 60
};
if (MODE == I2S_MODE_RX || MODE == I2S_MODE_TX) {
//Serial.println("using I2S_MODE");
i2s_pin_config_t pin_config;
pin_config.bck_io_num = PIN_I2S_BCLK;
pin_config.ws_io_num = PIN_I2S_LRC;
if (MODE == I2S_MODE_RX) {
pin_config.data_out_num = I2S_PIN_NO_CHANGE;
pin_config.data_in_num = PIN_I2S_DIN;
} else if (MODE == I2S_MODE_TX) {
pin_config.data_out_num = PIN_I2S_DOUT;
pin_config.data_in_num = I2S_PIN_NO_CHANGE;
}
esp_err_t err;
err = i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
if (err != ESP_OK) {
ESP_LOGI(TAG, "Failed installing driver: %d\n", err);
while (true) ;
}
err = i2s_set_pin(I2S_NUM_0, &pin_config);
if (err != ESP_OK) {
ESP_LOGI(TAG, "Failed setting pin: %d\n", err);
while (true) ;
}
err = i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_MONO);
if (err != ESP_OK) {
ESP_LOGI(TAG, "Failed setting clk: %d\n", err);
while (true) ;
}
ESP_LOGI(TAG, "lel");
} else if (MODE == I2S_MODE_DAC_BUILT_IN || MODE == I2S_MODE_ADC_BUILT_IN) {
//Serial.println("using ADC_builtin");
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
// GPIO36, VP
i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_0);
}
}
Code: Select all
void CreateWavHeader(char* header, int waveDataSize) {
header[0] = 'R';
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
unsigned int fileSizeMinus8 = waveDataSize + 44 - 8;
header[4] = (char)(fileSizeMinus8 & 0xFF);
header[5] = (char)((fileSizeMinus8 >> 8) & 0xFF);
header[6] = (char)((fileSizeMinus8 >> 16) & 0xFF);
header[7] = (char)((fileSizeMinus8 >> 24) & 0xFF);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f';
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 0x10; // linear PCM
header[17] = 0x00;
header[18] = 0x00;
header[19] = 0x00;
header[20] = 0x01; // linear PCM
header[21] = 0x00;
header[22] = 0x01; // monoral
header[23] = 0x00;
header[24] = 0x44; // sampling rate 44100
header[25] = 0xAC;
header[26] = 0x00;
header[27] = 0x00;
header[28] = 0x88; // Byte/sec = 44100x2x1 = 88200
header[29] = 0x58;
header[30] = 0x01;
header[31] = 0x00;
header[32] = 0x02; // 16bit monoral
header[33] = 0x00;
header[34] = 0x10; // 16bit
header[35] = 0x00;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (char)(waveDataSize & 0xFF);
header[41] = (char)((waveDataSize >> 8) & 0xFF);
header[42] = (char)((waveDataSize >> 16) & 0xFF);
header[43] = (char)((waveDataSize >> 24) & 0xFF);
}
Code: Select all
CreateWavHeader(header, waveDataSize);
// Use POSIX and C standard library functions to work with files.
// First create a file.
ESP_LOGI(TAG, "Opening file");
FILE* f = fopen(filename, "w");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
fwrite(header, 1, headerSize, f);
I2S_Init(I2S_MODE, I2S_BITS_PER_SAMPLE_32BIT);
for (int j = 0; j < waveDataSize / numPartWavData; ++j) {
//i2s_read(I2S_NUM_0, communicationData, numCommunicationData, bytesRead, portMAX_DELAY);
size_t bytes_read = 0;
//while (bytes_read == 0) {
i2s_read(I2S_NUM_0, (void*) buf, buf_len, &bytes_read, portMAX_DELAY);
//example_disp_buf((uint32_t*) buf, 64);
//}
//ESP_LOGI(TAG, "bytes = %i", (int)bytes_read);
for (int i = 0; i < buf_len / 8; ++i) {
partWavData[2*i] = buf[8*i + 2];
partWavData[2*i + 1] = buf[8*i + 3];
}
fwrite(partWavData, 1, numPartWavData, f);
//fwrite(buf, 1, buf_len, f);
}
fclose(f);
ESP_LOGI(TAG, "File written");
Here is the audio file generated:
https://github.com/SinanAkkoyun/tmp/raw ... SOUND8.WAV
Please help me!