-
Notifications
You must be signed in to change notification settings - Fork 215
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
510 changed files
with
140,553 additions
and
0 deletions.
There are no files selected for viewing
674 changes: 674 additions & 0 deletions
674
software/firmware/source/libraries/ESP8266Audio/LICENSE
Large diffs are not rendered by default.
Oops, something went wrong.
266 changes: 266 additions & 0 deletions
266
software/firmware/source/libraries/ESP8266Audio/README.md
Large diffs are not rendered by default.
Oops, something went wrong.
33 changes: 33 additions & 0 deletions
33
software/firmware/source/libraries/ESP8266Audio/keywords.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
AudioFileSource KEYWORD1 | ||
AudioFileSourceSPIFFS KEYWORD1 | ||
AudioFileSourceLittleFS KEYWORD1 | ||
AudioFileSourceFS KEYWORD1 | ||
AudioFileSourcePROGMEM KEYWORD1 | ||
AudioFileSourceHTTPStream KEYWORD1 | ||
AudioFileSourceICYStream KEYWORD1 | ||
AudioFileSourceID3 KEYWORD1 | ||
AudioFileSourceSD KEYWORD1 | ||
AudioFileSourceBuffer KEYWORD1 | ||
AudioFileSourceSPIRAMBuffer KEYWORD1 | ||
AudioGenerator KEYWORD1 | ||
AudioGeneratorAAC KEYWORD1 | ||
AudioGeneratorFLAC KEYWORD1 | ||
AudioGeneratorMOD KEYWORD1 | ||
AudioGeneratorMIDI KEYWORD1 | ||
AudioGeneratorMP3 KEYWORD1 | ||
AudioGeneratorOpus KEYWORD1 | ||
AudioGeneratorRTTTL KEYWORD1 | ||
AudioGeneratorTalkie KEYWORD1 | ||
AudioGeneratorWAV KEYWORD1 | ||
AudioOutput KEYWORD1 | ||
AudioOutputI2S KEYWORD1 | ||
AudioOutputI2SNoDAC KEYWORD1 | ||
AudioOutputI2SClass KEYWORD1 | ||
AudioOutputPWM KEYWORD1 | ||
AudioOutputNull KEYWORD1 | ||
AudioOutputBuffer KEYWORD1 | ||
AudioOutputSerialWAV KEYWORD1 | ||
AudioOutputSPIFFSWAV KEYWORD1 | ||
AudioOutputMixer KEYWORD1 | ||
AudioOutputMixerStub KEYWORD1 | ||
AudioOutputSPDIF KEYWORD1 |
26 changes: 26 additions & 0 deletions
26
software/firmware/source/libraries/ESP8266Audio/library.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"name": "ESP8266Audio", | ||
"description": "Audio file format and I2S DAC library for ESP8266, ESP32, and Raspberry Pi Pico RP2040", | ||
"keywords": "ESP8266, ESP32, MP3, AAC, WAV, MOD, FLAC, RTTTL, MIDI, I2S, DAC, Delta-Sigma, TTS", | ||
"authors": [ | ||
{ | ||
"name": "Earle F. Philhower, III", | ||
"email": "[email protected]", | ||
"url": "https://github.com/earlephilhower/ESP8266Audio", | ||
"maintainer": true | ||
} | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/earlephilhower/ESP8266Audio" | ||
}, | ||
"version": "1.9.7", | ||
"homepage": "https://github.com/earlephilhower/ESP8266Audio", | ||
"frameworks": "Arduino", | ||
"examples": [ | ||
"examples/*/*.ino" | ||
], | ||
"build": { | ||
"libLDFMode": "deep" | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
software/firmware/source/libraries/ESP8266Audio/library.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
name=ESP8266Audio | ||
version=1.9.7 | ||
author=Earle F. Philhower, III | ||
maintainer=Earle F. Philhower, III | ||
sentence=Audio file and I2S sound playing routines for ESP8266, ESP32, and Raspberry Pi Pico RP2040 | ||
paragraph=Decode compressed MP3, AAC, FLAC, Screamtracker MOD, MIDI, RTTL, TI Talkie, and WAV and play on an I2S DAC or a software-driven delta-sigma DAC and 1-transistor amplifier. | ||
category=Signal Input/Output | ||
url=https://github.com/earlephilhower/ESP8266Audio | ||
architectures=esp8266,esp32,rp2040 |
51 changes: 51 additions & 0 deletions
51
software/firmware/source/libraries/ESP8266Audio/src/AudioFileSource.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
AudioFileSource | ||
Base class of an input "file" to be used by AudioGenerator | ||
Copyright (C) 2017 Earle F. Philhower, III | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef _AUDIOFILESOURCE_H | ||
#define _AUDIOFILESOURCE_H | ||
|
||
#include <Arduino.h> | ||
#include "AudioStatus.h" | ||
|
||
class AudioFileSource | ||
{ | ||
public: | ||
AudioFileSource() {}; | ||
virtual ~AudioFileSource() {}; | ||
virtual bool open(const char *filename) { (void)filename; return false; }; | ||
virtual uint32_t read(void *data, uint32_t len) { (void)data; (void)len; return 0; }; | ||
virtual uint32_t readNonBlock(void *data, uint32_t len) { return read(data, len); }; | ||
virtual bool seek(int32_t pos, int dir) { (void)pos; (void)dir; return false; }; | ||
virtual bool close() { return false; }; | ||
virtual bool isOpen() { return false; }; | ||
virtual uint32_t getSize() { return 0; }; | ||
virtual uint32_t getPos() { return 0; }; | ||
virtual bool loop() { return true; }; | ||
|
||
public: | ||
virtual bool RegisterMetadataCB(AudioStatus::metadataCBFn fn, void *data) { return cb.RegisterMetadataCB(fn, data); } | ||
virtual bool RegisterStatusCB(AudioStatus::statusCBFn fn, void *data) { return cb.RegisterStatusCB(fn, data); } | ||
|
||
protected: | ||
AudioStatus cb; | ||
}; | ||
|
||
#endif | ||
|
190 changes: 190 additions & 0 deletions
190
software/firmware/source/libraries/ESP8266Audio/src/AudioFileSourceBuffer.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
/* | ||
AudioFileSourceBuffer | ||
Double-buffered file source using system RAM | ||
Copyright (C) 2017 Earle F. Philhower, III | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <Arduino.h> | ||
#include "AudioFileSourceBuffer.h" | ||
|
||
#pragma GCC optimize ("O3") | ||
|
||
AudioFileSourceBuffer::AudioFileSourceBuffer(AudioFileSource *source, uint32_t buffSizeBytes) | ||
{ | ||
buffSize = buffSizeBytes; | ||
buffer = (uint8_t*)malloc(sizeof(uint8_t) * buffSize); | ||
if (!buffer) audioLogger->printf_P(PSTR("Unable to allocate AudioFileSourceBuffer::buffer[]\n")); | ||
deallocateBuffer = true; | ||
writePtr = 0; | ||
readPtr = 0; | ||
src = source; | ||
length = 0; | ||
filled = false; | ||
} | ||
|
||
AudioFileSourceBuffer::AudioFileSourceBuffer(AudioFileSource *source, void *inBuff, uint32_t buffSizeBytes) | ||
{ | ||
buffSize = buffSizeBytes; | ||
buffer = (uint8_t*)inBuff; | ||
deallocateBuffer = false; | ||
writePtr = 0; | ||
readPtr = 0; | ||
src = source; | ||
length = 0; | ||
filled = false; | ||
} | ||
|
||
AudioFileSourceBuffer::~AudioFileSourceBuffer() | ||
{ | ||
if (deallocateBuffer) free(buffer); | ||
buffer = NULL; | ||
} | ||
|
||
bool AudioFileSourceBuffer::seek(int32_t pos, int dir) | ||
{ | ||
if(dir == SEEK_CUR && (readPtr+pos) < length) { | ||
readPtr += pos; | ||
return true; | ||
} else { | ||
// Invalidate | ||
readPtr = 0; | ||
writePtr = 0; | ||
length = 0; | ||
return src->seek(pos, dir); | ||
} | ||
} | ||
|
||
bool AudioFileSourceBuffer::close() | ||
{ | ||
if (deallocateBuffer) free(buffer); | ||
buffer = NULL; | ||
return src->close(); | ||
} | ||
|
||
bool AudioFileSourceBuffer::isOpen() | ||
{ | ||
return src->isOpen(); | ||
} | ||
|
||
uint32_t AudioFileSourceBuffer::getSize() | ||
{ | ||
return src->getSize(); | ||
} | ||
|
||
uint32_t AudioFileSourceBuffer::getPos() | ||
{ | ||
return src->getPos(); | ||
} | ||
|
||
uint32_t AudioFileSourceBuffer::getFillLevel() | ||
{ | ||
return length; | ||
} | ||
|
||
uint32_t AudioFileSourceBuffer::read(void *data, uint32_t len) | ||
{ | ||
if (!buffer) return src->read(data, len); | ||
|
||
uint32_t bytes = 0; | ||
if (!filled) { | ||
// Fill up completely before returning any data at all | ||
cb.st(STATUS_FILLING, PSTR("Refilling buffer")); | ||
length = src->read(buffer, buffSize); | ||
writePtr = length % buffSize; | ||
filled = true; | ||
} | ||
|
||
// Pull from buffer until we've got none left or we've satisfied the request | ||
uint8_t *ptr = reinterpret_cast<uint8_t*>(data); | ||
uint32_t toReadFromBuffer = (len < length) ? len : length; | ||
if ( (toReadFromBuffer > 0) && (readPtr >= writePtr) ) { | ||
uint32_t toReadToEnd = (toReadFromBuffer < (uint32_t)(buffSize - readPtr)) ? toReadFromBuffer : (buffSize - readPtr); | ||
memcpy(ptr, &buffer[readPtr], toReadToEnd); | ||
readPtr = (readPtr + toReadToEnd) % buffSize; | ||
len -= toReadToEnd; | ||
length -= toReadToEnd; | ||
ptr += toReadToEnd; | ||
bytes += toReadToEnd; | ||
toReadFromBuffer -= toReadToEnd; | ||
} | ||
if (toReadFromBuffer > 0) { // We know RP < WP at this point | ||
memcpy(ptr, &buffer[readPtr], toReadFromBuffer); | ||
readPtr = (readPtr + toReadFromBuffer) % buffSize; | ||
len -= toReadFromBuffer; | ||
length -= toReadFromBuffer; | ||
ptr += toReadFromBuffer; | ||
bytes += toReadFromBuffer; | ||
toReadFromBuffer -= toReadFromBuffer; | ||
} | ||
|
||
if (len) { | ||
// Still need more, try direct read from src | ||
bytes += src->read(ptr, len); | ||
// We're out of buffered data, need to force a complete refill. Thanks, @armSeb | ||
readPtr = 0; | ||
writePtr = 0; | ||
length = 0; | ||
filled = false; | ||
cb.st(STATUS_UNDERFLOW, PSTR("Buffer underflow")); | ||
} | ||
|
||
fill(); | ||
|
||
return bytes; | ||
} | ||
|
||
void AudioFileSourceBuffer::fill() | ||
{ | ||
if (!buffer) return; | ||
|
||
if (length < buffSize) { | ||
// Now try and opportunistically fill the buffer | ||
if (readPtr > writePtr) { | ||
if (readPtr == writePtr+1) return; | ||
uint32_t bytesAvailMid = readPtr - writePtr - 1; | ||
int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailMid); | ||
length += cnt; | ||
writePtr = (writePtr + cnt) % buffSize; | ||
return; | ||
} | ||
|
||
if (buffSize > writePtr) { | ||
uint32_t bytesAvailEnd = buffSize - writePtr; | ||
int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailEnd); | ||
length += cnt; | ||
writePtr = (writePtr + cnt) % buffSize; | ||
if (cnt != (int)bytesAvailEnd) return; | ||
} | ||
|
||
if (readPtr > 1) { | ||
uint32_t bytesAvailStart = readPtr - 1; | ||
int cnt = src->readNonBlock(&buffer[writePtr], bytesAvailStart); | ||
length += cnt; | ||
writePtr = (writePtr + cnt) % buffSize; | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
bool AudioFileSourceBuffer::loop() | ||
{ | ||
if (!src->loop()) return false; | ||
fill(); | ||
return true; | ||
} | ||
|
62 changes: 62 additions & 0 deletions
62
software/firmware/source/libraries/ESP8266Audio/src/AudioFileSourceBuffer.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
AudioFileSourceBuffer | ||
Double-buffered input file using system RAM | ||
Copyright (C) 2017 Earle F. Philhower, III | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef _AUDIOFILESOURCEBUFFER_H | ||
#define _AUDIOFILESOURCEBUFFER_H | ||
|
||
#include "AudioFileSource.h" | ||
|
||
|
||
class AudioFileSourceBuffer : public AudioFileSource | ||
{ | ||
public: | ||
AudioFileSourceBuffer(AudioFileSource *in, uint32_t bufferBytes); | ||
AudioFileSourceBuffer(AudioFileSource *in, void *buffer, uint32_t bufferBytes); // Pre-allocated buffer by app | ||
virtual ~AudioFileSourceBuffer() override; | ||
|
||
virtual uint32_t read(void *data, uint32_t len) override; | ||
virtual bool seek(int32_t pos, int dir) override; | ||
virtual bool close() override; | ||
virtual bool isOpen() override; | ||
virtual uint32_t getSize() override; | ||
virtual uint32_t getPos() override; | ||
virtual bool loop() override; | ||
|
||
virtual uint32_t getFillLevel(); | ||
|
||
enum { STATUS_FILLING=2, STATUS_UNDERFLOW }; | ||
|
||
private: | ||
virtual void fill(); | ||
|
||
private: | ||
AudioFileSource *src; | ||
uint32_t buffSize; | ||
uint8_t *buffer; | ||
bool deallocateBuffer; | ||
uint32_t writePtr; | ||
uint32_t readPtr; | ||
uint32_t length; | ||
bool filled; | ||
}; | ||
|
||
|
||
#endif | ||
|
Oops, something went wrong.