Read audio WAV from SD card and convert it to Base64

Greetings all,

I'm trying to convert audio file to string so i can encode it to base64 on ESP32.
but I have this error, I see the code is logical, but I can't find the issue.

#include <base64.h>
#include <SPI.h>
#include <SD.h>

File dataFile;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  
   
  Serial.println("Initializing SD card...");
 
  while (!SD.begin(SS)) {
    Serial.println("initialization failed!");
  }
    Serial.println("Wiring is correct and a card is present.");

 
}

void loop() {



 dataFile = SD.open(F("/Sound.wav"));
 char* pBuffer;
  // if the file opened okay, write to it:
  if (dataFile) {
    unsigned int fileSize = dataFile.size(); // Get the file size.
    pBuffer = (char*)malloc(fileSize + 1); // Allocate memory for the file and a terminating null char.
    dataFile.read(pBuffer, fileSize); // Read the file into the buffer.
    pBuffer[fileSize] = '\0'; // Add the terminating null char.
    Serial.println(pBuffer); // Print the file to the serial monitor.
    dataFile.close(); // Close the file.
    Serial.println("Done");

  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening Sound.wav");
  }

free(pBuffer); 

}

the error at dataFile.read(pBuffer, fileSize); :

Compilation error: invalid conversion from 'char*' to 'uint8_t*' {aka 'unsigned char*'} [-fpermissive]

I know that's weird to put the code in loop function like that but i did't complete my work due to this issue

I used this code before to convert text file to base64 and worked. but i did't get where is the issue.

can someone help?

change your buffer pointer to be a uint8_t*

don't forget to free() the malloc-ed memory... (and are you sure you have enough memory to copy over the whole file?)

it does not make sense to try to print a binary file (wav) to the serial monitor. what do you expect from

    Serial.println(pBuffer); // Print the file to the serial monitor.

if you want to send it over to some software reading over the Serial port, use Serial.write()

thanks for your response.

the free(pBuffer) put i forgot to copy it.
i did't before for text file but even when i make it for text file i see the same error. i don't know what is the issue.
i want to send the base63 string to server using HTTP request.

i followed this post:

anyways, i change it to uint8_t still the issue is on

post the code

Please post the complete compiler error message associated with the new code.

It’s no longer a char*

Why do you print the file handle?

You don’t do any base64 processing…
How large is the file and how much memory does your Arduino have?

sure:

C:\Users\xx\Documents\Arduino\xxx\xxx.ino: In function 'void loop()':
C:\Users\xx\Documents\Arduino\xxx\xxx.ino:30:19: error: invalid conversion from 'char*' to 'uint8_t*' {aka 'unsigned char*'} [-fpermissive]
     dataFile.read(pBuffer, fileSize);         // Read the file into the buffer.
                   ^~~~~~~
In file included from C:\Users\xx\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.5\libraries\SD\src/SD.h:17,
                 from C:\Users\xx\Documents\Arduino\xxx\xxx.ino:3:
C:\Users\xx\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.5\libraries\FS\src/FS.h:60:26: note:   initializing argument 1 of 'size_t fs::File::read(uint8_t*, size_t)'
     size_t read(uint8_t* buf, size_t size);
                 ~~~~~~~~~^~~
Multiple libraries were found for "SD.h"
  Used: C:\Users\xx\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.5\libraries\SD
  Not used: C:\Users\xx\AppData\Local\Arduino15\libraries\SD
exit status 1

Compilation error: invalid conversion from 'char*' to 'uint8_t*' {aka 'unsigned char*'} [-fpermissive]

this code work perfectly wih uno rev2 but not in ESP32

No the code does not work on UNO, you just don't check the warnings about the type cast. The compiler's option are more stringent on the ESP32 and it's not happy that you assign pointers of different types.

the code would gain to be cleared up.. try something like this

#include <SPI.h>
#include <SD.h>
#include <base64.h>

void setup() {
  Serial.begin(115200);
  Serial.println("Initializing SD card...");
  while (!SD.begin(SS)) {
    Serial.write('.');
    delay(1000);
  }
  Serial.println(F("\nWiring is correct and a card is present."));
}

void loop() {
  File dataFile = SD.open(F("/Sound.wav"));
  if (dataFile) {
    unsigned int fileSize = dataFile.size();                        // Get the file size.
    uint8_t * pBuffer = (uint8_t *) malloc(fileSize);               // allocate memory for the file.
    if (pBuffer != nullptr) {                                       // if allocation worked
      dataFile.read(pBuffer, fileSize);                             // then read the whole file into SRAM.

      // >>>> this is where you do something with the buffer <<<<

      free(pBuffer);                                                // Free the memory that was used by the buffer.
    } else {
      Serial.println(F("\Error: not enough memory to load /Sound.wav"));
    }
    dataFile.close();                                               // Close the file.
  } else {
    Serial.println(F("\Error: could not find /Sound.wav"));
  }
}

you need of course to add the base64 conversion to handle the buffer. Mapping the whole file to memory might not be the best option if the sound file is large.

you don't need the +1 for a trailing null char as a wav sound file is binary, not something you can print out as ACII text... just does not make any sense to try to do so.

Excuse me, it works perfectly fine I test by myself on Uno Rev2 but in text file.

I tried your code and give me.
Serial.println(F("\Error: not enough memory to load /Sound.wav"));
can you help me in this, I'm new in this field and I would like to learn more from your experience

well your want to believe this... but the code in post 1 will raise warnings if you compile on a UNO and it has issues like you call free even if the memory was not allocated or printing binary data (of the sound file) as it were ASCII data does not make any sense (but will work on a text file indeed). Also you have assignment of data types that need fixing (as caught by the more stringent compiler options on the ESP)

the code in post 9 will fix this.

Also you don't base64 encode at all...

yes sure I didn't add base64 encoding as the error raised I choose to solve it before complete the next step

start working from code in post 9 then and you'll be on more solid ground.