earlephilhower / ESP8266Audio

Arduino library to play MOD, WAV, FLAC, MIDI, RTTTL, MP3, and AAC files on I2S DACs or with a software emulated delta-sigma DAC on the ESP8266 and ESP32
GNU General Public License v3.0
2.02k stars 431 forks source link

Getting MP3:ERROR_BUFLEN 0 playing from SPIFFS on ESP32 #381

Open CircuitSetup opened 3 years ago

CircuitSetup commented 3 years ago

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, I2SDIN);

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:ERRORBUFLEN 0 after each tone plays (it does play properly). Eventually I get the error: _[E][vfsapi.cpp:243] VFSFileImpl(): fopen(/spiffs/Dtmf-#.mp3) failed and every subsequent key press does not play.

Any ideas why this would be happening?

3KMedialab commented 3 years ago

Hi everybody.

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

CircuitSetup commented 3 years ago

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);

pablofr918 commented 3 years ago

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

venetanji commented 3 years ago

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)

fsender commented 3 years ago

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

CircuitSetup commented 2 years ago

sprintf

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

HeikkiHietala commented 2 years ago

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?

burpitt commented 2 years ago

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.

HeikkiHietala commented 2 years ago

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.

burpitt commented 2 years ago

@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.

HeikkiHietala commented 2 years ago

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

venetanji commented 2 years ago

@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);

HeikkiHietala commented 2 years ago

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

HeikkiHietala commented 2 years ago

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.