0

I am writing a wav file to an SD card on a ESP32 and that requires that every time I append data to the the end of the file I modify the header to set the right size in some fields.

I cannot find how to replace a value inside a file, I tried to write the new values with the seek function but unless I'm missing something looks like this deletes everything after the new value added.

I do not want to create a new file and to delete the old one as I will storing potentially large wav files and looks like wasting resources.

Is there a way to overwrite one value inside a file. I'm using SDlib but I'm open to others too.

Here the code I use to create the file and to update it:

#include "WavFileWriter.h"

void WavFileWriter::createFile(char const* filename, WavFileHeader* wavFileHeader)
{
  byte headerBuffer[44];
  wavFileHeader->getHeaderData(headerBuffer);
  File file = SD.open(filename, FILE_WRITE);
  file.write(headerBuffer, 44);
  file.close();
}

void WavFileWriter::appendData(char const* filename, WavFileHeader* wavFileHeader, byte* data, int dataLength)
{
  File file = SD.open(filename, FILE_WRITE);
  file.write(data, dataLength);

  byte headerBuffer[44];
  wavFileHeader->setFileSize(file.size());
  wavFileHeader->getHeaderData(headerBuffer);

  file.seek(0);
  file.write(headerBuffer, 44);
  file.close();
}

After calling appendData I end up with a file with just the header size (with the right header for a file with data but the data is gone).

  • why do you need to store the sound data in wav format? – jsotola May 24 at 15:49
  • can you identify the position of the sector on the SD card where the header is stored, keep a copy of it in RAM, keep this copy updated and write it to SD from time to time? – imalipusram May 24 at 16:10
  • just store the raw data ... if you need a wav file then use something like Audacity to convert raw to wav – jsotola May 24 at 18:37
  • show your code. – Juraj May 25 at 4:33
  • added the code. I should have done from the beginning, my bad. – Ignacio Soler Garcia May 25 at 12:05
1

The FILE_WRITE in SD library is 'append' (for historical reasons)

#define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

so use

 File file = SD.open(filename, O_WRITE);
| improve this answer | |
  • Looks like the ESP32 uses a different library and the definitions are different: #define FILE_READ "r" #define FILE_WRITE "w" #define FILE_APPEND "a" – Ignacio Soler Garcia May 25 at 16:29
  • Should I use SPIFFS instead of SD? – Ignacio Soler Garcia May 25 at 17:03
0

SD.seek() is the API you're looking for. It allow you to position the read/write pointer within a file. In standard C++ the fseek() API is used.

| improve this answer | |
  • OP is using seek() – Juraj May 25 at 4:32
  • I added the code so you can see if this is the expected usage. – Ignacio Soler Garcia May 25 at 12:11
  • It looks like you're not seek'ing to the end of the file when you attempt to append data. Try: file.seek(file.size()) between the SD.open() and file.write() in the WavFileWriter::appendData() method. – Jeff Wahaus May 26 at 14:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.