Giter Club home page Giter Club logo

esp8266audio's Introduction

ESP8266Audio - supports ESP8266 & ESP32 & Raspberry Pi Pico RP2040 Gitter

Arduino library for parsing and decoding MOD, WAV, MP3, FLAC, MIDI, AAC, and RTTL files and playing them on an I2S DAC or even using a software-simulated delta-sigma DAC with dynamic 32x-128x oversampling.

ESP8266 is fully supported and most mature, but ESP32 is also mostly there with built-in DAC as well as external ones.

For real-time, autonomous speech synthesis, check out ESP8266SAM, a library which uses this one and a port of an ancient formant-based synthesis program to allow your ESP8266 to talk with low memory and no network required.

Disclaimer

All this code is released under the GPL, and all of it is to be used at your own risk. If you find any bugs, please let me know via the GitHub issue tracker or drop me an email.

  • The MOD and MP3 routines were taken from StellarPlayer and libMAD respectively.
  • The software I2S delta-sigma 32x oversampling DAC was my own creation, and sounds quite good if I do say so myself.
  • The AAC decode code is from the Helix project and licensed under RealNetwork's RSPL license. For commercial use you're still going to need the usual AAC licensing from Via Licensing. On the ESP32, AAC-SBR is supported (many webradio stations use this to reduce bandwidth even further). The ESP8266, however, does not support it due to a lack of onboard RAM.
  • MIDI decoding comes from a highly ported MIDITONES combined with a massively memory-optimized TinySoundFont, see the respective source files for more information.
  • Opus, OGG, and OpusFile are from Xiph.org with the Xiph license and patent described in src/{opusfile,libggg,libopus}/COPYING.. NOTE Opus decoding currently only works on the ESP32 due to the large memory requirements of opusfile. PRs to rewrite it to be less memory intensive would be much appreciated.

Neat Things People Have Done With ESP8266Audio

If you have a neat use for this library, I'd love to hear about it!

  • My personal use of the ESP8266Audio library is only to drive a 3D-printed, network-time-setting alarm clock for my kids which can play an MP3 instead of a bell to wake them up, called Psychoclock.
  • Harald Sattler has built a neat German word clock with MP3 alarm. Detailed discussion on the process and models are included.
  • Erich Heinemann has developed a Stomper (instrument for playing samples in real-time during a live stage performance) that you can find more info about here.
  • Dagnall53 has integrated this into a really neat MQTT based model train controller to add sounds to his set. More info is available here, including STL files for 3D printed components!
  • JohannesMTC has built a similar project especially for model trains: https://github.com/JohannesMTC/ESP32_MAS
  • A neat MQTT-driven ESP8266 light-and-sound device (alarm? toy? who can say!) was built by @CosmicMac, available at https://github.com/CosmicMac/ESParkle
  • A very interesting "linear clock" with a stepper motor, NTP time keeping, and configurable recorded chimes with schematics, 3D printer plans, and source code, is now available https://janderogee.com/projects/linear_clock/linear_clock.htm
  • Source and instructions for a gorgeous wooden MP3-playing clock, FM radio and a walkie-talkie using the ESP8266 and AVR microcontrollers is available https://github.com/zduka/mp3-player

Prerequisites

First, make sure you are running the 2.6.3/later or GIT head version of the Arduino libraries for ESP8266, or the latest ESP32 SDK from Espressif.

You can use GIT to pull right from GitHub: see this README for detailed instructions.

Installation

Install the library in your ~/Arduino/libraries

mkdir -p ~/Arduino/libraries
cd ~/Arduino/libraries
git clone https://github.com/earlephilhower/ESP8266Audio

When in the IDE please select the following options on the ESP8266:

Tools->lwIP Variant->v1.4 Open Source, or V2 Higher Bandwidth
Tools->CPU Frequency->160MHz

Usage

Create an AudioInputXXX source pointing to your input file, an AudioOutputXXX sink as either an I2S, I2S-sw-DAC, or as a "SerialWAV" which simply writes a WAV file to the Serial port which can be dumped to a file on your development system, and an AudioGeneratorXXX to actually take that input and decode it and send to the output.

After creation, you need to call the AudioGeneratorXXX::loop() routine from inside your own main loop() one or more times. This will automatically read as much of the file as needed and fill up the I2S buffers and immediately return. Since this is not interrupt driven, if you have large delay()s in your code, you may end up with hiccups in playback. Either break large delays into very small ones with calls to AudioGenerator::loop(), or reduce the sampling rate to require fewer samples per second.

Example

See the examples directory for some simple examples, but the following snippet can play an MP3 file over the simulated I2S DAC:

#include <Arduino.h>
#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"

AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioOutputI2SNoDAC *out;
void setup()
{
  Serial.begin(115200);
  delay(1000);
  SPIFFS.begin();
  file = new AudioFileSourceSPIFFS("/jamonit.mp3");
  out = new AudioOutputI2SNoDAC();
  mp3 = new AudioGeneratorMP3();
  mp3->begin(file, out);
}

void loop()
{
  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop(); 
  } else {
    Serial.printf("MP3 done\n");
    delay(1000);
  }
}

AudioFileSource classes

AudioFileSource: Base class which implements a very simple read-only "file" interface. Required because it seems everyone has invented their own filesystem on the Arduino with their own unique twist. Using this wrapper lets that be abstracted and makes the AudioGenerator simpler as it only calls these simple functions.

AudioFileSourceSPIFFS: Reads a file from the SPIFFS filesystem

AudioFileSourcePROGMEM: Reads a file from a PROGMEM array. Under UNIX you can use "xxd -i file.mp3 > file.h" to get the basic format, then add "const" and "PROGMEM" to the generated array and include it in your sketch. See the example .h files for a concrete example.

AudioFileSourceHTTPStream: Simple implementation of a streaming HTTP reader for ShoutCast-type MP3 streaming. Not yet resilient, and at 44.1khz 128bit stutters due to CPU limitations, but it works more or less.

AudioFileSourceBuffer - Double buffering, useful for HTTP streams

AudioFileSourceBuffer is an input source that simply adds an additional RAM buffer of the output of any other AudioFileSource. This is particularly useful for web streaming where you need to have 1-2 packets in memory to ensure hiccup-free playback.

Create your standard input file source, create the buffer with the original source as its input, and pass this buffer object to the generator.

...
AudioGeneratorMP3 *mp3;
AudioFileSourceHTTPStream *file;
AudioFileSourceBuffer *buff;
AudioOutputI2SNoDAC *out;
...
  // Create the HTTP stream normally
  file = new AudioFileSourceHTTPStream("http://your.url.here/mp3");
  // Create a buffer using that stream
  buff = new AudioFileSourceBuffer(file, 2048);
  out = new AudioOutputI2SNoDAC();
  mp3 = new AudioGeneratorMP3();
  // Pass in the *buffer*, not the *http stream* to enable buffering
  mp3->begin(buff, out);
...

AudioFileSourceID3 - ID3 stream parser filter with a user-specified callback

This class, which takes as input any other AudioFileSource and outputs an AudioFileSource suitable for any decoder, automatically parses out ID3 tags from MP3 files. You need to specify a callback function, which will be called as tags are decoded and allow you to update your UI state with this information. See the PlayMP3FromSPIFFS example for more information.

AudioGenerator classes

AudioGenerator: Base class for all file decoders. Takes a AudioFileSource and an AudioOutput object to get the data from and to write decoded samples to. Call its loop() function as often as you can to ensure the buffers are always kept full and your music won't skip.

AudioGeneratorWAV: Reads and plays Microsoft WAVE (.WAV) format files of 8 or 16 bits.

AudioGeneratorMOD: Reads and plays Amiga ModTracker files (.MOD). Use a 160MHz clock as this requires tons of SPIFFS reads (which are painfully slow) to get raw instrument sample data for every output sample. See https://modarchive.org for many free MOD files.

AudioGeneratorMP3: Reads and plays MP3 format files (.MP3) using a ported libMAD library. Use a 160MHz clock to ensure enough compute power to decode 128KBit 44.1KHz without hiccups. For complete porting history with the gory details, look at https://github.com/earlephilhower/libmad-8266

AudioGeneratorFLAC: Plays FLAC files via ported libflac-1.3.2. On the order of 30KB heap and minimal stack required as-is.

AudioGeneratorMIDI: Plays a MIDI file using a wavetable synthesizer and a SoundFont2 wavetable input. Theoretically up to 16 simultaneous notes available, but depending on the memory needed for the SF2 structures you may not be able to get that many before hitting OOM.

AudioGeneratorAAC: Requires about 30KB of heap and plays a mono or stereo AAC file using the Helix fixed-point AAC decoder.

AudioGeneratorRTTTL: Enjoy the pleasures of monophonic, 4-octave ringtones on your ESP8266. Very low memory and CPU requirements for simple tunes.

AudioOutput classes

AudioOutput: Base class for all output drivers. Takes a sample at a time and returns true/false if there is buffer space for it. If it returns false, it is the calling object's (AudioGenerator's) job to keep the data that didn't fit and try again later.

AudioOutputI2S: Interface for any I2S 16-bit DAC. Sends stereo or mono signals out at whatever frequency set. Tested with Adafruit's I2SDAC and a Beyond9032 DAC from eBay. Tested up to 44.1KHz. To use the internal DAC on ESP32, instantiate this class as AudioOutputI2S(0,1), see example PlayMODFromPROGMEMToDAC and code in AudioOutputI2S.cpp for details.

AudioOutputI2SNoDAC: Abuses the I2S interface to play music without a DAC. Turns it into a 32x (or higher) oversampling delta-sigma DAC. Use the schematic below to drive a speaker or headphone from the I2STx pin (i.e. Rx). Note that with this interface, depending on the transistor used, you may need to disconnect the Rx pin from the driver to perform serial uploads. Mono-only output, of course.

AudioOutputSPDIF (experimental): Another way to abuse the I2S peripheral to send out BMC encoded S/PDIF bitstream. To interface with S/PDIF receiver it needs optical or coaxial transceiver, for which some examples can be found at https://www.epanorama.net/documents/audio/spdif.html. It should work even with the simplest form with red LED and current limiting resistor, fed into TOSLINK cable. Minimum sample rate supported by is 32KHz. Due to BMC coding, actual symbol rate on the pin is 4x normal I2S data rate, which drains DMA buffers quickly. See more details inside AudioOutputSPDIF.cpp

AudioOutputSerialWAV: Writes a binary WAV format with headers to the Serial port. If you capture the serial output to a file you can play it back on your development system.

AudioOutputSPIFFSWAV: Writes a binary WAV format with headers to a SPIFFS filesystem. Ensure the FS is mounted and SPIFFS is started before calling. USe the SetFilename() call to pick the output file before starting.

AudioOutputNull: Just dumps samples to /dev/null. Used for speed testing as it doesn't artificially limit the AudioGenerator output speed since there are no buffers to fill/drain.

I2S DACs

I've used both the Adafruit I2S +3W amp DAC and a generic PCM5102 based DAC with success. The biggest problems I've seen from users involve pinouts from the ESP8266 for GPIO and hooking up all necessary pins on the DAC board. The essential pins are:

I2S pin Common label* ESP8266 pin
LRC D4 GPIO2
BCLK D8 GPIO15
DIN RX GPIO3

* The "common label" column applies to common NodeMCU and D1 Mini development boards. Unfortunately some manufacturers use different mappings so the labels listed here might not apply to your particular model.

Adafruit I2S DAC

This is quite simple and only needs the GND, VIN, LRC, BCLK< and DIN pins to be wired. Be sure to use +5V on the VIN to get the loudest sound. See the Adafruit example page for more info.

PCM5102 DAC

I've used several versions of PCM5102 DAC boards purchased from eBay. They've all had the same pinout, no matter the form factor. There are several input configuration pins beyond the I2S interface itself that need to be wired:

  • 3.3V from ESP8266 -> VCC, 33V, XMT
  • GND from ESP8266 -> GND, FLT, DMP, FMT, SCL
  • (Standard I2S interface) BCLK->BCK, I2SO->DIN, and LRCLK(WS)->LCK

Others

There are many other variants out there, and they should all work reasonably well with this code and the ESP8266. Please be certain you've read the datasheet and are applying proper input voltages, and be sure to tie off any unused inputs to GND or VCC as appropriate. Leaving an input pin floating on any integrated circuit can cause unstable operation as it may pick up noise from the environment (very low input capacitance) and cause havoc with internal IC settings.

Software I2S Delta-Sigma DAC (i.e. playing music with a single transistor and speaker)

For the best fidelity, and stereo to boot, spend the money on a real I2S DAC. Adafruit makes a great mono one with amplifier, and you can find stereo unamplified ones on eBay or elsewhere quite cheaply. However, thanks to the software delta-sigma DAC with 32x oversampling (up to 128x if the audio rate is low enough) you can still have pretty good sound!

Use the AudioOutputI2S*No*DAC object instead of the AudioOutputI2S in your code, and the following schematic to drive a 2-3W speaker using a single $0.05 NPN 2N3904 transistor and ~1K resistor:

                            2N3904 (NPN)
                            +---------+
                            |         |     +-|
                            | E  B  C |    / S|
                            +-|--|--|-+    | P|
                              |  |  +------+ E|
                              |  |         | A|
ESP8266-GND ------------------+  |  +------+ K| 
                                 |  |      | E|
ESP8266-I2SOUT (Rx) -----/\/\/\--+  |      \ R|
                                    |       +-|
USB 5V -----------------------------+

You may also want to add a 220uF cap from USB5V to GND just to help filter out any voltage droop during high volume playback.

If you don't have a 5V source available on your ESP model, you can use the 5V from your USB serial adapter, or even the 3V from the ESP8266 (but it'll be lower volume). Don't try and drive the speaker without the transistor, the ESP8266 pins can't give enough current to drive even a headphone well and you may end up damaging your device.

Connections are as a follows:

ESP8266-RX(I2S tx) -- Resistor (~1K ohm, not critical) -- 2N3904 Base
ESP8266-GND        -- 2N3904 Emitter
USB-5V             -- Speaker + Terminal
2N3904-Collector   -- Speaker - Terminal

NOTE: A prior version of this schematic had a direct connection from the ESP8266 to the base of the transistor. While this does provide the maximum amplitude, it also can draw more current from the 8266 than is safe, and can also cause the transistor to overheat.

As of the latest ESP8266Audio release, with the software delta-sigma DAC the LRCLK and BCLK pins can be used by an application. Simply use normal pinMode and digitalWrite or digitalRead as desired.

High pitched buzzing with the 1-T circuit

The 1-T amp can NOT drive any sort of amplified speaker. If there is a power or USB input to the speaker, or it has lights or Bluetooth or a battery, it can NOT be used with this circuit.

The 1T output is a binary signal at 0 or 5V, with nothing in between. When you connect to a 8ohm paper physical speaker directly, the speaker cone itself has inertia and acts as a low pass filter and averages the density of pulses in order to give a nice, analog output.

When you feed the 1T output to an amp you are alternatively grounding and overdriving the op-amp's input at a high frequency. That causes ringing and the opamp has a frequency response high enough to amplify the high frequency noise and you get that buzzing.

The same problem may happen with piezo speakers. They have a very high frequency response, normally, and have (almost) no inertia. So you hear the buzzing at high frequency.

You could attach the 1T output to a low pass and feed that into an amplifier. But at that point it is easier to just get an I2S DAC and avoid the whole thing (plus get stereo and true 16-bit output).

Debugging the 1-T amp circuit, compliments of @msmcmickey

If you've built the amp but are not getting any sound, @msmcmickey wrote up a very good debugging sequence to check:

  1. Please double-check the wiring. GPIO pins and board pins are not always the same and vary immensely between brands of ESP8266 carrier boards.
  2. Is the transistor connected properly? Check the datasheet for this package style and make sure you have the leads connected properly. This package has three leads, and the lead that is by itself in the middle of the one side is the collector, not the base as you might expect it to be.
  3. If connected properly, do you have ~5 volts between the collector and emitter?
  4. Was the transistor possibly damaged/overheated during soldering, or by connecting it improperly? Out-of-circuit diode check voltage drop test using a multimeter from base->emitter and base->collector should be between .5 and .7 volts. If it's shorted or open or conducting in both directions, then replace it and make sure it's connected properly.

SPDIF optical output

The proper way would be using optical TOSLINK transmitter (i.e. TOTXxxx). For testing, you can try with ~660nm red LED and resistor. Same as your basic Blink project with external LED, just that the LED will blink a bit faster.

                ____
ESP Pin -------|____|--------+ 
                             | 
                            --- 
                             V LED 
                            --- 
                             |
Ground  ---------------------+

For ESP8266 with red LED (~1.9Vf drop) you need minimum 150Ohm resistor (12mA max per pin), and output pin is fixed (GPIO3/RX0).On ESP32 it is configurable with AudioOutputSPDIF(gpio_num).

Using external SPI RAM to increase buffer

A class allows you to use a 23lc1024 SPI RAM from Microchip as input buffer. This chip connects to ESP8266 HSPI port and provides a large buffer to help avoid hiccus in playback of web streams.

The current version allows for using the standard hardware CS (GPIO15) or any other pin via software at slightly less performance. The following schematic shows one example:

Example of SPIRAM Schematic

Notes for using SD cards and ESP8266Audio on Wemos shields

I've been told the Wemos SD card shield uses GPIO15 as the SD chip select. This needs to be changed because GPIO15 == I2SBCLK, and is driven even if you're using the NoDAC option. Once you move the CS to another pin and update your program it should work fine.

Porting to other microcontrollers

There's no ESP8266-specific code in the AudioGenerator routines, so porting to other controllers should be relatively easy assuming they have the same endianness as the Xtensa core used. Drop me a line if you're doing this, I may be able to help point you in the right direction.

Thanks

Thanks to the authors of StellarPlayer and libMAD for releasing their code freely, and to the maintainers and contributors to the ESP8266 Arduino port.

Also, big thanks to @tueddy for getting the initial ESP32 porting into the tree!

-Earle F. Philhower, III

[email protected]

esp8266audio's People

Contributors

adamcbrz avatar chuckmash avatar d-a-v avatar dakkar avatar datanoisetv avatar don41382 avatar earlephilhower avatar ecoriag avatar federicobusero avatar ferbar avatar foreshadow avatar h3ndrik avatar hideakitai avatar ikostoski avatar judge2005 avatar kdmcmullan avatar martin-laclaustra avatar maxgerhardt avatar nils-trubkin avatar noer avatar oderik avatar pixtxa avatar rottifant avatar ryanmjacobs avatar simon-l avatar softhack007 avatar thepiguy avatar trailhead avatar troisiemetype avatar woutput avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp8266audio's Issues

esp32 no output when use_apll = 1

I have two esp32 development boards. One works fine with use_apll=1, the other one does not output anything with the same code. only when i set use_apll=0
both claim to be revision 1

Restart/loop audio

It's probably just me don't understanding, but how do you actually restart or loop an audio file?
My guess was to put the mp3->begin again after the file is finished but didn't work.

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SDAC.h"

// To run, set your ESP8266 build to 160MHz, and include a SPIFFS of 512KB or greater.
// Use the "Tools->ESP8266 Sketch Data Upload" menu to write the MP3 to SPIFFS
// Then upload the sketch normally.  

// pno_cs from https://ccrma.stanford.edu/~jos/pasp/Sound_Examples.html

AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioOutputI2SDAC *out;

void setup()
{
  WiFi.forceSleepBegin();
  Serial.begin(115200);
  delay(1000);
  SPIFFS.begin();
  file = new AudioFileSourceSPIFFS("/microwave.mp3");
  out = new AudioOutputI2SDAC();
  mp3 = new AudioGeneratorMP3();
  mp3->begin(file, out);
}

void loop()
{
  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    Serial.printf("MP3 done\n");
    delay(2000);
    mp3->begin(file, out);
  }
}

Fix examples to show proper memory hygiene

Hi,
I have a simple repetitive loop, playing a chuff sound. (for a loco sound module I am working on).
After 727 repeats it reliably fails, with the exception shown below. Its not dependant on the wav file, using a much longer "orchestra" wav, it also crashed at 727 loops.
Is the crash an error in the way I set up repeated wav files, or is it a memory leak elsewhere?- I'm afraid the exception decode means little to me.

To try and test a theory, I added curly brackets and added "delete file; file=Null;}" after the "wav->stop();"
(I have commented this out in the copy below).
Using this code seems to cure or hide the problem...Its run faultlessly more than 1704 repeats so far.. but I thought your code already closed the file as part of stop?

Many thanks
Dagnall

`Exception (29):
epc1=0x40207180 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont
sp: 3ffeffc0 end: 3fff01d0 offset: 01a0

stack>>>
3fff0160: 40104c70 13591d92 3ffeeefc 3ffef1a0
3fff0170: 3fffdad0 3ffe8900 3ffeeb58 401004d8
3fff0180: 3fffdad0 3ffef1a0 402091f0 40209100
3fff0190: 40201356 00000001 00000000 40206cd5
3fff01a0: 3fffdad0 3ffef0e0 3ffeeb58 40206dc5
3fff01b0: 3fffdad0 00000000 3ffef198 4020923c
3fff01c0: feefeffe feefeffe 3ffef1b0 4010070c
<<<stack<<<This decodesas:ecoding 9 results
0x40104c70: ets_timer_arm_new at ?? line ?
0x401004d8: malloc at C:\Users\Richard\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266\umm_malloc/umm_malloc.c line 1668
0x402091f0: loop_task at C:\Users\Richard\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266/core_esp8266_main.cpp line 57
0x40209100: String::operator=(String const&) at C:\Users\Richard\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266/WString.cpp line 220
0x40201356: delay at C:\Users\Richard\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266/core_esp8266_wiring.c line 54
0x40206cd5: BeginPlay(char const*) at C:\Users\Richard\AppData\Local\Temp\arduino_modified_sketch_25729/testWAV_sounds.ino line 14
0x40206dc5: loop at C:\Users\Richard\AppData\Local\Temp\arduino_modified_sketch_25729/testWAV_sounds.ino line 36
0x4020923c: esp_schedule at C:\Users\Richard\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266/core_esp8266_main.cpp line 57
0x4010070c: cont_norm at C:\Users\Richard\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266/cont.S line 109
`

Copy of main part of my program:

void BeginPlay(const char *wavfilename){
  file = new AudioFileSourceSPIFFS(wavfilename);
  wav->begin(file, out);
}
void setup()
{
  Serial.begin(115200);
  delay(1000);
  out = new AudioOutputI2SDAC();
  wav = new AudioGeneratorWAV();
  BeginPlay("/initiated.wav");
  x=0;
}
void loop()
{
  if (wav->isRunning()) {
    if (!wav->loop()) {wav->stop();
    }    //;delete file; file = NULL;}  // test to see if clearing file has any effect...
  } else {
    Serial.println(x);
    x=x+1;
    ;Serial.printf("WAV done\n");
    delay(1);
    BeginPlay("/chuff.wav");
      }
}

HTTP streaming : MP3 is fine, but AAC has "artefacts"

