Skip to content

Commit

Permalink
Merge branch 'master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
earlephilhower authored Oct 8, 2024
2 parents f54d848 + 235bcb1 commit 646b6c9
Show file tree
Hide file tree
Showing 68 changed files with 12,038 additions and 360 deletions.
48 changes: 37 additions & 11 deletions .github/workflows/pr-or-master-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,40 @@ on:

jobs:

build-rp2040:
name: Build RP2040
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1, 2, 3, 4]
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Build Sketches
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
BUILD_TYPE: build_rp2040
BUILD_MOD: 5
BUILD_REM: ${{ matrix.chunk }}
run: |
bash ./tests/common.sh
build-esp8266:
name: Build ESP8266
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1, 2, 3, 4]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Build Sketches
Expand All @@ -36,18 +59,17 @@ jobs:
run: |
bash ./tests/common.sh
build-esp32:
name: Build ESP-32
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1, 2, 3, 4]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Build Sketches
Expand All @@ -65,10 +87,10 @@ jobs:
name: Host tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v2
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Run host tests
Expand All @@ -84,13 +106,17 @@ jobs:
valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./mp3
valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./aac
valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./wav
valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./flac
valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./mod
valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./wav
valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./midi
valgrind --leak-check=full --track-origins=yes -v --error-limit=no --show-leak-kinds=all --error-exitcode=999 ./opus
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: arduino/arduino-lint-action@v1
- uses: actions/checkout@v4
- uses: arduino/arduino-lint-action@v2
with:
library-manager: 'update'

