10 #error Only supports ESP32
13 #ifndef AudioPlayer_h_
14 #define AudioPlayer_h_
15 #define FF_LFN_UNICODE 2
24 #include "WiFiClientSecure.h"
25 #include "driver/i2s.h"
72 size_t init(
size_t bufSize = 0);
100 typedef void (*
AudioSampleFilter)(
unsigned numBits,
unsigned numChannels,
const int16_t* samples,
unsigned sampleCount);
112 bool connecttohost(
const char* host,
const char* user =
"",
const char* pwd =
"");
144 bool setPinout(uint8_t BCLK, uint8_t LRC, uint8_t DOUT, int8_t DIN=I2S_PIN_NO_CHANGE);
158 inline uint32_t
streamavail() {
if(m_f_ssl==
false)
return client.available();
else return clientsecure.available();}
166 void setTone(uint8_t l_type = 0, uint16_t l_freq = 0, uint8_t r_type = 0, uint16_t r_freq = 0);
172 sampleFilter = filter;
178 void processNullStream();
179 void processLocalFile();
180 void processWebStream();
181 int sendBytes(uint8_t* data,
size_t len);
182 void compute_audioCurrentTime(
int bd);
183 void printDecodeError(
int r);
184 int readWaveHeader(uint8_t* data,
size_t len);
185 int readID3Metadata(uint8_t* data,
size_t len);
186 int readM4AContainer(uint8_t* data,
size_t len);
187 bool setSampleRate(uint32_t hz);
188 bool setBitsPerSample(
int bits);
189 bool setChannels(
int channels);
191 bool playSample(int16_t sample[2]) ;
192 bool playI2Sremains();
193 int32_t Gain(int16_t s[2]);
194 bool fill_InputBuf();
195 void showstreamtitle(
const char* ml);
196 void parsePlaylistData(
const char* pd);
197 void parseAudioHeader(
const char* ah);
198 bool parseContentType(
const char* ct);
199 void processControlData(uint8_t b);
200 esp_err_t I2Sstart(uint8_t i2s_num);
201 esp_err_t I2Sstop(uint8_t i2s_num);
202 String urlencode(String str);
203 int16_t* IIR_filterChain(int16_t iir_in[2],
bool clear =
false);
204 void IIR_calculateCoefficients();
207 bool startsWith (
const char* base,
const char* str) {
return (strstr(base, str) - base) == 0;}
208 bool endsWith (
const char* base,
const char* str) {
209 int blen = strlen(base);
210 int slen = strlen(str);
211 return (blen >= slen) && (0 == strcmp(base + blen - slen, str));
213 int indexOf (
const char* base,
const char* str,
int startIndex) {
215 int baselen = strlen(base);
216 if (strlen(str) > baselen || startIndex > baselen) result = -1;
218 char* pos = strstr(base + startIndex, str);
219 if (pos == NULL) result = -1;
220 else result = pos - base;
224 int specialIndexOf (uint8_t* base,
const char* str,
int baselen){
226 if (strlen(str) > baselen)
return -1;
227 for (
int i = 0; i < baselen - strlen(str); i++){
229 for (
int j = 0; j < strlen(str); j++){
230 if (*(base + i + j) != *(str + j)){
235 if (result >= 0)
break;
239 size_t bigEndian(uint8_t* base, uint8_t numBytes){
241 if(numBytes < 1 or numBytes > 4)
return 0;
242 for (
int i = 0; i < numBytes; i++) {
243 result += *(base + i) << (numBytes -i - 1) * 8;
248 virtual void audio_info(
const char *info) {}
249 virtual void audio_id3data(
const char *info) {}
250 virtual void audio_id3image(File& file,
const size_t pos,
const size_t size) {}
251 virtual void audio_eof_mp3(
const char *info) {}
252 virtual void audio_showstation(
const char *info) {}
253 virtual void audio_showstreamtitle(
const char *info) {}
254 virtual void audio_bitrate(
const char *info) {}
255 virtual void audio_commercial(
const char *info) {}
256 virtual void audio_icyurl(
const char *info) {}
257 virtual void audio_lasthost(
const char *info) {}
258 virtual void audio_eof_speech(
const char *info) {}
259 virtual void audio_eof_stream(
const char*) {}
262 enum :
int { APLL_AUTO = -1, APLL_ENABLE = 1, APLL_DISABLE = 0 };
263 enum :
int { EXTERNAL_I2S = 0, INTERNAL_DAC = 1, INTERNAL_PDM = 2 };
264 enum :
int { CODEC_NONE = 0, CODEC_WAV = 1, CODEC_MP3 = 2, CODEC_AAC = 4, CODEC_M4A = 5};
265 enum :
int { FORMAT_NONE = 0, FORMAT_M3U = 1, FORMAT_PLS = 2, FORMAT_ASX = 3};
266 enum :
int { AUDIO_NONE, AUDIO_HEADER , AUDIO_DATA, AUDIO_METADATA, AUDIO_PLAYLISTINIT,
267 AUDIO_PLAYLISTHEADER, AUDIO_PLAYLISTDATA, AUDIO_SWM };
268 typedef enum { LEFTCHANNEL=0, RIGHTCHANNEL=1 } SampleIndex;
270 const uint8_t volumetable[22]={ 0, 1, 2, 3, 4 , 6 , 8, 10, 12, 14, 17,
271 20, 23, 27, 30 ,34, 38, 43 ,48, 52, 58, 64};
273 typedef struct _filter{
283 WiFiClientSecure clientsecure;
284 i2s_config_t m_i2s_config;
285 i2s_pin_config_t m_pin_config;
292 char m_lastHost[256];
293 char m_audioName[256];
294 filter_t m_filter[2];
297 uint32_t m_sampleRate=16000;
299 uint32_t m_bitRate=0;
300 uint32_t m_avr_bitrate = 0;
303 int m_controlCounter = 0;
304 int8_t m_balance = 0;
305 uint8_t m_ID3version=0;
307 uint8_t m_bitsPerSample = 16;
308 uint8_t m_channels=2;
309 uint8_t m_i2s_num = I2S_NUM_0;
310 uint8_t m_playlistFormat = 0;
311 uint8_t m_codec = CODEC_NONE;
312 uint8_t m_filterType[2];
313 int16_t m_outBuff[2048*2];
314 int16_t m_validSamples = 0;
315 int16_t m_curSample = 0;
316 uint16_t m_st_remember = 0;
317 uint16_t m_datamode = 0;
318 uint32_t m_metaint = 0;
319 uint32_t m_totalcount = 0;
320 uint32_t m_chunkcount = 0 ;
322 uint32_t m_metaCount = 0;
323 uint32_t m_contentlength = 0;
324 uint32_t m_bytectr = 0;
325 uint32_t m_bytesNotDecoded = 0;
326 bool m_f_unsync =
false;
327 bool m_f_exthdr =
false;
328 bool m_f_localfile = false ;
329 bool m_f_webstream = false ;
330 bool m_f_nullstream = false ;
331 bool m_f_ssl =
false;
332 bool m_f_running =
false;
333 bool m_f_firststream_ready =
false;
334 bool m_f_ctseen =
false;
335 bool m_f_chunked = false ;
336 bool m_f_swm =
false;
337 bool m_f_firstmetabyte =
false;
338 bool m_f_stream =
false;
339 bool m_f_playing =
false;
340 bool m_f_webfile=
false;
341 bool m_f_psram =
false;
342 bool m_f_loop =
false;
343 bool m_f_forceMono =
false;
344 bool m_f_internalDAC =
false;
345 uint32_t m_audioFileDuration = 0;
346 float m_audioCurrentTime = 0;
347 float m_filterBuff[2][2][2];
348 size_t m_i2s_bytesWritten = 0;
349 size_t m_loop_point = 0;
350 size_t m_file_size = 0;
351 uint16_t m_filterFrequency[2];