Thanks to @earlephilhower and @armSeb sorting out my troubles I can use this great library for streaming HTTP streams (ref. issue #9 ).

In issue #9 I already mentioned my remaining issue with playing AAC streams, but issue #9 was about "connection errors" and the AAC issue was more or less "lost".

The issue is:

  • MP3 streams play with good quality, often for many hours without loosing connection to the stream, with only occasional tiny hickups probably due to "network errors".
  • AAC streams also play with good quality, also often for many hours without loosing connection to the stream. But every 5-10 seconds the sound is disturbed by a disturbing "whistling hiss" lasting for 1-2 seconds. It sounds as if there's occasionally another sound "mixed" with the original stream. Imperfect combining stereo to mono, maybe?

I tested using the Morow Radio stream, that's available both as MP3 stream and AAC stream.
http://stream.morow.com:8080/morow_med.aacp
http://stream.morow.com:8000/morow.mp3
Both streams play fine in my browser.

Could it be that the AAC decoding software has a remaining issue?

I created the AAC sketch below adapting the StreamMp3FromHTTP example (both with a 4096 buffer).

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "AudioFileSourceHTTPStream.h"
#include "AudioGeneratorAAC.h"
#include "AudioOutputI2SNoDAC.h"
#include "AudioFileSourceBuffer.h"

// To run, set your ESP8266 build to 160MHz, update the SSID info, and upload.

/*
21-11-2017. AAC Plays "OK" on Wemos D1 clone with artefacts every 5-10 secs
*/


// Enter your WiFi setup here:
const char *SSID = "....";
const char *PASSWORD = "....";

// Randomly picked URL
const char *URL="http://stream.morow.com:8080/morow_med.aacp";                     // Morow Radio, 128kbps 44.1 kHz : works OK, artefacts every 5-10 sec

AudioGeneratorAAC *aac;
AudioFileSourceHTTPStream *file;
AudioFileSourceBuffer *buff;
AudioOutputI2SNoDAC *out;

void setup()
{
  Serial.begin(115200);
  delay(1000);
  Serial.println("Connecting to WiFi");

  WiFi.disconnect();
  WiFi.softAPdisconnect(true);
  WiFi.mode(WIFI_STA);
  
  WiFi.hostname("melody");
  
  byte zero[] = {0,0,0,0};
  WiFi.config(zero, zero, zero, zero);

  WiFi.begin(SSID, PASSWORD);

  // Try forever
  while (WiFi.status() != WL_CONNECTED) {
    Serial.println("...Connecting to WiFi");
    delay(1000);
  }

  file = new AudioFileSourceHTTPStream(URL);
  buff = new AudioFileSourceBuffer(file, 4096);     // you can increase default 2048 bufffersize to 4096 (seems better) or 8192 (seems much worse)
  out = new AudioOutputI2SNoDAC();
  aac = new AudioGeneratorAAC();
  aac->begin(buff, out);
}

void loop()
{
  if (aac->isRunning()) {
    if (!aac->loop()) aac->stop();
  } else {
    Serial.printf("AAC done\n");
    delay(1000);
  }
}






Slow/Choppy audio with a mp3 of bitrate of 32Kbps

Hi,

I’m using an ESP8266 - Wemos D1 mini with your awesome library, ESP8266Audio.

If I use the sample pno-cs.mp3 included in the example program“PlayMP3FromSPIFFS” it play perfectly fine in fact it sounds amazing for abusing the I2S. I’m using 160Mhz for the CPU and a transistor to drive a small speaker, as per the instructions.

If I use a the attached force.mp3 it is very choppy and sounds slow.
force.mp3 is from google translator, I don’t have any control over the format.
I thought the issue maybe bitrate/sample rate related, but the force.mp3 is significantly lower.
Pno-cs.mp3 Bitrate: 128kbps Samplerate48Khz
Force.mp3 Bitrate: 32 Kbps Samplerate24Khz
force.zip

I also have choppy playback using the example StreamMP3FromHTTP.ino but I suspect that may be network delay, as there doesn’t’ seem to be any buffer?

If I use the exampe StreamMP3FromHTTP to stream just a single mp3 file from a server(my ultimate goal), it seems to crash at the end of the file. I suspect it's not detecting the end of the file.

Is there an issue with the force.mp3 that causes the slow/choppy playback?
Is there anything I can do to the Arduino code/library to make it play correctly, as I can’t change the mp3 from google.
How can I stop the StreamMP3FromHTTP from crashing at the end of the file?

Thanks for your time.

Play 1Kbyte buffer PCM(wav) Audio

Hi Dear earlephilhower. thanks for this useful library.
I want to play 1Kbyte buffer PCM(wav) Audio without any header received by UDP, transferd by android mobile microphone.
my problem is just to play 1kByte audio for example "unsigned char buf[1023]" filled with PCM data with this library.
can you suggest any example code or help me to do that?

Many thanks
Moradi

Decoding error 0x0235 (bad main_data_begin pointer) at byte offset

This looks like an excellent library to stream internet-radio.

The StreamMP3FromHTTP sketch compiles (Arduino 1.8.1 and ESP8266 2.3.0), but with dozens of "red" warnings.

Upload to a Wemos D1 Mini (160Mhz)results in the errors below.

Any suggestions what to do?

�:��������a�����aV������qEc��S�aEc�i...Connecting to WiFi
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 0
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 418
Decoding error 0x0101 (lost synchronization) at byte offset 57774
Decoding error 0x0104 (reserved sample frequency value) at byte offset 58011
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 58097
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 58515
Decoding error 0x0101 (lost synchronization) at byte offset 108874
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 109088
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 109506
Decoding error 0x0101 (lost synchronization) at byte offset 161434
Decoding error 0x0101 (lost synchronization) at byte offset 161467
Decoding error 0x0104 (reserved sample frequency value) at byte offset 161647
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 161751
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 162169
Decoding error 0x0101 (lost synchronization) at byte offset 209614
Decoding error 0x0104 (reserved sample frequency value) at byte offset 209700
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 209816
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 210234
Decoding error 0x0101 (lost synchronization) at byte offset 298674
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 298841
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 299259
Decoding error 0x0101 (lost synchronization) at byte offset 336215
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 336875
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 337293
Decoding error 0x0101 (lost synchronization) at byte offset 380434
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 380761
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 381179
Decoding error 0x0101 (lost synchronization) at byte offset 422774
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 422975
Decoding error 0x0101 (lost synchronization) at byte offset 440918
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 441783
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 442201
Decoding error 0x0101 (lost synchronization) at byte offset 638854
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 639060

SPIRAM Addition (was Compilation Issue)

Hello,

Thanks for this library which I try to run on NodeMCU 1.0.

I intalled the library but when I try to compile an example, I get the following message :

In file included from /Users/armseb/Documents/Arduino/libraries/ESP8266Audio-master/src/AudioFileSourceFastROMFS.cpp:21:0: /Users/armseb/Documents/Arduino/libraries/ESP8266Audio-master/src/AudioFileSourceFastROMFS.h:25:30: fatal error: ESP8266FastROMFS.h: No such file or directory #include <ESP8266FastROMFS.h>

I can't find any information about this header file, where can I find it ?

Thank you.

Sebastian.

esp32: send silence on error?

The ESP32 starts stuttering once the i2s dma buffer gets empty. how should we handle this?

we could i2s_zero_dma_buffer() in order to gain some time (Pushes zero-byte samples into the TX DMA buffer, until it is full.) and to play silence until anything else is written. fortunately the i2s driver offers an event queue (currently not configured) which could report this. but where in the code would we poll for an buffer empty event? the output is not called regularly, only if there is data availabe.

another way would be to push silence down the pipeline. either via a new SetSilence() in AudioOutput? or do it sample by sample like i tried here:

h3ndrik@417e981

that works most of the time (not always) but will likely be unwanted behaviour for various other Output methods.

Web radio crashes in loop (entered a m3u url)

Hi,

i'm testing your webradio and accidentialy entered a m3u playlist url instead of a mp3 url.
Demo crashes on every startup.

Steps to reproduce:
Enter this URl in webradio:
http://dl-ondemand.radiobremen.de/bremeneins.m3u

Serial output dump:

...Connecting to WiFi
Connected
Go to http://192.168.178.28/ to control the web radio.
Resuming stream from EEPROM: http://dl-ondemand.radiobremen.de/bremeneins.m3uRunning for 7 seconds...Free mem=42128
Changing URL to: http://dl-ondemand.radiobremen.de/bremeneins.m3u

Soft WDT reset

ctx: cont
sp: 3fff0740 end: 3fff0a90 offset: 01b0

stack>>>
3fff08f0: 402144ae 00000030 00000013 ffffffff
3fff0900: 402144ab 3fff3c08 3fff3c48 402061ec
3fff0910: 3fff718a 3fff718b 000000e0 ffffffe0
3fff0920: 000000c0 3fffc6fc 00000001 3fff3bcc
3fff0930: 00000000 3fff3c48 3fff3c08 00000030
3fff0940: 01930467 00000000 3fff9f9c 3fff335c
3fff0950: 3ffef442 3ffef9a8 4021134c 00000030
3fff0960: 3fff1cf0 00000000 3fff1cd8 3ffef344
3fff0970: 3ffef344 00000031 3ffe8304 401004d8
3fff0980: 3fff718b 00000186 3fff19bc 40210c45
3fff0990: 3ffe84ec 00000000 00000000 4021a9e7
3fff09a0: 00000000 3fff19bc 3fff19a4 4021a9be
3fff09b0: 00000000 3fff711c 00001bd6 3fff3c08
3fff09c0: 3fff3c48 3fff3c08 3fff3c48 402064e5
3fff09d0: 40236c76 00000000 3fff19bc 3fff6fcc
3fff09e0: 00000000 00000000 3fff3bcc 402144ab
3fff09f0: 55555555 00000001 3fff3bcc 3fff6fcc
3fff0a00: 3fff3bdc 3fff70cc 3fff3bcc 4021460f
3fff0a10: c024bfd7 3fff335c 3ffef3f0 40211ae3
3fff0a20: 40216860 00000000 00000000 3fff0a40
3fff0a30: 0000a490 3ffef3f0 3ffef2f8 40211d09
3fff0a40: 24160000 3ffef41c 3ffef9a8 3ffefa68
3fff0a50: 3fffdad0 3ffef41c 7fffffff 40211942
3fff0a60: 3ffe9048 1cb2a8c0 feefeffe 3ffefa68
3fff0a70: 3fffdad0 00000000 3ffefa60 40217a54
3fff0a80: feefeffe feefeffe 3ffefa70 40100710
<<<stack<<<

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v00000000
~ld

EXP exception tracer:

Decoding 18 results
0x402144ae: AudioGeneratorMP3::DecodeNextFrame() at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioGeneratorMP3.cpp line 266
0x402144ab: AudioGeneratorMP3::DecodeNextFrame() at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioGeneratorMP3.cpp line 266
0x402061ec: mad_header_decode at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src\libmad/frame.c line 354
0x4021134c: StatusCallback(void*, int, char const*) at C:\Users\D83101.CAR\AppData\Local\Temp\arduino_modified_sketch_674620/WebRadio.ino line 226
0x401004d8: malloc at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266\umm_malloc/umm_malloc.c line 1668
0x40210c45: _malloc_r at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/heap.c line 15
0x4021a9e7: _strdup_r at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/string/../../../.././newlib/libc/string/strdup_r.c line 11
0x4021a9be: strdup at /Users/igrokhotkov/e/newlib-xtensa/xtensa-lx106-elf/newlib/libc/string/../../../.././newlib/libc/string/strdup.c line 11
0x402064e5: mad_frame_decode at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src\libmad/frame.c line 446 (discriminator 1)
0x40236c76: i2s_write_sample_nb at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_i2s.c line 192
0x402144ab: AudioGeneratorMP3::DecodeNextFrame() at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioGeneratorMP3.cpp line 266
0x4021460f: AudioGeneratorMP3::loop() at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioGeneratorMP3.cpp line 266
0x40211ae3: StartNewURL() at C:\Users\D8310
1.CAR\AppData\Local\Temp\arduino_modified_sketch_674620/WebRadio.ino line 296 (discriminator 2)
0x40216860: EspClass::getFreeHeap() at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/Esp.cpp line 409
0x40211d09: loop at C:\Users\D83101.CAR\AppData\Local\Temp\arduino_modified_sketch_674620/WebRadio.ino line 361
0x40211942: setup at C:\Users\D8310
1.CAR\AppData\Local\Temp\arduino_modified_sketch_674620/WebRadio.ino line 275
0x40217a54: loop_wrapper at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 57
0x40100710: cont_norm at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 109

Best regards
stacktrace

Dirk

Is Gpio02 (D4) used in I2SNoDAC ?

I am very happy using the no dac solution, I added a 1k resistor in the transistor base and can upload new sketches easily (with noise whilst uploading!).

However, I have an issue: I see that D4 /GPIO02 is oscillating fast with circa 150us period, (exactly as it does with the I2SDAC code).
Is this something left over from the I2SDAC code, or deliberate and essential?
If just "left over", can you stop using it please so I can use the pin ;-)

