Unverified Commit a0bc3723 authored by Wolle's avatar Wolle Committed by GitHub

Merge pull request #619 from schreibfaul1/ArduinoV3.0

Arduino v3.0 support
parents 43115871 1d2f750d
This diff is collapsed.
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
* *
* Created on: Oct 28,2018 * Created on: Oct 28,2018
* *
* Version 3.0.7c * Version 3.0.7s
* Updated on: Nov 29.2023 * Updated on: Dec 01.2023
* Author: Wolle (schreibfaul1) * Author: Wolle (schreibfaul1)
*/ */
...@@ -17,14 +17,22 @@ ...@@ -17,14 +17,22 @@
#include <SPI.h> #include <SPI.h>
#include <WiFi.h> #include <WiFi.h>
#include <WiFiClientSecure.h> #include <WiFiClientSecure.h>
#include <vector>
#include <driver/i2s.h>
#include <SD.h> #include <SD.h>
#include <SD_MMC.h> #include <SD_MMC.h>
#include <SPIFFS.h> #include <SPIFFS.h>
#include <FS.h> #include <FS.h>
#include <FFat.h> #include <FFat.h>
#include <atomic>
#if ESP_IDF_VERSION_MAJOR == 5
#include <driver/i2s_std.h>
#else
#include <driver/i2s.h>
#endif
#ifndef I2S_GPIO_UNUSED
#define I2S_GPIO_UNUSED -1 // = I2S_PIN_NO_CHANGE in IDF < 5
#endif
using namespace std; using namespace std;
extern __attribute__((weak)) void audio_info(const char*); extern __attribute__((weak)) void audio_info(const char*);
...@@ -81,6 +89,7 @@ public: ...@@ -81,6 +89,7 @@ public:
size_t init(); // set default values size_t init(); // set default values
bool isInitialized() { return m_f_init; }; bool isInitialized() { return m_f_init; };
void setBufsize(int ram, int psram); void setBufsize(int ram, int psram);
int32_t getBufsize();
void changeMaxBlockSize(uint16_t mbs); // is default 1600 for mp3 and aac, set 16384 for FLAC void changeMaxBlockSize(uint16_t mbs); // is default 1600 for mp3 and aac, set 16384 for FLAC
uint16_t getMaxBlockSize(); // returns maxBlockSize uint16_t getMaxBlockSize(); // returns maxBlockSize
size_t freeSpace(); // number of free bytes to overwrite size_t freeSpace(); // number of free bytes to overwrite
...@@ -134,7 +143,7 @@ public: ...@@ -134,7 +143,7 @@ public:
bool setFilePos(uint32_t pos); bool setFilePos(uint32_t pos);
bool audioFileSeek(const float speed); bool audioFileSeek(const float speed);
bool setTimeOffset(int sec); bool setTimeOffset(int sec);
bool setPinout(uint8_t BCLK, uint8_t LRC, uint8_t DOUT, int8_t DIN = I2S_PIN_NO_CHANGE, int8_t MCK = I2S_PIN_NO_CHANGE); bool setPinout(uint8_t BCLK, uint8_t LRC, uint8_t DOUT, int8_t MCK = I2S_GPIO_UNUSED);
bool pauseResume(); bool pauseResume();
bool isRunning() {return m_f_running;} bool isRunning() {return m_f_running;}
void loop(); void loop();
...@@ -159,9 +168,9 @@ public: ...@@ -159,9 +168,9 @@ public:
uint32_t getTotalPlayingTime(); uint32_t getTotalPlayingTime();
uint16_t getVUlevel(); uint16_t getVUlevel();
esp_err_t i2s_mclk_pin_select(const uint8_t pin);
uint32_t inBufferFilled(); // returns the number of stored bytes in the inputbuffer uint32_t inBufferFilled(); // returns the number of stored bytes in the inputbuffer
uint32_t inBufferFree(); // returns the number of free bytes in the inputbuffer uint32_t inBufferFree(); // returns the number of free bytes in the inputbuffer
uint32_t inBufferSize(); // returns the size of the inputbuffer in bytes
void setTone(int8_t gainLowPass, int8_t gainBandPass, int8_t gainHighPass); void setTone(int8_t gainLowPass, int8_t gainBandPass, int8_t gainHighPass);
void setI2SCommFMT_LSB(bool commFMT); void setI2SCommFMT_LSB(bool commFMT);
int getCodec() {return m_codec;} int getCodec() {return m_codec;}
...@@ -192,6 +201,8 @@ private: ...@@ -192,6 +201,8 @@ private:
const char* parsePlaylist_PLS(); const char* parsePlaylist_PLS();
const char* parsePlaylist_ASX(); const char* parsePlaylist_ASX();
const char* parsePlaylist_M3U8(); const char* parsePlaylist_M3U8();
const char* m3u8redirection();
uint64_t m3u8_findMediaSeqInURL();
bool STfromEXTINF(char* str); bool STfromEXTINF(char* str);
void showCodecParams(); void showCodecParams();
int findNextSync(uint8_t* data, size_t len); int findNextSync(uint8_t* data, size_t len);
...@@ -280,14 +291,14 @@ private: ...@@ -280,14 +291,14 @@ private:
return true; return true;
} }
bool endsWith (const char* base, const char* str) { bool endsWith(const char *base, const char *searchString) {
//fb int32_t slen = strlen(searchString);
int slen = strlen(str) - 1; if(slen == 0) return false;
const char *p = base + strlen(base) - 1; const char *p = base + strlen(base);
while(p > base && isspace(*p)) p--; // rtrim // while(p > base && isspace(*p)) p--; // rtrim
p -= slen; p -= slen;
if (p < base) return false; if(p < base) return false;
return (strncmp(p, str, slen) == 0); return (strncmp(p, searchString, slen) == 0);
} }
int indexOf (const char* base, const char* str, int startIndex = 0) { int indexOf (const char* base, const char* str, int startIndex = 0) {
...@@ -399,7 +410,17 @@ private: ...@@ -399,7 +410,17 @@ private:
hash += (str[i] - 31) * i * 32; hash += (str[i] - 31) * i * 32;
} }
return hash; return hash;
} }
char* x_strdup(const char* str){
if(m_f_psramFound){
char* s = (char*)ps_malloc(strlen(str) + 1);
strcpy(s, str);
return s;
}
else{
return strdup(str);
}
}
private: private:
const char *codecname[10] = {"unknown", "WAV", "MP3", "AAC", "M4A", "FLAC", "AACP", "OPUS", "OGG", "VORBIS" }; const char *codecname[10] = {"unknown", "WAV", "MP3", "AAC", "M4A", "FLAC", "AACP", "OPUS", "OGG", "VORBIS" };
...@@ -436,10 +457,21 @@ private: ...@@ -436,10 +457,21 @@ private:
WiFiClientSecure clientsecure; // @suppress("Abstract class cannot be instantiated") WiFiClientSecure clientsecure; // @suppress("Abstract class cannot be instantiated")
WiFiClient* _client = nullptr; WiFiClient* _client = nullptr;
SemaphoreHandle_t mutex_audio; SemaphoreHandle_t mutex_audio;
i2s_config_t m_i2s_config = {}; // stores values for I2S driver
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#if ESP_IDF_VERSION_MAJOR == 5
i2s_chan_handle_t m_i2s_tx_handle = {};
i2s_chan_config_t m_i2s_chan_cfg = {}; // stores I2S channel values
i2s_std_config_t m_i2s_std_cfg = {}; // stores I2S driver values
#else
i2s_config_t m_i2s_config = {};
i2s_pin_config_t m_pin_config = {}; i2s_pin_config_t m_pin_config = {};
std::vector<char*> m_playlistContent; // m3u8 playlist buffer #endif
std::vector<char*> m_playlistURL; // m3u8 streamURLs buffer #pragma GCC diagnostic pop
std::vector<char*> m_playlistContent; // m3u8 playlist buffer
std::vector<char*> m_playlistURL; // m3u8 streamURLs buffer
std::vector<uint32_t> m_hashQueue; std::vector<uint32_t> m_hashQueue;
const size_t m_frameSizeWav = 1024; const size_t m_frameSizeWav = 1024;
...@@ -455,7 +487,9 @@ private: ...@@ -455,7 +487,9 @@ private:
char* m_ibuff = nullptr; // used in audio_info() char* m_ibuff = nullptr; // used in audio_info()
char* m_chbuf = NULL; char* m_chbuf = NULL;
uint16_t m_chbufSize = 0; // will set in constructor (depending on PSRAM) uint16_t m_chbufSize = 0; // will set in constructor (depending on PSRAM)
uint16_t m_ibuffSize = 0; // will set in constructor (depending on PSRAM)
char* m_lastHost = NULL; // Store the last URL to a webstream char* m_lastHost = NULL; // Store the last URL to a webstream
char* m_lastM3U8host = NULL;
char* m_playlistBuff = NULL; // stores playlistdata char* m_playlistBuff = NULL; // stores playlistdata
const uint16_t m_plsBuffEntryLen = 256; // length of each entry in playlistBuff const uint16_t m_plsBuffEntryLen = 256; // length of each entry in playlistBuff
filter_t m_filter[3]; // digital filters filter_t m_filter[3]; // digital filters
...@@ -485,10 +519,10 @@ private: ...@@ -485,10 +519,10 @@ private:
uint8_t m_vuLeft = 0; // average value of samples, left channel uint8_t m_vuLeft = 0; // average value of samples, left channel
uint8_t m_vuRight = 0; // average value of samples, right channel uint8_t m_vuRight = 0; // average value of samples, right channel
int16_t* m_outBuff = NULL; // Interleaved L/R int16_t* m_outBuff = NULL; // Interleaved L/R
int16_t m_validSamples = 0; std::atomic<int16_t> m_validSamples = {0}; // #144
int16_t m_curSample = 0; std::atomic<int16_t> m_curSample{0};
std::atomic<uint16_t> m_datamode{0}; // Statemaschine
int16_t m_decodeError = 0; // Stores the return value of the decoder int16_t m_decodeError = 0; // Stores the return value of the decoder
uint16_t m_datamode = 0; // Statemaschine
uint16_t m_streamTitleHash = 0; // remember streamtitle, ignore multiple occurence in metadata uint16_t m_streamTitleHash = 0; // remember streamtitle, ignore multiple occurence in metadata
uint16_t m_timeout_ms = 250; uint16_t m_timeout_ms = 250;
uint16_t m_timeout_ms_ssl = 2700; uint16_t m_timeout_ms_ssl = 2700;
...@@ -514,6 +548,7 @@ private: ...@@ -514,6 +548,7 @@ private:
bool m_f_ssl = false; bool m_f_ssl = false;
bool m_f_running = false; bool m_f_running = false;
bool m_f_firstCall = false; // InitSequence for processWebstream and processLokalFile bool m_f_firstCall = false; // InitSequence for processWebstream and processLokalFile
bool m_f_firstM3U8call = false; // InitSequence for m3u8 parsing
bool m_f_chunked = false ; // Station provides chunked transfer bool m_f_chunked = false ; // Station provides chunked transfer
bool m_f_firstmetabyte = false; // True if first metabyte (counter) bool m_f_firstmetabyte = false; // True if first metabyte (counter)
bool m_f_playing = false; // valid mp3 stream recognized bool m_f_playing = false; // valid mp3 stream recognized
...@@ -527,6 +562,8 @@ private: ...@@ -527,6 +562,8 @@ private:
bool m_f_continue = false; // next m3u8 chunk is available bool m_f_continue = false; // next m3u8 chunk is available
bool m_f_ts = true; // transport stream bool m_f_ts = true; // transport stream
bool m_f_m4aID3dataAreRead = false; // has the m4a-ID3data already been read? bool m_f_m4aID3dataAreRead = false; // has the m4a-ID3data already been read?
bool m_f_psramFound = false; // set in constructor, result of psramInit()
bool m_f_timeout = false; //
uint8_t m_f_channelEnabled = 3; // internal DAC, both channels uint8_t m_f_channelEnabled = 3; // internal DAC, both channels
uint32_t m_audioFileDuration = 0; uint32_t m_audioFileDuration = 0;
float m_audioCurrentTime = 0; float m_audioCurrentTime = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment