Skip to content

Commit 2006d30

Browse files
committed
an update of ESP8266Audio library
1 parent 80d8eb4 commit 2006d30

File tree

15 files changed

+207
-88
lines changed

15 files changed

+207
-88
lines changed

software/firmware/source/libraries/ESP8266Audio/README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
# 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)
1+
# ESP8266Audio - supports ESP8266 & ESP32 & Raspberry Pi Pico RP2040 and Pico 2 RP2350 [![Gitter](https://badges.gitter.im/ESP8266Audio/community.svg)](https://gitter.im/ESP8266Audio/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
22
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.
33

4+
# Raspberry Pi Pico (RP2040 and RP2350) Users
5+
Consider using [BackgroundAudio](https://github.com/earlephilhower/BackgroundAudio) instead of this library as it can provide a simpler usage model and better results and performance on the Pico by using an interrupt-based, frame-aligned output model.
6+
7+
# ESP8266 and ESP32 Users
48
ESP8266 is fully supported and most mature, but ESP32 is also mostly there with built-in DAC as well as external ones.
59

610
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.
@@ -138,7 +142,7 @@ AudioGeneratorRTTTL: Enjoy the pleasures of monophonic, 4-octave ringtones on y
138142
## AudioOutput classes
139143
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.
140144
141-
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](src/AudioOutputI2S.cpp#L29) for details.
145+
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,AudioOutputI2S::INTERNAL_DAC)`, see example `PlayMODFromPROGMEMToDAC` and code in [AudioOutputI2S.cpp](src/AudioOutputI2S.cpp#L29) for details. To use the hardware Pulse Density Modulation (PDM) on ESP32, instantiate this class as `AudioOutputI2S(0,AudioOutputI2S::INTERNAL_PDM)`. For both later cases, default output pins are GPIO25 and GPIO26.
142146
143147
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.
144148
@@ -190,7 +194,8 @@ Use the `AudioOutputI2S*No*DAC` object instead of the `AudioOutputI2S` in your c
190194
ESP8266-GND ------------------+ | +------+ K|
191195
| | | E|
192196
ESP8266-I2SOUT (Rx) -----/\/\/\--+ | \ R|
193-
| +-|
197+
or ESP32 DOUT pin | +-|
198+
|
194199
USB 5V -----------------------------+
195200

196201
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.
@@ -203,12 +208,19 @@ ESP8266-RX(I2S tx) -- Resistor (~1K ohm, not critical) -- 2N3904 Base
203208
ESP8266-GND -- 2N3904 Emitter
204209
USB-5V -- Speaker + Terminal
205210
2N3904-Collector -- Speaker - Terminal
211+
212+
*For ESP32, default output pin is GPIO22. Note that GPIO25 ang GPIO26 are occupied by wclk/bclk and can not be used.
206213
```
207214
208215
*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.
209216
210217
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.
211218
219+
### Hardware PDM on ESP32
220+
221+
Hardware PDM outputs 128 * 48Khz pulses regardless of sample rate.
222+
It seems that currently hardware PDM either does not output constant One at maximum sample level, or does not output 3.3V voltage at pulse sound is not as loud as desired. You may consider using software delta-sigma DAC instead.
223+
212224
### High pitched buzzing with the 1-T circuit
213225
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.
214226

software/firmware/source/libraries/ESP8266Audio/library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"type": "git",
1515
"url": "https://github.com/earlephilhower/ESP8266Audio"
1616
},
17-
"version": "1.9.7",
17+
"version": "1.9.9",
1818
"homepage": "https://github.com/earlephilhower/ESP8266Audio",
1919
"frameworks": "Arduino",
2020
"examples": [

software/firmware/source/libraries/ESP8266Audio/library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ESP8266Audio
2-
version=1.9.7
2+
version=1.9.9
33
author=Earle F. Philhower, III
44
maintainer=Earle F. Philhower, III
55
sentence=Audio file and I2S sound playing routines for ESP8266, ESP32, and Raspberry Pi Pico RP2040

software/firmware/source/libraries/ESP8266Audio/src/AudioGeneratorMIDI.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,9 @@ int AudioGeneratorMIDI::PlayMIDI()
443443
for (tgnum = 0; tgnum < num_tonegens; ++tgnum) { /* find which generator is playing it */
444444
tg = &tonegen[tgnum];
445445
if (tg->playing && tg->track == tracknum && tg->note == trk->note) {
446-
tsf_note_off (g_tsf, tg->instrument, tg->note);
446+
tsf_note_off_fast (g_tsf, tg->instrument, tg->note, tg->playIndex);
447447
tg->playing = false;
448+
tg->playIndex = -1;
448449
trk->tonegens[tgnum] = false;
449450
}
450451
}
@@ -476,7 +477,7 @@ int AudioGeneratorMIDI::PlayMIDI()
476477
if (tg->instrument != midi_chan_instrument[trk->chan]) { /* new instrument for this generator */
477478
tg->instrument = midi_chan_instrument[trk->chan];
478479
}
479-
tsf_note_on (g_tsf, tg->instrument, tg->note, trk->velocity / 127.0); // velocity = 0...127
480+
tg->playIndex = tsf_note_on_fast (g_tsf, tg->instrument, tg->note, trk->velocity / 127.0); // velocity = 0...127
480481
} else {
481482
++notes_skipped;
482483
}