(still waiting eagerly for some mixing code..)

ESP32 / M5Stack - onboard DAC playback too fast

Hi,

Wondering if you might have some pointers about a problem i'm having playing WAV and MP3 on a ESP32, I think i have the audio working (or at least some sound) but it appears to be playing way to fast. Would you have an pointers as to what it might be or where i should start looking ?

Thanks

here is my code i've been testing with..

`
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include "SPIFFS.h"
#else
#include <ESP8266WiFi.h>
#endif

#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"
#include "AudioOutputI2S.h"
#include "AudioFileSourceSD.h"

#include "AudioGeneratorWAV.h"

#include <M5Stack.h>

AudioGeneratorWAV *mp3;
AudioFileSourceSD *file;
AudioOutputI2S *out;
AudioFileSourceID3 *id3;

void setup()
{
M5.begin();

M5.Speaker.setVolume(3);

Serial.begin(115200);
delay(1000);
//SPIFFS.begin();
Serial.printf("Sample MP3 playback begins...\n");
file = new AudioFileSourceSD("/slow.wav");

out = new AudioOutputI2S(0,true);

mp3 = new AudioGeneratorWAV();
mp3->begin(file,out);

}

void loop()
{
M5.update();
if (mp3->isRunning()) {
M5.update();

if (!mp3->loop()) {
mp3->stop();
}
} else {
Serial.printf("MP3 done\n");
delay(1000);
}
}
`

Undefined reference to `memcpy_P'

After updating to include d06dcf1 compilation on Arduino Esp8266 2.4.0-rc2 fails with:

Linking everything together...
...
C:\Users\xxx\AppData\Local\Temp\arduino_build_948531\libraries\ESP8266Audio\libmad\layer3.c.o: In function `III_imdct_l':

c:\Users\xxx\Documents\Arduino_ESP8266Audio\libraries\ESP8266Audio\src\libmad/layer3.c:2202: undefined reference to `memcpy_P'

C:\Users\xxx\AppData\Local\Temp\arduino_build_948531\libraries\ESP8266Audio\libmad\layer3.c.o: In function `III_imdct_s':

c:\Users\xxx\Documents\Arduino_ESP8266Audio\libraries\ESP8266Audio\src\libmad/layer3.c:2219: undefined reference to `memcpy_P'

collect2.exe: error: ld returned 1 exit status

Seems related to esp8266/Arduino#3726

NodeMCU - PlayMP3FromSPIFFS.ino - undefined reference to `memcpy_P'

I get following error when I tried to install on NodeMCU.
Sketch that I used: PlayMP3FromSPIFFS.ino from examples
Error:
Arduino: 1.8.4 (Linux), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, 921600, 4M (3M SPIFFS)"

Archiving built core (caching) in: /tmp/arduino_cache_653286/core/core_esp8266com_esp8266_nodemcuv2_CpuFrequency_80,UploadSpeed_921600,FlashSize_4M3M_969f2f37cb57bce10f8f8743aaef779a.a
libraries/ESP8266Audio-master/libmad/layer3.c.o: In function III_imdct_l': Multiple libraries were found for "SD.h" Used: /home/vksalian/Software-Downloaded/Arduino/arduino-1.8.4/hardware/esp8266com/esp8266/libraries/SD Not used: /home/vksalian/Software-Downloaded/Arduino/arduino-1.8.4/libraries/SD /home/vksalian/Software-Downloaded/Arduino/arduino-1.8.4/libraries/ESP8266Audio-master/src/libmad/layer3.c:2202: undefined reference to memcpy_P'
libraries/ESP8266Audio-master/libmad/layer3.c.o: In function III_imdct_s': /home/vksalian/Software-Downloaded/Arduino/arduino-1.8.4/libraries/ESP8266Audio-master/src/libmad/layer3.c:2219: undefined reference to memcpy_P'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Use of printf_P ?

Hi, and thanks for your ESP8266 audio library... However, I have an issue that is certainly down to my system, but I was hoping you could shed some light on it:
I am getting an error regarding "printf_P"

Arduino: 1.8.5 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, 115200, 4M (3M SPIFFS)"

C:\Users\Richard\Documents\Arduino\libraries\ESP8266Audio-master\src\AudioFileSourceBuffer.cpp: In constructor 'AudioFileSourceBuffer::AudioFileSourceBuffer(AudioFileSource*, int)':

C:\Users\Richard\Documents\Arduino\libraries\ESP8266Audio-master\src\AudioFileSourceBuffer.cpp:30:23: error: 'class HardwareSerial' has no member named 'printf_P'

if (!buffer) Serial.printf_P(PSTR("Unable to allocate AudioFileSourceBuffer::buffer[]\n"));

                   ^

I have looked and note you use this function a lot in the code, so some simple deletes did not allow me to make the examples work...

Presumably there is a Library that you are using that defines "Serial.printf_P" ... do you know which one it is?

I have just deleted my whole esp8266 library sets and clean re-installed arduino 1.8.5 hoping it was a recent library addition ... I can see others have the code working so I assume I have not (re?) installed something crucial! Is it something defined in your fork of the esp8266 code?

Many thanks
Dagnall

Question : Replay the same MP3 again ??

@earlephilhower thank you so much for your excellent library.

I have a question regarding replaying the same MP3 file from SPIFFS.
Once the mp3 is played and then mp3->stop() will get called.

Now again I tried using " mp3->begin(id3, out);", the mp3 is not getting played again.
Is this the correct way of replaying a mp3 with same settings (file, i2s..etc)

Please let me know. Thanks.

AudioFileSourceHTTPStream : Playing MP3 shutters

Board : ESP-12E (4MB Flash)
I2S DAC : PCM5102A
https://ae01.alicdn.com/kf/HTB14SqWlBHH8KJjy0Fbq6AqlpXac/Interface-I2S-PCM5102-DAC-Decoder-GY-PCM5102-I2S-Player-Module-For-Raspberry-Pi-pHAT-Format-Board.jpg_640x640.jpg

I am trying to play a mp3 file (15KB) served by a local webserver in the internal network.
But while playing the mp3, the playback shutters a lot. If I use the "AudioFileSourceBuffer", then I couldn't even hear the playback properly.
"mp3->begin(file, out);"

Using "file" directly in the "begin(), the shuttering is not that much, but still its there.
But If I try to play the same mp3 from SPIFFS (same code) the playback is very smooth.
I have even tried to pre-allocate buffer
`
void *preallocateCodec = NULL;
const int preallocateCodecSize = 29192; // MP3 codec max mem needed
preallocateCodec = malloc(preallocateCodecSize);

mp3 = new AudioGeneratorMP3(preallocateCodec, preallocateCodecSize);
`

and it never helped. So any solution on how we can fix this ?? Thank you.

`
#define FS_NO_GLOBALS
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266Spiram.h>
#include <FS.h>
#include <SD.h>
#include <ESP8266WiFi.h>
#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"
#include "AudioFileSourceHTTPStream.h"

char ssid[] = "wifiname";
char password[] = "passwd";

AudioGeneratorMP3 *mp3;
// AudioFileSourceSPIFFS *file;
AudioOutputI2S *out;
AudioFileSourceHTTPStream *file;

void setup()
{
Serial.begin(115200);

Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");

/**
Loading a mp3 file from SPIFFS works without any shutter
The playback is smooth
**/
// file = new AudioFileSourceSPIFFS("/test/hello.mp3");

// Mp3 is loaded from a internal webserer on network
file = new AudioFileSourceHTTPStream("http://192.168.0.120/test.mp3");

/**
Using buffer is causing more shutter in playback
**/
// buff = new AudioFileSourceBuffer(file, 2048);

out = new AudioOutputI2S();
out->SetOutputModeMono(true);
out->SetGain(0.5);
out->SetRate(22050);

mp3 = new AudioGeneratorMP3();

// Directly using "file" instead of "buff"
// This is causing less shutters in playback
mp3->begin(file, out);
}

void loop() {
if (mp3->isRunning()) {
if (!mp3->loop()) mp3->stop();
}
}
`

