Skip to content

Commit

Permalink
Merge branch 'master' into FedericoBusero-patch-ULP
Browse files Browse the repository at this point in the history
  • Loading branch information
earlephilhower authored Oct 8, 2024
2 parents d3e18fd + 96dc79c commit a0baa36
Show file tree
Hide file tree
Showing 34 changed files with 226 additions and 152 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/pr-or-master-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ jobs:
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 @@ -43,10 +43,10 @@ jobs:
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 @@ -66,10 +66,10 @@ jobs:
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 @@ -87,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 @@ -115,7 +115,7 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: arduino/arduino-lint-action@v1
with:
library-manager: 'update'
Expand All @@ -128,7 +128,7 @@ jobs:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true
- name: Run codespell
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Arduino library for parsing and decoding MOD, WAV, MP3, FLAC, MIDI, AAC, and RTT

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.
Expand Down
4 changes: 2 additions & 2 deletions examples/PlayMIDIFromSPIFFS/PlayMIDIFromSPIFFS.ino
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include <Arduino.h>

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

#if defined(ARDUINO_ARCH_RP2040) || ((__GNUC__ == 8) && (__XTENSA__))
#if defined(ARDUINO_ARCH_RP2040) || (defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__))
void setup() {}
void loop() {}
#else
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"type": "git",
"url": "https://github.com/earlephilhower/ESP8266Audio"
},
"version": "1.9.7",
"version": "1.9.9",
"homepage": "https://github.com/earlephilhower/ESP8266Audio",
"frameworks": "Arduino",
"examples": [
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ESP8266Audio
version=1.9.7
version=1.9.9
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
Expand Down
4 changes: 4 additions & 0 deletions src/AudioFileSourceHTTPStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ uint32_t AudioFileSourceHTTPStream::readInternal(void *data, uint32_t len, bool
}
if ((size > 0) && (pos >= size)) return 0;

#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3
NetworkClient *stream = http.getStreamPtr();
#else
WiFiClient *stream = http.getStreamPtr();
#endif

// Can't read past EOF...
if ( (size > 0) && (len > (uint32_t)(pos - size)) ) len = pos - size;
Expand Down
4 changes: 4 additions & 0 deletions src/AudioFileSourceHTTPStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ class AudioFileSourceHTTPStream : public AudioFileSource

private:
virtual uint32_t readInternal(void *data, uint32_t len, bool nonBlock);
#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3
NetworkClient client;
#else
WiFiClient client;
#endif
HTTPClient http;
int pos;
int size;
Expand Down
4 changes: 4 additions & 0 deletions src/AudioFileSourceICYStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ uint32_t AudioFileSourceICYStream::readInternal(void *data, uint32_t len, bool n
}
if ((size > 0) && (pos >= size)) return 0;

#if defined(ESP_ARDUINO_VERSION_MAJOR) && ESP_ARDUINO_VERSION_MAJOR >= 3
NetworkClient *stream = http.getStreamPtr();
#else
WiFiClient *stream = http.getStreamPtr();
#endif

// Can't read past EOF...
if ( (size > 0) && (len > (uint32_t)(pos - size)) ) len = pos - size;
Expand Down
2 changes: 1 addition & 1 deletion src/AudioGeneratorFLAC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ char AudioGeneratorFLAC::error_cb_str[64];
void AudioGeneratorFLAC::error_cb(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status)
{
(void) decoder;
strncpy_P(error_cb_str, FLAC__StreamDecoderErrorStatusString[status], 64);
strncpy_P(error_cb_str, FLAC__StreamDecoderErrorStatusString[status], sizeof(AudioGeneratorFLAC::error_cb_str) - 1);
cb.st((int)status, error_cb_str);
}

4 changes: 2 additions & 2 deletions src/AudioGeneratorMIDI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@

#include "AudioGeneratorMIDI.h"

#if (__GNUC__ == 8) && (__XTENSA__)
// Do not build, GCC8 has a compiler bug
#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__)
// Do not build, Espressif's GCC8+ has a compiler bug
#else // __GNUC__ == 8

#pragma GCC optimize ("O3")
Expand Down
4 changes: 2 additions & 2 deletions src/AudioGeneratorMIDI.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#ifndef _AUDIOGENERATORMIDI_H
#define _AUDIOGENERATORMIDI_H

#if (__GNUC__ == 8) && (__XTENSA__)
// Do not build, GCC8 has a compiler bug
#if defined(ESP32) && (__GNUC__ >= 8) && (__XTENSA__)
// Do not build, Espressif's GCC8+ has a compiler bug
#else // __GNUC__ == 8

#include "AudioGenerator.h"
Expand Down
18 changes: 11 additions & 7 deletions src/AudioGeneratorMP3.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
AudioGeneratorMP3
Wrap libmad MP3 library to play audio
Copyright (C) 2017 Earle F. Philhower, III
This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -62,7 +62,7 @@ AudioGeneratorMP3::~AudioGeneratorMP3()
free(synth);
free(frame);
free(stream);
}
}
}


Expand Down Expand Up @@ -182,15 +182,15 @@ bool AudioGeneratorMP3::GetOneSample(int16_t sample[2])
output->SetChannels(synth->pcm.channels);
lastChannels = synth->pcm.channels;
}

// If we're here, we have one decoded frame and sent 0 or more samples out
if (samplePtr < synth->pcm.length) {
sample[AudioOutput::LEFTCHANNEL ] = synth->pcm.samples[0][samplePtr];
sample[AudioOutput::RIGHTCHANNEL] = synth->pcm.samples[1][samplePtr];
samplePtr++;
} else {
samplePtr = 0;

switch ( mad_synth_frame_onens(synth, frame, nsCount++) ) {
case MAD_FLOW_STOP:
case MAD_FLOW_BREAK: audioLogger->printf_P(PSTR("msf1ns failed\n"));
Expand Down Expand Up @@ -302,6 +302,7 @@ bool AudioGeneratorMP3::begin(AudioFileSource *source, AudioOutput *output)
synth = reinterpret_cast<struct mad_synth *>(preallocateSynthSpace);
}
else {
output->stop();
audioLogger->printf_P("OOM error in MP3: Want %d/%d/%d/%d bytes, have %d/%d/%d/%d bytes preallocated.\n",
preAllocBuffSize(), preAllocStreamSize(), preAllocFrameSize(), preAllocSynthSize(),
preallocateSize, preallocateStreamSize, preallocateFrameSize, preallocateSynthSize);
Expand All @@ -319,6 +320,7 @@ bool AudioGeneratorMP3::begin(AudioFileSource *source, AudioOutput *output)
p += preAllocSynthSize();
int neededBytes = p - reinterpret_cast<uint8_t *>(preallocateSpace);
if (neededBytes > preallocateSize) {
output->stop();
audioLogger->printf_P("OOM error in MP3: Want %d bytes, have %d bytes preallocated.\n", neededBytes, preallocateSize);
return false;
}
Expand All @@ -336,17 +338,20 @@ bool AudioGeneratorMP3::begin(AudioFileSource *source, AudioOutput *output)
stream = NULL;
frame = NULL;
synth = NULL;

output->stop();
audioLogger->printf_P("OOM error in MP3\n");
return false;
}
}

mad_stream_init(stream);
mad_frame_init(frame);
mad_synth_init(synth);
synth->pcm.length = 0;
mad_stream_options(stream, 0); // TODO - add options support
madInitted = true;

running = true;
return true;
}
Expand Down Expand Up @@ -413,4 +418,3 @@ extern "C" {
}
#endif
}

6 changes: 3 additions & 3 deletions src/AudioGeneratorRTTTL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,13 @@ bool AudioGeneratorRTTTL::GetNextNote()
ptr++;
note++;
}
if (!ReadInt(&scale)) {
scale = defaultOctave;
}
if ((ptr < len) && (buff[ptr] == '.')) {
ptr++;
dur += dur / 2;
}
if (!ReadInt(&scale)) {
scale = defaultOctave;
}
// Eat any trailing whitespace and comma
SkipWhitespace();
if ((ptr < len) && (buff[ptr]==',')) {
Expand Down
33 changes: 26 additions & 7 deletions src/AudioOutputI2S.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ AudioOutputI2S::AudioOutputI2S(long sampleRate, pin_size_t sck, pin_size_t data)
doutPin = data;
mclkPin = 0;
use_mclk = false;
swap_clocks = false;
SetGain(1.0);
}
#endif
Expand Down Expand Up @@ -115,7 +116,7 @@ bool AudioOutputI2S::SetPinout(int bclk, int wclk, int dout, int mclk)
bclkPin = bclk;
wclkPin = wclk;
doutPin = dout;
#ifdef ESP32
#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040)
mclkPin = mclk;
if (i2sOn)
return SetPinout();
Expand Down Expand Up @@ -168,12 +169,23 @@ bool AudioOutputI2S::SetLsbJustified(bool lsbJustified)
return true;
}

