Using progmem instead of SPIFF - type conversion ?

Hi,

While I stumbled from one I2S lib to another:

XT_I2S doesn't work (sounds are distorted/chopped)
ESP8266audio doesn't make it too easy to play different sound on a press of a button, though it works pretty good with a single PROGMEM audio.

I came across the slim variant made by "honey the codewitch" but got another obstacle right in front of me, my LOLIN D32 got no PSRAM/SPIFF option so I need to get the data from PROGMEM.

Is there a way to convert the types so I can do something like:

file = unsigned char audiodata[13637] = {
  0x52, 0x49, 0x46, 0x46, 0x3d, 0x35, 0x00,

instead of

file = SPIFFS.open("/demo.wav","rb");

example code (taken from SFX: Making Noise with a New Audio and MIDI Library for IoT - CodeProject) :

#include <Arduino.h>
#include <SPIFFS.h>
#include <i2s_internal.hpp>
#include <htcw_button.hpp>
#include <sfx.hpp>

using namespace arduino;
using namespace sfx;

constexpr static const int8_t button_c_pin = 12;

using audio_t = i2s_internal<i2s_channels::left>;

button<button_c_pin,10,true> button_c;

audio_t sound;

performer<5> perform(sound);
File file;
file_stream file_stm(file);
int button_handles[3];
uint32_t second_ts;
int sound_state;
void setup() {
    Serial.begin(115200);
    SPIFFS.begin(false);
    button_c.initialize();
    button_c.callback([](bool pressed,void*state){
        if(pressed) {
            button_handles[2]=perform.wav(file_stm,.3);
        } else {
            perform.stop(button_handles[2]);
        }
    });
    if(!sound.initialize()) {
        Serial.println("Could not initialize sound");
        while(true);
    }
    file = SPIFFS.open("/demo.wav","rb");
    if(!file) {
        Serial.println("Could not open demo.wav file");
        while(true);
    }
    // reinitialize the file_stream with the now valid object
    file_stm.set(file);
    
}
void loop() {
    perform.update();
    button_c.update();
}

Why do you say that? It may not have PSRAM, put as an ESP32 it most certainly supports LittleFS (the follow-on to SPIFFS which had been deprecated).

Well yes, somehow maybe but:

load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4
E (132) psram: PSRAM ID read error: 0xffffffff

E (1147) esp_littlefs: ./components/esp_littlefs/src/littlefs/lfs.c:1347:error: Corrupted dir pair at {0x0, 0x1}

E (1148) esp_littlefs: mount failed,  (-84)
E (1150) esp_littlefs: Failed to initialize LittleFS
[  1036][E][LittleFS.cpp:95] begin(): Mounting LittleFS failed! Error: -1

looks like that path would create even more obstacles

board specs:

Operating Voltage 3.3V
Supported Battery Lipo 3.7V
Battery Connector PH-2 2.0mm
Digital I/O Pins 22
Analog Input Pins 6 (VP, VN, 32, 33, 34, 35)
Analog Output Pins 2 (25, 26)
LED_BUILTIN GPIO5
Clock Speed(Max) 240MHz
Flash 4M Bytes
Size 57*25.4mm
Weight 6.1g

Post your mystery code and exactly what board you have selected in the Arduino IDE.

And a link to exact board being used.

hmm that above IS the code, I'll try to port this to arduino IDE (the lib is set up for platformio) and try it there

Sorry, I was looking at the wrong post. What board is selected in the IDE? Link to to board on manufacturer's web page?

this one: D32 — WEMOS documentation

porting to arduino IDE is slightly more complicated than I thought... trying...

Please post a small, complete code without all the extraneous clutter (i2s_internal, htcw_button, sfx) and just demonstrates the problem with SPIFFS and / or LIttleFS.

that would be this:

#include <Arduino.h>
#include <SPIFFS.h>
#include <LittleFS.h>

File file;
void setup() {
    delay(1000); // for the serial monitor to not skip the first output

      if(!LittleFS.begin()){
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }
    Serial.begin(115200);
    SPIFFS.begin(false);
    
    file = SPIFFS.open("/demo.wav","rb");
    if(!file) {
        Serial.println("Could not open demo.wav file");
        while(true);
    }
    
}
void loop() {
}

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4
E (1011) esp_littlefs: ./components/esp_littlefs/src/littlefs/lfs.c:1347:error: Corrupted dir pair at {0x0, 0x1}

E (1012) esp_littlefs: mount failed, (-84)
E (1015) esp_littlefs: Failed to initialize LittleFS
[ 1037][E][LittleFS.cpp:95] begin(): Mounting LittleFS failed! Error: -1

Interesting will go over it when I get a chance.

PLEASE ... a manufacturer's link to the exact board AND board settings from IDE ... PLEASE

this board: D32 — WEMOS documentation

just have the platformio config :-/

[env:lolin_d32]
platform = espressif32
board = lolin_d32
framework = arduino
upload_speed = 921600
monitor_speed = 115200
monitor_filters = esp32_exception_decoder
lib_ldf_mode = deep
lib_deps =
codewitch-honey-crisis/htcw_button
codewitch-honey-crisis/htcw_i2s_audio

Can't think of why it wouldn't work. But I would try:

  1. Run test using Arduino IDE. Make sure you have the latest version of the EP32 Arduino Core installed.

  2. Remove the line: #include <SPIFFS.h>

BTW, what is "rb" mode in:
file = SPIFFS.open("/demo.wav","rb");
I don't see that mode in the documentation.

Does the file "demo.wav" already exist in the boards file system? If so, how did you get it there?

You may want to check out this tutorial: https://randomnerdtutorials.com/esp32-littlefs-arduino-ide/

Have you ever actually formatted for LittleFS? The signature for LittleFS.begin (with default values) is

bool begin(
  bool formatOnFail=false,
  const char * basePath="/littlefs",
  uint8_t maxOpenFiles=10,
  const char * partitionLabel="spiffs");

After getting rid of all references to SPIFFS, you can try

  LittleFS.begin(true);

to get past the Corrupted dir pair error, which sounds like the volume is not formatted. Of course, once you format, the volume will be empty. So getting any files there is a separate issue.

As for your original question: yes, you should be able to treat an array of bytes in memory as a stream, just as a bunch of bytes from a file. One potential complication is that the file_stream type in this case looks like a custom one that is part of SFX, so it may require some tinkering to allow input streams in general. If you have exactly one WAV to play, it might be easier to convert that to program text and bake it into the firmware, as opposed to dealing with any kind of filesystem.

good question, I did the formatting with platformio but there were no parameters, it is a one button thing :-/

For the progmem way, yes I have 3 sounds actually, with my current setting I use them with XT-DAC and from PROGMEM but I'd prefer it to be I2S since the sound is way better and the hardware doesn't need any additional denoising.

I don't know if the demo.wav exists, platformio looks like it is flashing soemthing but since I can't access the section I can not validate that.

rb is read (bytewise?) I don't know, code is from codewitch. It is also used here : Storing byte array in SPIFFS - #6 by hutje

The obvious next step is to try it using the Arduino IDE using code that's known to work. That will at least tell you if there's a hardware problem.

@kenb4 also mentioned that the partition must be formatted first.

I put that asside for now, couldn't get the SPIFF thing working but I found an I2S lib with progmem capabilities.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.