Problem with starting stream/playback in loop

Hello

I'm having some trouble starting the playback of a mp3 stream from within loop(). The code crashes every time the stream is started in this way.

Starting the same stream within setup() works flawlessly.

I attached a script showing the problem. The variable "startInLoop" switches between setup (0) and loop (1)

What am I doing wrong? Any help would be greatly appriciated.

kind regards

Erik

StreamSetupLoop.zip

No playback on NoDAC on esp-12-e

Trying to run the NoDac example in the readme fails on the esp-12-e if you are flicking the onboard led.

This onboard LED seems to use GPIO pin 2.

According to the board docs : http://www.kloppenborg.net/images/blog/esp8266/esp8266-esp12e-specs.pdf pin 2 also handles : GPIO2; UART1_TXD, however I believe it also is used for i2s, hence the potential issue.

Can the led be driven from another pin?

Is this a board limitation?

Can the i2s be driven on different pins to avoid this issue?

Incorrect parameter check in AudioOutputI2SNoDAC::SetOversampling

In AudioOutputI2SNoDAC::SetOversampling, the oversampling value is parameter checked against 256:

if (os > 256) return false; // Don't be silly now!

The text on the repository's readme states:

software delta-sigma DAC with 32x oversampling (up to 128x if the audio rate is low enough)

The implementation of AudioOutputI2SNoDAC::ConsumeSample passes a dsBuff of 4 32- bit values, for a total of 128 bits, to AudioOutputI2SNoDAC::DeltaSigma which determines the number of 32-bit values to output by dividing the oversampling value by 32:

int oversample32 = oversample / 32;

If the oversampling is set higher than 128, it appears AudioOutputI2SNoDAC::DeltaSigma will write more than 4 32-bit values, overflowing dsBuff.

Apologies if my analysis is incorrect, as I'm not yet set-up to run the code.

Attempting to use the library results in an error.

In file included from C:\Users\user\Documents\Arduino\libraries\ESP8266Audio\src\libflac\private/bitreader.h:38:0,

             from C:\Users\user\Documents\Arduino\libraries\ESP8266Audio\src\libflac\bitreader.c:40:

C:\Users\user\Documents\Arduino\libraries\ESP8266Audio\src\libflac\private/cpu.h:39:20: fatal error: config.h: No such file or directory

#include <config.h>

                ^

compilation terminated.

decoding error

I have this error in decoding mp3.

STATUS(mp3) '257' = 'Decoding error 'lost synchronization' at byte offset 6050'

what is the problem. should i change the mp3 file properties?

ESP32 Support Update/Fixes

Tracking bug for ESP32 issues brought up by @tueddy, @reaper7, others, and myself.

I2S non-blocking
The I2S functions now hard-block, meaning that once you start writing samples it will stick in side the mp3::loop and never return to your main app until the mp3 ends or an error occurs. The i2s_write_bytes seems to always block, even when the timeoput is set to 0.

Workaround is to make a worker thread who only pushes samples passed in to it. The thread will set a flag the main arduino code can look at (bool willBlock) and either say "sorry, out of space" or put the data into the worker thread's to-be-xmitted fifo. Ugly.

Enable onboard DAC
. Remove the global, hard coded i2s settings now #if ESP32'd.
. Add a constructor, #ifdef ESP32'd, I2SDAC::I2SDAC(bclk,lrclk,dout) => Set these as the I2S Pins
. Modify I2SDAC()::I2SDAC() to default to something sane on the ESP32 (existing settings?)
. Add a constructor, #ifdef ESP32, I2SDAC::I2SDAC(INTERNAL_DAC_[0|1] ), which routes the I2S data to internal 8-bit DAC
.Modify I2SNoDac::I2SNODAC() to use sane defaulrs on ESP32
. Add a constructor, #ifdef ESP32'd, I2SNODAC::I2SNODAC(bclk,lrclk,dout) => Set these as the I2S Pins

Problem with I2S Delta-Sigma DAC

Hillo Earle,
Thank you for your great job.

To play a MP3 file from PROGMEM, I'm using a ESP32 board connected to an external DAC on pins 26(BCK), 25( LCK) and 22 (DIN).
It works very fine and very good quality.

The problem is when I tried the I2S Delta-Sigma DAC. Nothing sound is played.
About hardware: the external DAC is removed, and I follow your schematic to drive a speaker (Base is connected to pin 25 in ESP32).

On Arduino IDE the following code compile without errors:

#include <Arduino.h>
#include "AudioFileSourcePROGMEM.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"
#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
#endif

// enigma.mod sample from the mod archive: https://modarchive.org/index.php?request=view_by_moduleid&query=42146
#include "fileMP3.h"

AudioGeneratorMP3 *mp3;
AudioFileSourcePROGMEM *file;
AudioOutputI2SNoDAC *out;

void setup()
{
WiFi.mode(WIFI_OFF); //WiFi.forceSleepBegin();
Serial.begin(115200);
delay(1000);
file = new AudioFileSourcePROGMEM(fileMP3_mp3, sizeof(fileMP3_mp3) );
out = new AudioOutputI2SNoDAC();
mp3 = new AudioGeneratorMP3();
mp3->begin(file, out);
}