bool AudioOutputI2S::SwapClocks(bool swap_clocks)
{
if (i2sOn) {
return false; // Not allowed
}
this->swap_clocks = swap_clocks;
return true;
}

bool AudioOutputI2S::SetMclk(bool enabled){
(void)enabled;
#ifdef ESP32
if (output_mode == INTERNAL_DAC || output_mode == INTERNAL_PDM)
return false; // Not allowed

use_mclk = enabled;
#elif defined(ARDUINO_ARCH_RP2040)
use_mclk = enabled;
#endif
return true;
Expand All @@ -188,9 +200,9 @@ bool AudioOutputI2S::begin(bool txDAC)
{
// don't use audio pll on buggy rev0 chips
use_apll = APLL_DISABLE;
esp_chip_info_t out_info;
esp_chip_info(&out_info);
if (out_info.revision > 0)
//esp_chip_info_t out_info;
//esp_chip_info(&out_info);
//if (out_info.revision > 0)
{
use_apll = APLL_ENABLE;
}
Expand Down Expand Up @@ -300,9 +312,16 @@ bool AudioOutputI2S::begin(bool txDAC)
#elif defined(ARDUINO_ARCH_RP2040)
(void)txDAC;
if (!i2sOn) {
i2s.setBCLK(bclkPin);
i2s.setDATA(doutPin);
i2s.begin(hertz);
i2s.setSysClk(hertz);
i2s.setBCLK(bclkPin);
i2s.setDATA(doutPin);
i2s.setMCLK(mclkPin);
i2s.setMCLKmult(256);
if (swap_clocks) {
i2s.swapClocks();
}
i2s.setBitsPerSample(bps);
i2s.begin(hertz);
}
#endif
i2sOn = true;
Expand Down
2 changes: 2 additions & 0 deletions src/AudioOutputI2S.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class AudioOutputI2S : public AudioOutput
bool SetOutputModeMono(bool mono); // Force mono output no matter the input
bool SetLsbJustified(bool lsbJustified); // Allow supporting non-I2S chips, e.g. PT8211
bool SetMclk(bool enabled); // Enable MCLK output (if supported)
bool SwapClocks(bool swap_clocks); // Swap BCLK and WCLK

protected:
bool SetPinout();
Expand All @@ -64,6 +65,7 @@ class AudioOutputI2S : public AudioOutput
int dma_buf_count;
int use_apll;
bool use_mclk;
bool swap_clocks;
// We can restore the old values and free up these pins when in NoDAC mode
uint32_t orig_bck;
uint32_t orig_ws;
Expand Down
4 changes: 2 additions & 2 deletions src/AudioOutputMixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ bool AudioOutputMixerStub::stop()
AudioOutputMixer::AudioOutputMixer(int buffSizeSamples, AudioOutput *dest) : AudioOutput()
{
buffSize = buffSizeSamples;
leftAccum = (int32_t*)calloc(sizeof(int32_t), buffSize);
rightAccum = (int32_t*)calloc(sizeof(int32_t), buffSize);
leftAccum = (int32_t*)calloc(buffSize, sizeof(int32_t));
rightAccum = (int32_t*)calloc(buffSize, sizeof(int32_t));
for (int i=0; i<maxStubs; i++) {
stubAllocated[i] = false;
stubRunning[i] = false;
Expand Down
3 changes: 3 additions & 0 deletions src/AudioOutputPWM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ bool AudioOutputPWM::ConsumeSample(int16_t sample[2]) {
ms[LEFTCHANNEL] = ms[RIGHTCHANNEL] = (ttl>>1) & 0xffff;
}

ms[LEFTCHANNEL] = Amplify(ms[LEFTCHANNEL]);
ms[RIGHTCHANNEL] = Amplify(ms[RIGHTCHANNEL]);

if (pwm.available()) {
pwm.write((int16_t) ms[0]);
pwm.write((int16_t) ms[1]);
Expand Down
Loading

0 comments on commit a0baa36

Please sign in to comment.