Hi! I wanted to ask if it is possible to do the following:
I'm using an esp32 s3 n16r8, with a SDIO interface for the microSD.
And I need to :
- Create a
.wavfile. - Write a placeholder header.
- Save the audio data.
- Close the file.
- Reopen it later.
- Calculate its size.
- Edit the header with the correct file size.
So far, I haven't been able to reopen the file for editing.
The limitation is that I am using the SD_MMC library.
Any help would be greatly appreciated!
My sketch is something like this:
#include "esp_sleep.h" // Sleep mode.
#include "ESP32Time.h" // RTC.
#include "WiFi.h" // RTC update.
#include "SD_MMC.h" // SD MMC mode.
#include "driver/i2s_std.h" // I2S STD driver.
#include "driver/gpio.h" // I2S STD driver?
#include "SdFat.h"
//
// SD MMC #defines.
#define MMC_D2 4
#define MMC_D3 5
#define MMC_CMD 6
#define MMC_CLK 7
#define MMC_D0 15
#define MMC_D1 16
// some code ......
wavGenerator(audioFileName.c_str(), true); // Creates wav file with temporary header.
duration = 2*60*1000; /*debugging*/
while (millis() - startTime < duration)
{
I2S_read();
SD_write();
if (cycleCount >= MAX_CICLE_COUNT)
{
cycleCount = 0;
Serial.printf("Start. - ");
Serial.printf("Ciclo : %d . - ", cycleCount);
Serial.printf("Tiempo ciclo : %d . \n", millis() - cycleTime);
cycleTime = millis();
}
cycleCount++;
}
wavGenerator(audioFileName.c_str(), false); // Saves proper wav header.
// more code...
The 2nd time wavGenerator is called, it should calculate the size of the file and update the header. take into account that the recording time is unknown before beggining the recording. The file could be 1, 2 up to 10 hours long (16 bit 44.1khz).
void wavGenerator(const char *filename, bool create) // Generates .wav files with proper header.
{
// If create == true -> writes a temporary header at the beginning of the file.
// If create == false -> updates the header with the correct data size.
struct WavHeader // Header for .wav files.
{
char ChunkID[4] = {'R', 'I', 'F', 'F'};
uint32_t ChunkSize;
char Format[4] = {'W', 'A', 'V', 'E'};
char Subchunk1ID[4] = {'f', 'm', 't', ' '};
uint32_t Subchunk1Size = 16; // PCM
uint16_t AudioFormat = 1; // PCM
uint16_t NumChannels = 1; // Mono
uint32_t SampleRate = SAMPLERATE;
uint32_t ByteRate = SAMPLERATE * 1 * 16 / 8;
uint16_t BlockAlign = 1 * 16 / 8;
uint16_t BitsPerSample = 16;
char Subchunk2ID[4] = {'d', 'a', 't', 'a'};
uint32_t Subchunk2Size;
} header;
if (!SD_MMC.begin("/sdcard", true, SDMMC_SPEED)) return;
File file = SD_MMC.open(filename, FILE_WRITE);
if (!file) return;
header.Subchunk2Size = create ? 0 : file.size() - sizeof(WavHeader);
header.ChunkSize = header.Subchunk2Size + 36;
file.seek(0);
file.write((uint8_t*)&header, sizeof(header));
file.flush();
file.close();
SD_MMC.end();
Serial.println(create ? "Header creado." : "Header actualizado.");
Serial.println(filename);
}
The problem is i dont know if file.seek(0) is properly used.ยก
If I use file_append it just appends the data to the end of the file.
file_write deletes all the data and saves just the header.