void loop()
{
if (mp3->isRunning()) {
if (!mp3->loop()) mp3->stop();
} else {
Serial.printf("MP3 done\n");
delay(1000);
}

the code is the same than used with DAC, only the AudioOutputI2SNoDAC object is used instead of the AudioOutputI2SDAC.

What am I doing wrong?
Could you help me?

Using pushbutton for play mp3

Is it possibile to play a mp3 from a remote server by using different pushbutton? Each of them will play different mp3, and if while playing another pushbutton is pressed, stop the current mp3 and start the other.

PlayMP3FromSPIFFS crashes

Hi,
the example PlayMP3FromSPIFFS crashes when it calls the function:

out = new AudioOutputI2SNoDAC();

I'm using a Wemos D1 Mini, latest ESP8266Audio library, ESP8266 2.4.0
This is the stack:

Exception (0):
epc1=0x4000e25d epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
ctx: cont
sp: 3fff0360 end: 3fff05a0 offset: 01a0

stack>>>
3fff0500: 00000007 00000007 00000001 4022da15
3fff0510: 00000000 3ffeef28 3fff1a0c 4020d34a
3fff0520: 00000000 00000000 3fff1a0c 402105c4
3fff0530: 00000000 3ffeef28 3fff1a0c 4020d498
3fff0540: 00000000 3ffeef28 3ffef4ac 4020c3cd
3fff0550: 3ffe8cc0 00000000 000003e8 feefeffe
3fff0560: 3fff18ec 3fff192c 3fff1864 3fff18bc
3fff0570: feefeffe feefeffe feefeffe 3ffef56c
3fff0580: 3fffdad0 00000000 3ffef564 4020f278
3fff0590: feefeffe feefeffe 3ffef580 40100710
<<<stack<<<
ets Jan 8 2013,rst cause:2, boot mode:(1,6)
ets Jan 8 2013,rst cause:4, boot mode:(1,6)
wdt reset

What I wrong?

[EDIT] By changing AudioOutputI2SNoDAC() with AudioOutputI2S() the sketch works

WAV format

Hello.

In example "PlayWAVFromPROGMEM" you have file viola.h. How convert wav file to this format?

WebRadio demo: crash with AudioOutputI2SNoDAC & change the volume

Hi,

i'm testing webradio with AudioOutputI2SNoDAC as output. i can play a mp3 stream, but when is change the volume the esp crashes with this staktrace:
(so far as i can see it's this line:
out->SetGain
)

Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
Decoding 18 results
0x4021157f: HandleVolume(WiFiClient*, char*) at C:\Users\D83101.CAR\AppData\Local\Temp\arduino_modified_sketch_145799/WebRadio.ino line 321
0x40211578: HandleVolume(WiFiClient*, char*) at C:\Users\D8310
1.CAR\AppData\Local\Temp\arduino_modified_sketch_145799/WebRadio.ino line 321
0x40211c05: loop at C:\Users\D8310~1.CAR\AppData\Local\Temp\arduino_modified_sketch_145799/WebRadio.ino line 384
0x40101db2: trc_NeedRTS at ?? line ?
0x401021f2: wDev_ProcessFiq at ?? line ?
0x40101f8c: wDev_ProcessFiq at ?? line ?
0x401021f2: wDev_ProcessFiq at ?? line ?
0x401068c4: millis at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_wiring.c line 68
0x402179bb: loop_wrapper at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 57
0x402179bb: loop_wrapper at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 57
0x40212c90: WiFiClient::WiFiClient() at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\libraries\ESP8266WiFi\src/WiFiClient.cpp line 92
0x40213328: WiFiServer::available(unsigned char*) at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\libraries\ESP8266WiFi\src/WiFiServer.cpp line 106
0x40211b7a: loop at C:\Users\D8310
1.CAR\AppData\Local\Temp\arduino_modified_sketch_145799/WebRadio.ino line 373
0x402179b8: loop_wrapper at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 57
0x40100710: cont_norm at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 109

Best regards
Dirk

Software NoDac Crashes

I am trying the No DAC implementation, exactly as per the example : https://github.com/earlephilhower/ESP8266Audio#software-i2s-delta-sigma-dac-ie-playing-music-with-a-single-transistor-and-speaker

It crashes with the following error:

Exception (0):
epc1=0x4000e25d epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont
sp: 3fff0250 end: 3fff0460 offset: 01a0

stack>>>
3fff03f0: 00000007 00000007 00000001 4022d08d
3fff0400: 3ffeedfc 00000000 3fff14ac 4020cb42
3fff0410: 00000000 00000000 3fff14ac 4020fc8c
3fff0420: 3ffeedfc 00000000 3fff14ac 4020cc90
3fff0430: feefeffe 00000000 3fff14ac 4020c1c6
3fff0440: 3fffdad0 00000000 3ffef430 4020eab0
3fff0450: feefeffe feefeffe 3ffef440 40100710
<<<stack<<<

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v4ceabea9
~ld

ets Jan 8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v4ceabea9
~ld
rl�l⸮⸮|�⸮l⸮|� ⸮ l⸮ b|⸮⸮�⸮�⸮r⸮b⸮ b⸮⸮nn⸮lnn⸮⸮⸮ b�p⸮⸮lrlrlp⸮n⸮�� ⸮ l ⸮⸮ b n⸮|�l⸮ ⸮b⸮⸮nn⸮�l⸮⸮l�⸮��nn l���nr⸮⸮⸮n b ⸮�l�r⸮⸮n b ⸮�l⸮⸮⸮�b⸮��l`�⸮⸮n⸮�
Exception (0):
epc1=0x4000e25d epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont
sp: 3fff0250 end: 3fff0460 offset: 01a0

stack>>>
3fff03f0: 00000007 00000007 00000001 4022d08d
3fff0400: 3ffeedfc 00000000 3fff14ac 4020cb42
3fff0410: 00000000 00000000 3fff14ac 4020fc8c
3fff0420: 3ffeedfc 00000000 3fff14ac 4020cc90
3fff0430: feefeffe 00000000 3fff14ac 4020c1c6
3fff0440: 3fffdad0 00000000 3ffef430 4020eab0
3fff0450: feefeffe feefeffe 3ffef440 40100710
<<<stack<<<

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v4ceabea9
~ld

ets Jan 8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v4ceabea9
~ld

Once it crashes, the esp resets, and it fails again! Help!

Is it possible to change the playback speed/rate?

HI I thought I would add this as a separate "issue".
I would like to change the playback speed of my "chuff" wav.

I had assumed something like
out->SetRate((wav->sampleRate)*My_Rate_Modifiier); .. except of course that does not compile!..

Huge thanks
Dagnall

Click on completion of playing wav file

Earle, I think I have found a "bug" in your wav audio generator.
In my application I have a number of files that I play, and I discovered that some have a distinct "click" when they end.
To cut a long story short, the ones that "click" have metadata that describes what/who the sounds /artists are. The attached zip has two identical audio files, one has metadata, and clicks on completion, and the other does not, and is silent on completion.

Easy answer is to remove all the metadata, but I have found another post from 2014 that seems to suggest that at least one other wav program was not accounting for this metadata and producing similar results by effectively having the wrong data sample length, it also provided some code to answer this issue (at least for the other software.?) .
Hopefully this may help improve your library??, it looks to me that you have a slightly different way to get the sample length after "data" to the one in the "solution" example..

F7 F8.zip

This was the site with the possible solution?

https://gamedev.stackexchange.com/questions/71571/how-do-i-prevent-clicking-at-the-end-of-each-sound-play-in-openal
<

For those following these issues: this is a video of a test WITHOUT metadata.. https://youtu.be/Vd0HbV_MXVI
All the best
Dagnall

Audio playback using NoDAC causes WiFi / Udp server to 'stop'

Hi, this issue is reproducible and happens consistently. It is using the NoDAC output, as I have no DAC to test it out on that Output option.

My setup is:

ESP-12-E
v1.4 Open Source
160MHz

This project reproduces the problem, please check it out from git : https://bitbucket.org/renegadeandy/audio_bug/

git clone https://[email protected]/renegadeandy/audio_bug.git

This application connects to WiFi and launches a UDP Multicast server joining group 231.3.3.7 on port 1337.
Make sure to change your wifi ssid and password. It then plays w1.mp3 in the music folder (everything is included in the repo)

Audio playback begins.

Using Packet Sender A tool for sending packets , I send packets to the multicast group as per:

screen shot 2018-02-05 at 15 35 03

When a packet arrives, the DiscoverMe class sends a printf. Sending packets quickly after startup works ok:

Connecting to VM2111119 .. connected
DC::Starting up DiscoverMe listening for UDP datagrams...
DC::Now listening to Multicast Group IP: 231.3.3.7l From IPAddress: 192.168.0.53
Started playing audio
DC::Received 16 bytes from IP:192.168.0.41 on port:52888
DC::UDP packet contents:This is a test!!
DC::Received 16 bytes from IP:192.168.0.41 on port:52888
DC::UDP packet contents:This is a test!!
MP3 stop, len==0

I then leave the ESP8266 running the same sketch for around 7 - 11 minutes, after the audio is played and a couple of packets are received.

Then I try to send another Multicast packet, it is never received by my application - no DC::Received 16 bytes from IP:192.168.0.41 on port:52888 style message ever appears on my serial monitor. No errors, nothing, the main loop() continues on its merry way.

Reset the ESP8266, and the audio plays, some packets are received for the first couple of minutes, then , boom, packets are not received any longer.

Removing this audio library from the sketch, allows the UDP Server to run, stably, for any amount of time - drawing the conclusion that the problem is associated with this library. It may not be, but what else could it be?

Thoughts?

ESP32 stereo mp3 stream: every sample gets played twice

Using AudioGeneratorMP3 and AudioOutputI2S connected to a MAX98357A
stereo streams sound distorted and only playing at half speed. (mono is okay)

For example if you compare the two streams (first is stereo, second is mono):
"http://streaming.shoutcast.com/80sPlanet?lang=en-US"
"http://swr-swr1-bw.cast.addradio.de/swr/swr1/bw/mp3/64/stream.mp3"

Code:

  file = new AudioFileSourceICYStream(URL);
  file->RegisterMetadataCB(MDCallback, (void*)"ICY");
  buff = new AudioFileSourceBuffer(file, preallocateBuffer, preallocateBufferSize);
  buff->RegisterStatusCB(StatusCallback, (void*)"buffer");
  out = new AudioOutputI2S(I2S_NUM_0, false);
  out->SetPinout(12, 13, 23);
  mp3 = new AudioGeneratorMP3(preallocateCodec, preallocateCodecSize);
  mp3->RegisterStatusCB(StatusCallback, (void*)"mp3");
  mp3->begin(buff, out);

PlayMP3FromSPIFFS: Crash with specific MP3 - Problem with ID3 reader?

Hi,

the "PlayMP3FromSPIFFS" example works fine. I have replaced the sample mp3 with MySong.mp3.
After uploading i get this crash (decoded here):

Decoding 11 results
0x4020d0b4: AudioOutputI2SNoDAC::~AudioOutputI2SNoDAC() at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioOutputI2SNoDAC.cpp line 73
0x4020c7b2: AudioFileSourceID3::read(void*, unsigned int) at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioFileSourceID3.cpp line 46
0x4020e7bc: Print::printf(char const*, ...) at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/Print.cpp line 107
0x4020f2c4: SPIFFSFileImpl::flush() at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/spiffs_api.h line 315
0x4020c90a: AudioFileSourceID3::read(void*, unsigned int) at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioFileSourceID3.cpp line 46
0x4020cd13: AudioGeneratorMP3::ErrorToFlow() at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioGeneratorMP3.cpp line 266
0x4020cebf: AudioGeneratorMP3::GetOneSample(short*) at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src/AudioGeneratorMP3.cpp line 266
0x40201809: mad_frame_init at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\src\libmad/frame.c line 100
0x4020c200: setup at C:\Users\D.Carstensen\Documents\Arduino\libraries\ESP8266Audio\examples\PlayMP3FromSPIFFS/PlayMP3FromSPIFFS.ino line 49
0x4020ed48: preloop_update_frequency() at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/core_esp8266_main.cpp line 57
0x40100710: cont_norm at C:\Users\D.Carstensen\Documents\Arduino\hardware\esp8266com\esp8266\cores\esp8266/cont.S line 109

Then i stripped the ID3 tags from the specific file and uploaded again. The MP3 plays fine now.
So i assume there is a problem in ID3 tag reader? I see a special character "ß" in the title..

files to reproduce:
MySong.zip

Hope this helps to find the issue.

Thanks & best regards &

Merry Christmas
Dirk

Web interface

I'm trying to implement a web interface with my friend. But your library refuses to work correctly. We will be very happy if you can help me.

https://github.com/tretyakovsa/ESP_WIFI_RADIO

https://github.com/tretyakovsa/ESP_WIFI_RADIO/blob/master/ESP_WIFI_RADIO.ino#L43-L44

void loop() {
  //handleAudio();
}

https://github.com/tretyakovsa/ESP_WIFI_RADIO/blob/master/Audio.ino#L11-L16

  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  } else {
    Serial.printf("MP3 done\n");
    delay(1000);
}

2017 10 01-01 08 52

Enhancement request: support ESP32

Hi earlephilhower,

ESP-32 is the successor of ESP-8266, has two i2s ports and bluetooth audio support.
It should be possible to support this platform too.
I would make a pull request but this is a bit out of my capabilities..

I have installed the ESP-32 support in Arduino IDE and tried to modify the sources. Some hints for porting:

Replace include declarations with this:

#ifdef ESP32
#include <HTTPClient.h>
#else
#include <ESP8266HTTPClient.h>
#endif`

AudioFileSourceSPIFFS.cpp & AudioOutputSPIFFSWAV.cpp:
#ifdef ESP32 #include "SPIFFS.h" #endif

AudioOutputI2SNoDAC.cpp:

#ifdef ESP32
#include "driver/i2s.h"
#else
#include <i2s.h>
#endif`

I2S support requires some more modification,
here is a demo for playing wav via i2s on ESP-32:
http://www.iotsharing.com/2017/07/how-to-use-arduino-esp32-i2s-to-play-wav-music-from-sdcard.html

Replace the functions

i2s_begin(); i2s_end(); i2s_set_rate(); i2s_write_sample();

with
i2s_driver_install(); i2s_set_pin(); i2s_set_sample_rates(); i2s_driver_uninstall(); i2s_set_sample_rates(); i2s_write_bytes();

Porting MP3 decoder seems harder and i failed to get it to compile. But it should be possible. Here is a libmad port for ESP-32:
https://github.com/MrBuddyCasino/ESP32_MP3_Decoder/tree/master/components/mad

What do you think?
Best
Dirk

No playback with ESP32 from SPIFFS

I'm having issues getting this library to play MP3 files on my ESP32 (Adafruit Feather, and am connecting it to a Teensy Prop Shield amp, which accepts i2s). My understanding of the schematics implies that I should be using DAC1 (that is routed to the same pin that goes to the prop shield). However, it seems like I'm not even getting to the point where that should matter. It seems like the library is having a hard time reading the file at all. My code is:

#include <Arduino.h>
#include <WiFi.h>
#include <SPI.h>
#include <SPIFFS.h>
#include "AudioFileSourceSPIFFS.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"

AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *poweron;
AudioFileSourceSPIFFS *hum;
AudioFileSourceID3 *poweronid3;
AudioFileSourceID3 *humid3;
AudioOutputI2S *out;

void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
  (void)cbData;
  Serial.printf("ID3 callback for: %s = '", type);

  if (isUnicode) {
    string += 2;
  }
  
  while (*string) {
    char a = *(string++);
    if (isUnicode) {
      string++;
    }
    Serial.printf("%c", a);
  }
  Serial.printf("'\n");
  Serial.flush();
}
void setup() {
  Serial.begin(115200);
  delay(1000);      // sanity check delay
  while (!Serial) ; // wait for serial port open

  SPIFFS.begin();
    Serial.printf("Listing directory: %s\n", "/");

    File root = SPIFFS.open("/");
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }
    File file = root.openNextFile();
    while(file){
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
            file = root.openNextFile();
     }

  poweron = new AudioFileSourceSPIFFS("/POWERON.mp3");
  poweronid3 = new AudioFileSourceID3(poweron);
  poweronid3->RegisterMetadataCB(MDCallback, (void*)"ID3TAG");
  out = new AudioOutputI2S(0, false);
  mp3 = new AudioGeneratorMP3();
  mp3->begin(poweronid3, out);
  Serial.println("Done Setup");
}
void loop() {
  //Update sound
  if (mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  }
  else {
    Serial.println("MP3 Done");
    delay(1000);
  }
}

