ESP8266Audio icon indicating copy to clipboard operation
ESP8266Audio copied to clipboard

Getting MP3:ERROR_BUFLEN 0 playing from SPIFFS on ESP32

Open CircuitSetup opened this issue 3 years ago • 14 comments

I needed to quickly play tones to emulate touch tone sounds on a keypad (the ESP32 cannot play 2 tones at the same time), so I loaded the DTMF sounds in SPIFFS, and play them through I2S. I'm using an external DAC IC for the I2S connection, and the pins are set properly. out->SetPinout(I2S_BCLK, I2S_LRCLK, I2S_DIN);

This is what the code looks like that does that:

    if(mp3->isRunning()) {
        if (!mp3->loop()) mp3->stop(); 
    }
    if (key) {
        if (key == '0') file = new AudioFileSourceSPIFFS("/Dtmf-0.mp3");
        if (key == '1') file = new AudioFileSourceSPIFFS("/Dtmf-1.mp3");
        if (key == '2') file = new AudioFileSourceSPIFFS("/Dtmf-2.mp3");
        if (key == '3') file = new AudioFileSourceSPIFFS("/Dtmf-3.mp3");
        if (key == '4') file = new AudioFileSourceSPIFFS("/Dtmf-4.mp3");
        if (key == '5') file = new AudioFileSourceSPIFFS("/Dtmf-5.mp3");
        if (key == '6') file = new AudioFileSourceSPIFFS("/Dtmf-6.mp3");
        if (key == '7') file = new AudioFileSourceSPIFFS("/Dtmf-7.mp3");
        if (key == '8') file = new AudioFileSourceSPIFFS("/Dtmf-8.mp3");
        if (key == '9') file = new AudioFileSourceSPIFFS("/Dtmf-9.mp3");

        out = new AudioOutputI2S();
        mp3 = new AudioGeneratorMP3();
        mp3->begin(file, out);  //Start playing the tone
    }

But I'm getting the error MP3:ERROR_BUFLEN 0 after each tone plays (it does play properly). Eventually I get the error: [E][vfs_api.cpp:243] VFSFileImpl(): fopen(/spiffs/Dtmf-#.mp3) failed and every subsequent key press does not play.

Any ideas why this would be happening?

CircuitSetup avatar Mar 23 '21 18:03 CircuitSetup

Hi everybody.

Same problem here. The only difference is that I load mp3 files from SD.

3KMedialab avatar Mar 26 '21 09:03 3KMedialab

I believe this has something to do with the DMA buffer. After I increased it, the second fopen error stopped. This is how I increased the buffer: AudioOutputI2S *out = new AudioOutputI2S(0, 0, 32, 0);

CircuitSetup avatar Mar 26 '21 14:03 CircuitSetup

Hi, I got the same problem, did you find any solution?

pablofr918 avatar Apr 21 '21 12:04 pablofr918

Ran into this as well. I figured you should reuse the same AudioFileSourceSPIFFS object, just call call file->open(filename). My case below:

  file = new AudioFileSourceSPIFFS("/tp00.mp3");
  mp3 = new AudioGeneratorMP3();
  out = new AudioOutputI2S();

then in loop under some condition:

    clockm++;
    sprintf(filen, "/tp%02d.mp3", clockm);
    file->open(filen);
    mp3->begin(file, out);

(filen is char filen[9] in my case)

venetanji avatar May 13 '21 09:05 venetanji

I got the same problem. But my problem is on an ESP8266 module. How could I do?

fsender avatar Jul 06 '21 18:07 fsender

sprintf

Are you using out() or stop() anywhere in the loop?

CircuitSetup avatar Oct 22 '21 16:10 CircuitSetup

i was wondering if you have a way to have the play routine in a function that could be called With various file names as parameters?

HeikkiHietala avatar Dec 16 '21 10:12 HeikkiHietala

Also bare in mind if you do not delete the buffer and keep stuffing things into it then it will eventually throw up. I believe @earlephilhower mentions this in some of his posts helping others about the fact the code is not designed for multiple mp3's but I don't want to put words in his mouth. Try using:

delete file;

Then you can tell it a new mp3 and carry on from there. Add whatever parameters / file names etc. Hope this is of help.

burpitt avatar Dec 16 '21 11:12 burpitt

Nope, I can't get it to run more than one file.

I am struggling to understand the audio object as a whole - it's not described anywhere in n00b detail.

I'd just like to have a way to create a sound object, play it until it runs out, then destroy it and make a new one. I am trying to build a talking clock that would have a playMySound(hour, minute) function, but editing this sample code somehow just begins to click, or reboots the ESP32.

Also, I found a way to edit the pins for this, but connecting the BLCK and LRC to assigned pins makes static noise while leading one of them to ground makes a scratchy MP3 sound.

I'll just need to work on this somehow. Thank you for your assistance.

HeikkiHietala avatar Dec 16 '21 11:12 HeikkiHietala

@HeikkiHietala take a look at the ATOMIC SPEAKER repo I recently put up. I think it might have the answer you are looking for if I understand correctly.

burpitt avatar Dec 16 '21 11:12 burpitt

Thanks muchly! I will have a look and be back to bother you with more silly questions later :)

HeikkiHietala avatar Dec 16 '21 11:12 HeikkiHietala

@HeikkiHietala, this worked for me:

https://gist.github.com/venetanji/975253eeef7c1a3beada97bf38223fc2

You'd have to upload the mp3s to the spiffs and name them with filenames with fixed amount of characters for this to work. Check the variable filen and the line sprintf(filen, "/tp%02d.mp3", clockh);

venetanji avatar Dec 16 '21 12:12 venetanji

That's another great starting point - thank you very much!

HeikkiHietala avatar Dec 16 '21 15:12 HeikkiHietala

Okay, I have it working to a point.

It plays the intro sound MP3 I made, then it gets the time, and then it tells the time, reading MP3 files for the hour and the minute. So far, so good.

The issue here is now that I can't get the thing to say it only when asked.

Ideally, I'd like a HC-SR04 ultrasound to trigger the MP3 routine when someone is less than 50 cm away from it. But any attempt to interfere with the flow of the sound makes it go mute. If I have the talk function entered after the ultrasound triggers, it comes back to the ultrasound so fast that it starts to stutter.

I have tried setting up a variable for the minute that has been said, and only going to the talk function when the new minute arises, but it goes mute.

It would be great to have everything halt until the file has been played, but apparently the sound playing is independent of the main loop which runs like a hare injected with speed.

Any pointers as to the control of the sound process would be greatly appreciated,

thanks,

-h.

HeikkiHietala avatar Feb 18 '22 13:02 HeikkiHietala