Expand All @@ -102,11 +128,11 @@ jobs:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true
- name: Run codespell
uses: codespell-project/actions-codespell@master
with:
skip: ./src/libmad,./src/libhelix-aac,./src/libopus
skip: ./src/libmad,./src/libhelix-aac,./src/libopus,./src/libflac
ignore_words_list: ESP8266,esp8266,esp,dout,DOUT,ser,ans,inout,numer,hist
50 changes: 21 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,30 @@
# ESP8266Audio - supports ESP8266 & ESP32 & Raspberry Pi RP2040[![Gitter](https://badges.gitter.im/ESP8266Audio/community.svg)](https://gitter.im/ESP8266Audio/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
# ESP8266Audio - supports ESP8266 & ESP32 & Raspberry Pi Pico RP2040 [![Gitter](https://badges.gitter.im/ESP8266Audio/community.svg)](https://gitter.im/ESP8266Audio/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
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](https://github.com/earlephilhower/ESP8266SAM), a library which uses this one and a port of an ancient format-based synthesis program to allow your ESP8266 to talk with low memory and no network required.
For real-time, autonomous speech synthesis, check out [ESP8266SAM](https://github.com/earlephilhower/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 StellaPlayer 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.
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 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](http://www.via-corp.com/us/en/licensing/aac/overview.html).

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](https://github.com/LenShustek/miditones) combined with a massively memory-optimized [TinySoundFont](https://github.com/schellingb/TinySoundFont), see the respective source files for more information.

Opus, OGG, and OpusFile are from [Xiph.org](https://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.
* 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](http://www.via-corp.com/us/en/licensing/aac/overview.html). 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](https://github.com/LenShustek/miditones) combined with a massively memory-optimized [TinySoundFont](https://github.com/schellingb/TinySoundFont), see the respective source files for more information.
* Opus, OGG, and OpusFile are from [Xiph.org](https://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](mailto:[email protected])!

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](https://github.com/earlephilhower/psychoclock).

Harald Sattler has built a neat German [word clock with MP3 alarm](http://www.harald-sattler.de/html/mini-wecker.htm). 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](https://github.com/ErichHeinemann/hman-stomper).

Dagnall53 has integrated this into a really neat MQTT based model train controller to add sounds to his set. More info is available [here](https://github.com/dagnall53/ESPMQTTRocnetSound), 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
* 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](https://github.com/earlephilhower/psychoclock).
* Harald Sattler has built a neat German [word clock with MP3 alarm](http://www.harald-sattler.de/html/mini-wecker.htm). 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](https://github.com/ErichHeinemann/hman-stomper).
* Dagnall53 has integrated this into a really neat MQTT based model train controller to add sounds to his set. More info is available [here](https://github.com/dagnall53/ESPMQTTRocnetSound), 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.
Expand Down Expand Up @@ -181,7 +172,7 @@ I've used several versions of PCM5102 DAC boards purchased from eBay. They've a
### 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.
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!
Expand Down Expand Up @@ -216,7 +207,7 @@ USB-5V -- 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 `dicitalWrite` or `digitalRead` as desired.
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.
Expand Down Expand Up @@ -249,7 +240,7 @@ ESP Pin -------|____|--------+
|
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 confgurable with `AudioOutputSPDIF(gpio_num)`.
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.
Expand All @@ -265,10 +256,11 @@ I've been told the Wemos SD card shield uses GPIO15 as the SD chip select. This
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 StellaPlayer and libMAD for releasing their code freely, and to the maintainers and contributors to the ESP8266 Arduino port.
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]
7 changes: 6 additions & 1 deletion examples/MixerSample/MixerSample.ino
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#include <Arduino.h>
#ifdef ESP32

#if defined(ARDUINO_ARCH_RP2040)
#define WIFI_OFF
class __x { public: __x() {}; void mode() {}; };
__x WiFi;
#elif defined(ESP32)
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
Expand Down
8 changes: 7 additions & 1 deletion examples/PlayFLAC-SD-SPDIF/PlayFLAC-SD-SPDIF.ino
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#include <Arduino.h>
#ifdef ARDUINO_ARCH_RP2040
void setup() {}
void loop() {}
#else
#include "AudioFileSourceSD.h"
#include "AudioOutputSPDIF.h"
#include "AudioGeneratorFLAC.h"
Expand Down Expand Up @@ -61,8 +65,10 @@ void loop() {
}
}
} else {
Serial.println(F("Playback form SD card done\n"));
Serial.println(F("Playback from SD card done\n"));
delay(1000);
}
}
}
#endif

9 changes: 7 additions & 2 deletions examples/PlayMIDIFromLittleFS/PlayMIDIFromLittleFS.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
}
void loop() {}
#else
#include <ESP8266WiFi.h>
#if defined(ARDUINO_ARCH_RP2040)
#define WIFI_OFF
class __x { public: __x() {}; void mode() {}; };
__x WiFi;
#else
#include <ESP8266WiFi.h>
#endif
#include <AudioOutputI2S.h>
#include <AudioGeneratorMIDI.h>
#include <AudioFileSourceLittleFS.h>
Expand Down Expand Up @@ -42,7 +48,6 @@ void loop()
{
if (midi->isRunning()) {
if (!midi->loop()) {
uint32_t e = millis();
midi->stop();
}
} else {
Expand Down
10 changes: 8 additions & 2 deletions examples/PlayMIDIFromSPIFFS/PlayMIDIFromSPIFFS.ino
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
#include <Arduino.h>

// Do not build on Espressif GCC8+, compiler bug

#if defined(ARDUINO_ARCH_RP2040) || (defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__))
void setup() {}
void loop() {}
#else
#ifdef ESP32
#include <WiFi.h>
#include "SPIFFS.h"
Expand Down Expand Up @@ -44,7 +51,6 @@ void loop()
{
if (midi->isRunning()) {
if (!midi->loop()) {
uint32_t e = millis();
midi->stop();
}
} else {
Expand All @@ -53,4 +59,4 @@ void loop()
}
}


#endif
6 changes: 5 additions & 1 deletion examples/PlayMODFromPROGMEMToDAC/PlayMODFromPROGMEMToDAC.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
#include "AudioFileSourcePROGMEM.h"
#include "AudioGeneratorMOD.h"
#include "AudioOutputI2S.h"
#ifdef ESP32
#if defined(ARDUINO_ARCH_RP2040)
#define WIFI_OFF
class __x { public: __x() {}; void mode() {}; };
__x WiFi;
#elif defined(ESP32)
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
Expand Down
Loading

0 comments on commit 646b6c9

Please sign in to comment.