Which produces output like this:

Listing directory: /
  FILE: /POWERON.mp3  SIZE: 24987
  FILE: /SWING1.mp3  SIZE: 12934
  FILE: /HUM.mp3  SIZE: 275054
  FILE: /CLASH3.mp3  SIZE: 8502
  FILE: /CLASH2.mp3  SIZE: 17161
  FILE: /SWING5.mp3  SIZE: 13508
  FILE: /SWING3.mp3  SIZE: 15702
  FILE: /POWEROFF.mp3  SIZE: 17453
  FILE: /CLASH5.mp3  SIZE: 8501
  FILE: /CLASH1.mp3  SIZE: 10326
  FILE: /LOCKUP.mp3  SIZE: 75683
  FILE: /SWING2.mp3  SIZE: 11633
+0 0x3ffca67c
Done Setup
MP3 stop, len==0
MP3 Done
...

The MP3 stop, len==0 happens very quickly, sooner than I might have expected for the file being played. So, that leaves me with two questions:

  1. Has anyone else had success with ESP32 and SPIFFS?
  2. How do I tell the library to output to DAC1 instead of DAC0?

I know ESP32 support is relatively new/buggy. I'd be happy to help wherever I can, I'm just not sure where to start. Thanks!

Something is not alright with hardware serial

I am trying to get your software running but at the first compiling effort I get the message:
'class HardwareSerial' has no member named 'printf_P'
if (!buffer) Serial.printf_P(PSTR("Unable to allocate AudioFileSourceBuffer::buffer[]\n"));

How do I proceed

Regards
Ellard

Pins for I2S DAC chip

Hi all,

Having had marginal success with the NoDAC options I opted to buy one of these:

https://www.aliexpress.com/item/1PCS-PCM5102-PCM5102A-DAC-decoder-I2S-raspberry-red-core-player/32818888303.html

I need assistance wiring the pins up correctly. I am using the ESP8266 ESP-12-E, see its pins here:

https://i.pinimg.com/564x/0c/8c/e8/0c8ce8bc22ee6ba0e2ed830bcbb28454--diy-electronics-arduino.jpg

If i want to run the AACExample in the examples dir, what do I wire the LRCK,DATA and BLK pins to on the ESP?

VCC : 5v
GND : 5v gnd
GND : 5v gnd
LRCK : ???
DATA ;???
BLK ; ???

Play two wav files simultaneously?

Do you think it would be possible to play two wav files simultaneously?
and asynchronously. (at least as far as when they individually start and finish...The sample rates would be the same)
I tried some of the obvious things like having two definitions of wav and file, but there is only one "out" ---

MP3 playback delay / skip on Wemos D1 Mini Pro

Hi! I really like the library :)
But there's a strange thing... I tried to (re)play a mp3 on a Wemos D1 Mini Lite, which worked great.
Then I tried it on the Wemos ~ Pro, becaus of the bigger flash size. (Both on 160 MHz)
Then things behaved different. I heard a gap in the audio, at different places, at different bitrates... (Every time, same place)
Here's a picture:
schermafbeelding 2018-02-26 om 18 00 20
MP3's are converted WAV's with ffmpeg: ffmpeg -i filename.wav -b:a 320000 newfilename.mp3
Here's the code (mostly the mp3-SPIFFS-example).

#include <Arduino.h>
#include "AudioFileSourceSPIFFS.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"

AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioOutputI2S *out;
bool beat = true;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(100);
  SPIFFS.begin();
  delay(100);

  file = new AudioFileSourceSPIFFS("/a.mp3");
  out = new AudioOutputI2S();
  mp3 = new AudioGeneratorMP3();
  mp3->begin(file, out);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (mp3->isRunning()) {
    if (!mp3->loop()){
      mp3->stop(); 
      delete file;
      delete mp3;
      mp3 = new AudioGeneratorMP3();
    }
  } else {
    Serial.printf("mp3 done\n");
    if(beat){
      Serial.println("a");
      file = new AudioFileSourceSPIFFS("/a.mp3"); // 320 kbps
      beat = false;
    } else{
      Serial.println("b");
      file = new AudioFileSourceSPIFFS("/b.mp3"); // 128 kbps
      beat = true;
    }
      delay(5000);
      mp3->begin(file, out);
  }
}

Curious!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.