software/firmware/source/libraries/ESP8266Audio/src/AudioGeneratorMIDI.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,13 @@ class AudioGeneratorMIDI : public AudioGenerator
9494
unsigned long earliest_time = 0;
9595

9696
struct tonegen_status { /* current status of a tone generator */
97-
bool playing; /* is it playing? */
97+
bool playing; /* is it playing? */
9898
char track; /* if so, which track is the note from? */
9999
char note; /* what note is playing? */
100100
char instrument; /* what instrument? */
101+
int playIndex; /* is index provided?
102+
Unique identifier generated when note starts playing.
103+
This help us to turn the note off faster */
101104
} tonegen[MAX_TONEGENS];
102105

103106
struct track_status { /* current processing point of a MIDI track */

software/firmware/source/libraries/ESP8266Audio/src/AudioGeneratorMP3.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ AudioGeneratorMP3::AudioGeneratorMP3()
2727
file = NULL;
2828
output = NULL;
2929
buff = NULL;
30+
synth = NULL;
31+
frame = NULL;
32+
stream = NULL;
3033
nsCountMax = 1152/32;
3134
madInitted = false;
3235
}
@@ -37,6 +40,9 @@ AudioGeneratorMP3::AudioGeneratorMP3(void *space, int size): preallocateSpace(sp
3740
file = NULL;
3841
output = NULL;
3942
buff = NULL;
43+
synth = NULL;
44+
frame = NULL;
45+
stream = NULL;
4046
nsCountMax = 1152/32;
4147
madInitted = false;
4248
}
@@ -51,6 +57,9 @@ AudioGeneratorMP3::AudioGeneratorMP3(void *buff, int buffSize, void *stream, int
5157
file = NULL;
5258
output = NULL;
5359
buff = NULL;
60+
synth = NULL;
61+
frame = NULL;
62+
stream = NULL;
5463
nsCountMax = 1152/32;
5564
madInitted = false;
5665
}

software/firmware/source/libraries/ESP8266Audio/src/AudioOutputI2S.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout, int mclk)
123123
bclkPin = bclk;
124124
wclkPin = wclk;
125125
doutPin = dout;
126-
#ifdef ESP32
126+
#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040)
127127
mclkPin = mclk;
128128
if (i2sOn)
129129
return SetPinout();
@@ -182,6 +182,8 @@ bool AudioOutputI2S::SetMclk(bool enabled){
182182
if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM)
183183
return false; // Not allowed
184184

185+
use_mclk = enabled;
186+
#elif defined(ARDUINO_ARCH_RP2040)
185187
use_mclk = enabled;
186188
#endif
187189
return true;
@@ -336,9 +338,16 @@ bool AudioOutputI2S::begin(bool txDAC)
336338
#elif defined(ARDUINO_ARCH_RP2040)
337339
(void)txDAC;
338340
if (!i2sOn) {
339-
i2s.setBCLK(bclkPin);
340-
i2s.setDATA(doutPin);
341-
i2s.begin(hertz);
341+
i2s.setSysClk(hertz);
342+
i2s.setBCLK(bclkPin);
343+
i2s.setDATA(doutPin);
344+
i2s.setMCLK(mclkPin);
345+
i2s.setMCLKmult(256);
346+
if (swap_clocks) {
347+
i2s.swapClocks();
348+
}
349+
i2s.setBitsPerSample(bps);
350+
i2s.begin(hertz);
342351
}
343352
#endif
344353
i2sOn = true;

software/firmware/source/libraries/ESP8266Audio/src/AudioOutputMixer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ bool AudioOutputMixerStub::stop()
7171
AudioOutputMixer::AudioOutputMixer(int buffSizeSamples, AudioOutput *dest) : AudioOutput()
7272
{
7373
buffSize = buffSizeSamples;
74-
leftAccum = (int32_t*)calloc(sizeof(int32_t), buffSize);
75-
rightAccum = (int32_t*)calloc(sizeof(int32_t), buffSize);
74+
leftAccum = (int32_t*)calloc(buffSize, sizeof(int32_t));
75+
rightAccum = (int32_t*)calloc(buffSize, sizeof(int32_t));
7676
for (int i=0; i<maxStubs; i++) {
7777
stubAllocated[i] = false;
7878
stubRunning[i] = false;

software/firmware/source/libraries/ESP8266Audio/src/AudioOutputPWM.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ bool AudioOutputPWM::ConsumeSample(int16_t sample[2]) {
105105
MakeSampleStereo16( ms );
106106
}
107107

108+
ms[LEFTCHANNEL] = Amplify(ms[LEFTCHANNEL]);
109+
ms[RIGHTCHANNEL] = Amplify(ms[RIGHTCHANNEL]);
110+
108111
if (pwm.available()) {
109112
pwm.write((int16_t) ms[0]);
110113
pwm.write((int16_t) ms[1]);

software/firmware/source/libraries/ESP8266Audio/src/libhelix-aac/assembly.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -558,14 +558,8 @@ static __inline int CLZ(int x)
558558
typedef union _U64 {
559559
Word64 w64;
560560
struct {
561-
#if defined(__XTENSA__) || defined (__riscv)
562561
unsigned int lo32;
563562
signed int hi32;
564-
#else
565-
/* PowerPC = big endian */
566-
signed int hi32;
567-
unsigned int lo32;
568-
#endif
569563
} r;
570564
} U64;
571565

0 commit comments

Comments
 (0)