earlephilhower / ESP8266Audio

Arduino library to play MOD, WAV, FLAC, MIDI, RTTTL, MP3, and AAC files on I2S DACs or with a software emulated delta-sigma DAC on the ESP8266 and ESP32
GNU General Public License v3.0
2.01k stars 432 forks source link

Decoding error 0x0235 (bad main_data_begin pointer) at byte offset #9

Closed gerardwr closed 6 years ago

gerardwr commented 6 years ago

This looks like an excellent library to stream internet-radio.

The StreamMP3FromHTTP sketch compiles (Arduino 1.8.1 and ESP8266 2.3.0), but with dozens of "red" warnings.

Upload to a Wemos D1 Mini (160Mhz)results in the errors below.

Any suggestions what to do?

�:�������a�����aV������qEc��S�aEc�i...Connecting to WiFi
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 0
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 418
Decoding error 0x0101 (lost synchronization) at byte offset 57774
Decoding error 0x0104 (reserved sample frequency value) at byte offset 58011
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 58097
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 58515
Decoding error 0x0101 (lost synchronization) at byte offset 108874
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 109088
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 109506
Decoding error 0x0101 (lost synchronization) at byte offset 161434
Decoding error 0x0101 (lost synchronization) at byte offset 161467
Decoding error 0x0104 (reserved sample frequency value) at byte offset 161647
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 161751
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 162169
Decoding error 0x0101 (lost synchronization) at byte offset 209614
Decoding error 0x0104 (reserved sample frequency value) at byte offset 209700
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 209816
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 210234
Decoding error 0x0101 (lost synchronization) at byte offset 298674
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 298841
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 299259
Decoding error 0x0101 (lost synchronization) at byte offset 336215
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 336875
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 337293
Decoding error 0x0101 (lost synchronization) at byte offset 380434
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 380761
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 381179
Decoding error 0x0101 (lost synchronization) at byte offset 422774
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 422975
Decoding error 0x0101 (lost synchronization) at byte offset 440918
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 441783
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 442201
Decoding error 0x0101 (lost synchronization) at byte offset 638854
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 639060
earlephilhower commented 6 years ago

Howdy,

Can you please post those warnings you're getting? I compile with -Wall and don't get anything in the Audio library (but I do see stuff in SPIFFS and the main ESP arduino libs which I can't touch)...

It looks like things are working fine, you're just losing packets somewhere. The decoder is resyncing and continuing to play from what I can see.

Have you tried adding a buffer between the HTTPStream and the Generator? The README.md shows a simple example...as long as you have memory it's literally a 1-2 line change.

Here's all I get on a clean compile w/-Wall using the latest Arduino and ESP8266Audio Git:

/home/earle/Arduino/libraries/ESP8266Audio/src/AudioGeneratorAAC.cpp: In member function 'virtual bool AudioGeneratorAAC::loop()':
/home/earle/Arduino/libraries/ESP8266Audio/src/AudioGeneratorAAC.cpp:108:69: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     if (ret = AACDecode(hAACDecoder, &inBuff, &bytesLeft, outSample)) {
                                                                     ^
/home/earle/Arduino/libraries/ESP8266Audio/src/AudioGeneratorAAC.cpp:115:29: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       if (fi.sampRateOut != lastRate) {
                             ^
/home/earle/Arduino/libraries/ESP8266Audio/src/libhelix-aac/dequant.c: In function 'raac_DeinterleaveShortBlocks':
/home/earle/Arduino/libraries/ESP8266Audio/src/libhelix-aac/dequant.c:367:41: warning: unused parameter 'aacDecInfo' [-Wunused-parameter]
 int DeinterleaveShortBlocks(AACDecInfo *aacDecInfo, int ch)
                                         ^
/home/earle/Arduino/libraries/ESP8266Audio/src/libhelix-aac/dequant.c:367:57: warning: unused parameter 'ch' [-Wunused-parameter]
 int DeinterleaveShortBlocks(AACDecInfo *aacDecInfo, int ch)
earlephilhower commented 6 years ago

And, as I felt bad having them hanging around, I just cleared up those 4 warnings with the latest push. No functional changes, just stuff to make GCC happy.

gerardwr commented 6 years ago

Thanks for your response, is appreciated!

The warnings in your post LOOK similar to mine, but I will check in detail later today, and report back. AND I will check the version with the 4 warnings cleared, nice work!

And NO, i didn't try adding a buffer yet, just added my SSID and compiled the standard example sketch.

My turn again, I will report back later. Thx.

gerardwr commented 6 years ago

These are my warnings with the latest Arduino-ESP8266 GIT and with the former ESP8266Audio GIT:

/Users/gerard/Documents/My Data/ArduinoESP/libraries/ESP8266Audio/src/AudioGeneratorAAC.cpp: In member function 'virtual bool AudioGeneratorAAC::loop()':
/Users/gerard/Documents/My Data/ArduinoESP/libraries/ESP8266Audio/src/AudioGeneratorAAC.cpp:108:69: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     if (ret = AACDecode(hAACDecoder, &inBuff, &bytesLeft, outSample)) {
                                                                     ^
/Users/gerard/Documents/My Data/ArduinoESP/libraries/ESP8266Audio/src/AudioGeneratorAAC.cpp:115:29: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       if (fi.sampRateOut != lastRate) {
                             ^
/Users/gerard/Documents/My Data/ArduinoESP/libraries/ESP8266Audio/src/libhelix-aac/dequant.c: In function 'raac_DeinterleaveShortBlocks':
/Users/gerard/Documents/My Data/ArduinoESP/libraries/ESP8266Audio/src/libhelix-aac/dequant.c:367:41: warning: unused parameter 'aacDecInfo' [-Wunused-parameter]
 int DeinterleaveShortBlocks(AACDecInfo *aacDecInfo, int ch)
                                         ^
/Users/gerard/Documents/My Data/ArduinoESP/libraries/ESP8266Audio/src/libhelix-aac/dequant.c:367:57: warning: unused parameter 'ch' [-Wunused-parameter]
 int DeinterleaveShortBlocks(AACDecInfo *aacDecInfo, int ch)
                                                         ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp:45:18: warning: unused parameter 'client' [-Wunused-parameter]
     virtual bool verify(WiFiClient& client, const char* host)
                  ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp:45:18: warning: unused parameter 'host' [-Wunused-parameter]
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/SD.cpp:233:9: warning: unused parameter 'isLastComponent' [-Wunused-parameter]
 boolean callback_pathExists(SdFile& parentDir, char *filePathComponent, 
         ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/SD.cpp:233:9: warning: unused parameter 'object' [-Wunused-parameter]
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/SD.cpp:311:9: warning: unused parameter 'object' [-Wunused-parameter]
 boolean callback_remove(SdFile& parentDir, char *filePathComponent, 
         ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/SD.cpp:319:9: warning: unused parameter 'object' [-Wunused-parameter]
 boolean callback_rmdir(SdFile& parentDir, char *filePathComponent, 
         ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/Sd2Card.cpp: In member function 'uint8_t Sd2Card::readData(uint32_t, uint16_t, uint16_t, uint8_t*)':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/Sd2Card.cpp:396:12: warning: unused variable 'n' [-Wunused-variable]
   uint16_t n;

            ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/SdFile.cpp: In static member function 'static uint8_t SdFile::make83Name(const char*, uint8_t*)':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/SdFile.cpp:262:15: warning: unused variable 'b' [-Wunused-variable]
       uint8_t b;

               ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/SdFile.cpp: In member function 'uint8_t SdFile::rmRfStar()':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/SdFile.cpp:908:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if (curPosition_ != (32*(index + 1))) {

                                        ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs_hydrogen.c: In function 'SPIFFS_buffer_bytes_for_filedescs':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs_hydrogen.c:16:49: warning: unused parameter 'fs' [-Wunused-parameter]
 u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) {
                                                 ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp: In member function 'bool EspClass::eraseConfig()':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp:399:10: warning: unused variable 'ret' [-Wunused-variable]
     bool ret = true;
          ^
Archiving built core (caching) in: /var/folders/5l/fjrz26dn5710yvf5hgzlcvsw0000gn/T/arduino_cache_825551/core/core_esp8266com_esp8266_d1_mini_CpuFrequency_160,FlashSize_4M3M,LwIPVariant_open,Debug_Disabled,DebugLevel_None____,UploadSpeed_230400_0a1796809b00622e6557403083020d45.a
De schets gebruikt 397437 bytes (38%)  programma-opslagruimte. Maximum is 1044464 bytes.
Globale variabelen gebruiken 35924 bytes (43%) van het dynamisch geheugen. Resteren 45996 bytes voor lokale variabelen. Maximum is 81920 bytes.
Uploading 401584 bytes from /var/folders/5l/fjrz26dn5710yvf5hgzlcvsw0000gn/T/arduino_build_926479/StreamMP3FromHTTP.ino.bin to flash at 0x00000000
................................................................................ [ 20% ]
................................................................................ [ 40% ]
................................................................................ [ 61% ]
................................................................................ [ 81% ]
.........................................................................        [ 100% ]
gerardwr commented 6 years ago

These are my warnings with the latest Arduino-ESP8266 GIT and with your latest ESP8266Audio GIT:

/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp:45:18: warning: unused parameter 'client' [-Wunused-parameter]
     virtual bool verify(WiFiClient& client, const char* host)
                  ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp:45:18: warning: unused parameter 'host' [-Wunused-parameter]
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/SD.cpp:233:9: warning: unused parameter 'isLastComponent' [-Wunused-parameter]
 boolean callback_pathExists(SdFile& parentDir, char *filePathComponent, 
         ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/SD.cpp:233:9: warning: unused parameter 'object' [-Wunused-parameter]
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/SD.cpp:311:9: warning: unused parameter 'object' [-Wunused-parameter]
 boolean callback_remove(SdFile& parentDir, char *filePathComponent, 
         ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/SD.cpp:319:9: warning: unused parameter 'object' [-Wunused-parameter]
 boolean callback_rmdir(SdFile& parentDir, char *filePathComponent, 
         ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/Sd2Card.cpp: In member function 'uint8_t Sd2Card::readData(uint32_t, uint16_t, uint16_t, uint8_t*)':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/Sd2Card.cpp:396:12: warning: unused variable 'n' [-Wunused-variable]
   uint16_t n;

            ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/SdFile.cpp: In static member function 'static uint8_t SdFile::make83Name(const char*, uint8_t*)':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/SdFile.cpp:262:15: warning: unused variable 'b' [-Wunused-variable]
       uint8_t b;

               ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/SdFile.cpp: In member function 'uint8_t SdFile::rmRfStar()':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/libraries/SD/src/utility/SdFile.cpp:908:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if (curPosition_ != (32*(index + 1))) {

                                        ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs_hydrogen.c: In function 'SPIFFS_buffer_bytes_for_filedescs':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs_hydrogen.c:16:49: warning: unused parameter 'fs' [-Wunused-parameter]
 u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) {
                                                 ^
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp: In member function 'bool EspClass::eraseConfig()':
/Users/gerard/Documents/My Data/ArduinoESP/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp:399:10: warning: unused variable 'ret' [-Wunused-variable]
     bool ret = true;
          ^
Archiving built core (caching) in: /var/folders/5l/fjrz26dn5710yvf5hgzlcvsw0000gn/T/arduino_cache_604903/core/core_esp8266com_esp8266_d1_mini_CpuFrequency_160,FlashSize_4M3M,LwIPVariant_open,Debug_Disabled,DebugLevel_None____,UploadSpeed_230400_0a1796809b00622e6557403083020d45.a
De schets gebruikt 397437 bytes (38%)  programma-opslagruimte. Maximum is 1044464 bytes.
Globale variabelen gebruiken 35924 bytes (43%) van het dynamisch geheugen. Resteren 45996 bytes voor lokale variabelen. Maximum is 81920 bytes.
Uploading 401584 bytes from /var/folders/5l/fjrz26dn5710yvf5hgzlcvsw0000gn/T/arduino_build_570333/StreamMP3FromHTTP.ino.bin to flash at 0x00000000
................................................................................ [ 20% ]
................................................................................ [ 40% ]
................................................................................ [ 61% ]
................................................................................ [ 81% ]
.........................................................................        [ 100% ]
gerardwr commented 6 years ago

Now running StreamMP3fromHTTP sketch from the latest GIT:

Is this the behaviour you expect from the sketch?

...Connecting to WiFi
...Connecting to WiFi
...Connecting to WiFi
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 0
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 418
Decoding error 0x0101 (lost synchronization) at byte offset 2054
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 2090
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 2508
Decoding error 0x0101 (lost synchronization) at byte offset 15453
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 15464
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 15882
Decoding error 0x0101 (lost synchronization) at byte offset 30462
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 30511
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 30929
Decoding error 0x0101 (lost synchronization) at byte offset 43862
.
<many more similar lines with increasing byte offset value
.
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 844695
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 845113
Decoding error 0x0101 (lost synchronization) at byte offset 858046
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 858070
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 858488
Decoding error 0x0101 (lost synchronization) at byte offset 873054
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 873117
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 873535
Decoding error 0x0101 (lost synchronization) at byte offset 886453
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 886491
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 886909
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
.
<unending MP3 done lines>
.
gerardwr commented 6 years ago

Now tested the example in the README.MD playing the stream from http://mp3radio.com/playback" with the extra buffer.

After uploading/resetting the ESP8266 the "MP3 done" starts immediately without the former "Decoding error" lines.

Looks like SUCCESS to me!! Now searching for a working earpiece ;-)

sll⸮⸮|⸮l⸮|⸮l⸮c|⸮⸮⸮⸮{⸮c⸮c⸮⸮oo⸮loo⸮⸮⸮cp⸮lsl{lp⸮o⸮⸮d⸮⸮co⸮|d⸮⸮c⸮⸮oo⸮d⸮⸮d`⸮nnd`o{⸮⸮⸮oc⸮l{⸮⸮oc⸮l⸮⸮⸮⸮⸮⸮⸮⸮⸮`⸮⸮o⸮⸮MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
<etcetera>
earlephilhower commented 6 years ago

All those warnings you've got on the latest GIT are in the main Arduino code, not the audio portion. They're harmless, but I'm sure igrr wouldn't mind a PR if you want to fix them.

As to the "MP3 done," that actually means the MP3 is..err...done, and not playing any more. So the socket got closed, the file was completed, etc.

The example http address in the readme isn't a real URL. I thought it was obvious, but I guess not. You'll need to replace that with a real MP3 stream URL to run it.

One other possibility is that the errors are related to things like ICY tags or ID3 or other form of station identification.

gerardwr commented 6 years ago

Understand. For testing the sketch in the README I used the URL "http://streaming.shoutcast.com/80sPlanet?lang=en-US" used in the StreamMp3FromHttp example sketch.

Tried this URL in a browser windows and the stream plays, si I assume it's OK for testing the sketch.

But I still get every second the "Mp3 done" message. Now I know this indicates that no sound is played.

Will do some more testing tomorrow.

Thanks for your support so far in tackling my issues!

gerardwr commented 6 years ago

Started again to do some testing to get this beauty working, sorry to bother you, again.

TEST 1

As "baseline" I uploaded example sketch PlayWavFromProgmem. Works perfectly, violin sounds through speaker system connected to RX :-)

TEST 2

Uploaded HTTP stream example from README, using the valid URL from the StreamMp3FromHTTP example. Result:

The sketch contains this line in Setup:

  WiFi.forceSleepBegin();

I think this disables Wifi alltogether, and that would mean that playing the stream is impossible. I would say this sketch cannot work "as is", or am I mistaken?

TEST 3

Uploaded StreamMP3FromHTTP example, URL="http://streaming.shoutcast.com/80sPlanet?lang=en-US". Result: 1 - ESP connects OK to router (gets IP) 2 - Serial monitor displays 3 lines "Decoding error" 3 - plays appr. 1 second good quality sound from the stream 4 - appr. 1 second silence Steps 2,3 and 4 repeated until "Mp3 done".

This is the serial monitor output, some further suggestions, maybe, I'm getting banana's here!

 1384, room 16 
tail 8
chksum ...Connecting to WiFi
...Connecting to WiFi
...Connecting to WiFi
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 0
Decoding error 0x0101 (lost synchronization) at byte offset 2054
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 2090
Decoding error 0x0101 (lost synchronization) at byte offset 15453
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 15464
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 15882
Decoding error 0x0101 (lost synchronization) at byte offset 30462
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 30511
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 30929
Decoding error 0x0101 (lost synchronization) at byte offset 43862
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 43886
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 44303

<many similar lines deleted>

Decoding error 0x0101 (lost synchronization) at byte offset 802837
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 802899
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 803317
Decoding error 0x0101 (lost synchronization) at byte offset 816238
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 816274
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 816692
Decoding error 0x0101 (lost synchronization) at byte offset 829638
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 829649
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 830067
Decoding error 0x0101 (lost synchronization) at byte offset 844645
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 844695
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 845113
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
MP3 done
earlephilhower commented 6 years ago

Yup, the README.md example was just intended to show how to add the buffer. That's what I get for cutting-and-pasting code in a text file and expecting it to work

I'll delete it, you should start w/the Stream example and add the buffer instead.

Try a different webserver, or your own sitting on your own network to start. I just picked the first working URL I could find for the example as I don't do any web streaming myself. Looks like you're having bad packet loss between your ESP and that streamcast server...

gerardwr commented 6 years ago

Glad to help, grin!

As said before the stream example (without buffer) "works" alternating good sound with silences. Just tried adding a buffer but that seemed to make things even worse.

Also tried another URL (in my home country), but to no avail.

Spent (to) many hours today, so I'll call it quits for now. Tomorrow is another day :-)

Would be really pleased to get this working. I would love to have a couple of streaming ESP's.

Thx.

earlephilhower commented 6 years ago

So it turns out that @armSeb, who's been doing lots of work with me recently, found a bug overnight in the buffer routine which would cause certain reads to return invalid data. You should do a pull of the updated repo and see if it changes things for you.

gerardwr commented 6 years ago

Yep, it changes things dramatically!

First pulled the updated repo and uploaded the example sketch StreamMP3FromHTTP (no buffer). Behaviour was similar as before with repeating "Decoding error" messages and eventually 1-sec repeating "Mp3 done" messages.

Then added a buffer to the sketch. Sound plays with a disturbing hickup of 50Herz or so, but it plays continually, NO "Decoding error" and NO "MP3 done" messages anymore.

Not sure where the 50?Herz hickup is coming from, but it is quite disturbing. But it is dramatic progress for me, it shows that my environment is more or less OK.

Will do some more testing later.

Good show!

armSeb commented 6 years ago

Hello,

What is the MP3 bitrate ?

gerardwr commented 6 years ago

For testing I used this URL, but I have no clue what the bitrate is, sorry: http://icecast.omroep.nl/radio1-bb-mp3

gerardwr commented 6 years ago

For fun I just tried the default URL in the sketch: http://streaming.shoutcast.com/80sPlanet?lang=en-US

Wow, NO 50?Hz hickups with this stream, perfect sound !!!!!! Just a "crackle" now and then.

Also no idea what the bitrate for this stream is :-(

armSeb commented 6 years ago

It's 192kbit/s 48000 Hz.

Please try with 44100Hz streaming ;)

And for buffer, you can try 4096 or 8192 bytes.

earlephilhower commented 6 years ago

Great feedback on the example. I've just added buffering to the sample code so it's obvious to new users how to do it.

gerardwr commented 6 years ago

@earlephilhower : Glad that I could give something back to you guys!

gerardwr commented 6 years ago

@armSeb : Now that I know that bitrate is an issue I investigated the bitrate of the tested streams (opened stream in iTunes and showed INFO).

These are the streams and results I tested so far (note : loooong lines, scrolling required):

// const char *URL="http://streaming.shoutcast.com/80sPlanet?lang=en-US"; // 80sPlanet radio, 128kbps 44.1 kHz : works, only occasional a hickup
// const char *URL="http://icecast.omroep.nl/radio1-bb-mp3";              // Dutch Radio 1, 128kbps 48.0 kHz : works with a 50Hz hickup hickups (mayne hight mp3 bitrate)
// const char *URL="http://91.221.151.155:80/;?.mp3";                     // Arrow Classick Rock, 128kbps 44.1 kHz : works, only occasional a hickup

The 44.1kHz@128kbps work satisfactory, the 48kHz@128kbps stream has severe hickups.

Increasing the buffer to 4096 : I THINK the number of small hickups decreased, but it may be wishfull thinking. Increasing the buffer to 8192 : This resulted in many hickups and standstills. May be a coincidence, no scientific testing done :-)

Will do some more testing when I'm alone in the house, so not to bother them with the crackles and hickups :-)

earlephilhower commented 6 years ago

I think the issue is that at 48KHz the audio output portion that copies to I2S isn't being called often enough due to WiFi and other background ops taking time.

The ESP8266 can decode samples at >> 48KHz with no problem, probably even @ 80MHz, but there's a minuscule I2S buffer of only 11ms @ 44KHz, which is <10ms @48KHz. Even if you've got 20ms of data decoded and ready to go, only what fits in the I2S buffer will be used if there's a delay somewhere in the whole system.

I've put in a PR to let a user app override this default, https://github.com/esp8266/Arduino/pull/3790 , but it's obviously a low priority for them as they're releasing a new version soon and cleaning up existing features. The change is easy and you could hand-apply it if you're running the GIT head simply enough and set a larger buffer count.

Are you using an I2S DAC or the SW one? If it's the SW one you are using more CPU (~10 more insns/sample) than the HW DAC, so that makes it even harder to hit 48KHz...

One simple, if unappealing, way to work around this is to introduce a subsampler. It's not rocket science to downsample from 48KHz->44.1KHz if you don't care too much about noise floors, and then you gain an extra 1ms or 2 of time to play around in background tasks.

gerardwr commented 6 years ago

@earlephilhower : Thanks for enlightening me re. the 48kHz issue. The fact is that I just happened to test using a stream that was MP3 @ 48kHz. The stream I'm mostly interested is an AAC stream @128kbps.

From your explanation I gues the small I2S is the major bottleneck. I read the PR and I think I can manage changing it to a larger buffer count. Before I'll go that route I'll refrain myself to getting "the best quality sound" using the current default.

I'm currently using the SW DAC, one challenge at a time, right ;-) I understand this "wastes" some extra CPU power compared to an I2S DAC.

So for now, I'll focus on getting the AAC @128kbps as good as possible. Then I'll know what imperfection I will have to deal with.

Many thanks for the inspiration.

gerardwr commented 6 years ago

@armSeb : did some more tests with different buffer sizes: 2048 works 4096 works (a bit better, less hickups) 8192 does not work at all (MP3 done) or dramatic hickups Possibly setting the buffer to 8192 consumer all RAM?

armSeb commented 6 years ago

8192 works for me, but I think the best compromise is 4096. You need free heap to be able to decode mp3 (and AAC) correctly.

I received my SPI RAM chip, I need some time to plug it an begin the tests. If I can use it, this will bring 128kbytes of buffer, without eating the main RAM.

gerardwr commented 6 years ago

@armSeb : Not sure why 8192 fails for me, but for now I'll stick with 4096.

Adding extra RAM will certainly help. Too bad that it adds an extra component, the fact that it runs on "just" a basic ESP8266 with a speaker is magic.

armSeb commented 6 years ago

Yeah but with a real DAC you really get a nice stereo sound :)

gerardwr commented 6 years ago

Stereo, hickups from 2 sides ;-)

Seriously, a DAC is certainly worth the couple of $$.

armSeb commented 6 years ago

Really ?

I bought this one : https://www.ebay.com/itm/PCM5102A-DAC-Decoder-I2S-32bit-Player-Module-Beyond-ES9023-PCM1794-Raspberry-Pi/331976578784

Without DAC you already have to decode stereo mp3, then converted to mono.

gerardwr commented 6 years ago

I believe a saw an even cheaper one on Aliexpress, but can't find it right now. If I do find it again , I'll let you know.

So the SW DAC wastes CPU cycles?, had no idea.

I am more of a SW guy myself, but I guess there's no way avoiding a hardware DAC :-(

Signing off for tonite.

armSeb commented 6 years ago

SW DAC has to convert the samples to delta sigma. It's a hack that works but not for daily use. But if you can optimize a lot more the SW DAC code you will get a better quality, but only in mono. The output filter is important to eliminate the high freq harmonics, to avoid noise.

armSeb commented 6 years ago

So, I guess the next step is to add some inline ASM with xtensa specific instructions to optimize a lot more the decoder and audio output, with pre-processing instructions to keep compability with other architectures.

earlephilhower commented 6 years ago

8K won't work reliably due to memory limitations. Depending on when/what the WiFi does you'll hit OOM randomly. You start w/~40KB with the Hello World app in Arduino, and it goes down from there, very fast.

Without profiling, I would not assume that the SW DAC is eating an appreciable amount of time compared to other bits.

For the SW DAC, the generated assembly isn't too bad. I'm not sure you're going to do much better by hand. The whole SPI progam ROM+ IROM cache may actually slow you down more than the code. It's possible to do a table-lookup and convert 2-4 bits at a time instead of just 1, but it gets complicated very fast and the table explodes which means ICACHE misses which means it'll be way slower than the calculated code (40MHz SPI takes ages to load a $-line).

As for quality, if the I2S can go fast enough you can go to x64 or x128 oversampling. It already works and is a class method. :) This, however, reduces the effective time the I2S buffers last for by 2x or 4x...leading to hiccups during IP stuff.

LIBMAD has provisions for using assembly in the inner loops, however the Xtensa core that ESPRESSIF bought doesn't have the proper type of signed multiply instruction hardware. You're not going to make MP3 much faster is my thinking. I spent way too much time learning GCC ASM syntax only to find they'd not built that bit into the HW.

AAC has the possibility, and they definitely did use some targeted asm in the ARM port I looked at, but it was actually used mostly because the ARM was the wrong endinaness compared to the file...

l built a FIR filter and decimation engine so you can lowpass the 48khz and send it out at 44.1khz (or any other FIR and rate change you want), but that doesn't seem to be the problem. There's some sort of buffering/IP issue when listening to that stream and it's not related to the I2S output.

You can adjust the buffering in the MP3 decoder and the external buffer and try and you'll see that it decodes the first bit fine when you do, but then after a while (when the RAM buffering of the IP data is exhausted) starts the 20Hz silences/ticks.

  buff = new AudioFileSourceBuffer(file, 3000);
  ...
  mp3 = new AudioGeneratorMP3();
  mp3->SetBufferSize(1000);
  mp3->begin(buff, out);

Could be related to the stream encoded BW more than the I2S is my thinking. Maybe hitting the ESP's TCP processing limit?

Oh, and listening to Dutch talk radio is very disconcerting for an American English speaker. Like I should be able to understand them due to the common roots, but enough differences to make it unintelligible to me.

gerardwr commented 6 years ago

@armSeb

Have been searching for the "few dollars DAC" but didn't find it. I then remembered I saw an amplifier board with an I2S input. It's more expensive as the DAC you found on Ebay, appr. $10, but the board also contains an few-Watt mono amplifier.

https://learn.adafruit.com/adafruit-max98357-i2s-class-d-mono-amp/overview

https://www.aliexpress.com/item/1-pcs-x-Amplifier-IC-Development-Tools-I2S-3W-Class-D-Amp-Breakout-MAX98357A/32841736609.html?spm=2114.search0104.3.16.HaF9rJ&ws_ab_test=searchweb0_0,searchweb201602_5_10152_10065_10151_10344_10068_10345_10342_10343_10340_10341_10541_10562_10084_10083_10304_10307_10301_10177_10060_10155_10154_10539_10312_10059_10313_10314_10534_10533_100031_10103_10073_10594_10557_10596_10595_10142_10107,searchweb201603_25,ppcSwitch_5&btsid=ee474da4-0220-48f8-b61f-537d7a35c21b&algo_expid=9f65e9cf-564b-4e24-85c0-e2565a4a23d1-2&algo_pvid=9f65e9cf-564b-4e24-85c0-e2565a4a23d1&rmStoreLevelAB=0

armSeb commented 6 years ago

You can get an analog stereo class d amplifier, which you can plug to the DAC with a potentiometer. The dac itself is enough to drive a little earpiece/earphones.

armSeb commented 6 years ago

@gerardwr My opinion is that the SW DAC is a proof of concept. The most important is to fine tune the rest, the goal is to make a really usable device with a real DAC.

earlephilhower commented 6 years ago

@gerardwr, try pulling the latest repo. @armSeb found a case where on slower streams the buffer would never refill and you'd be stuck w/micro-stutter. His suggestion was to just take the hit and do 1 bigger stutter and refill in that case, and that's just been committed. I was able to listen to a Dutch report about Mugabe resigning w/o hiccups on that 48KHz URL w/o stuttering except when the Buffering... appeared (because the stream fell behind the audio out).

gerardwr commented 6 years ago

@earlephilhower : Excellent, will do that later today and report back.

I have to do my best to keep up with the responses from you and @armSeb , so much to do, so little time ;-)

In the meantime you can continue practicing your Dutch skills, I fully missed Mugabe resigning. Must have been a hickup in the stream ;-)

gerardwr commented 6 years ago

@earlephilhower : Installed the latest repo, but unfortunately all of my test streams (48 and 44 kHz) now displays "Buffering..'" appr. every second in the serial monitor with the related hickups.

Not sure what is happening, but for me this is a step back.

Will do some further testing later to make sure that my test results are reliable.

BTW : I'm on a rather slow 40 Mbits/s WAN connection, but assume the ESP wifi is the bottleneck anyway.

gerardwr commented 6 years ago

@earlephilhower : 1 addition to my previous remark.

With the latest repo the stream continues to play indefinitely, while the previous repo often ended after a while with "MP3 done" (Tested with a 4096 buffer).

So, that's an important positive change!

armSeb commented 6 years ago

For me it works like a charm, I have an ADSL connection @13Mbit/s, and many people using wifi around me.

gerardwr commented 6 years ago

After the troubles with the continuously "buffering" of my MP3 streams I tried this AAC stream with the latest repo: "http://stream.morow.com:8080/morow_med.aacp"

Much better.

No "buffering"/hickups (maybe 1 every few minutes) , occasionally a 1 sec whistling/hissing tone in the output, that's quite disturbing.

Stay tuned.

gerardwr commented 6 years ago

Not sure what I'm fighting here.

I tested the Morow Radio stream, that's available both as MP3 stream and AAC stream. http://stream.morow.com:8080/morow_med.aacp http://stream.morow.com:8000/morow.mp3

I created the AAC sketch adapting the StreamMp3FromHTTP (both with a 4096 buffer).

The AAC stream plays continuously with a disturbing "whistling hiss" now and then (maybe every 20 secs?) but otherwise quality is OK.

The MP3 stream pauses appr. every second while displaying "Buffering", and sounds awfull.

Both stream play fine in my browser.

Need a drink!

armSeb commented 6 years ago

@gerardwr Your MP3 stream plays fine :)

Can you try to ping your ESP from computer ?

I just soldered my SPI RAM chip, the big job will be to create a class to use it as buffer (as described here: https://github.com/espressif/ESP8266_MP3_DECODER)

gerardwr commented 6 years ago

@armSeb : Thank for confirming the MP3 stream playing OK for you. Must be somethig weard over here.

Ping not quite stable (understatement)

64 bytes from 192.168.0.41: icmp_seq=0 ttl=255 time=4.380 ms
64 bytes from 192.168.0.41: icmp_seq=1 ttl=255 time=0.977 ms
64 bytes from 192.168.0.41: icmp_seq=2 ttl=255 time=1.117 ms
64 bytes from 192.168.0.41: icmp_seq=3 ttl=255 time=8.662 ms
64 bytes from 192.168.0.41: icmp_seq=4 ttl=255 time=0.848 ms
64 bytes from 192.168.0.41: icmp_seq=5 ttl=255 time=0.904 ms
64 bytes from 192.168.0.41: icmp_seq=6 ttl=255 time=99.734 ms
64 bytes from 192.168.0.41: icmp_seq=7 ttl=255 time=0.869 ms
64 bytes from 192.168.0.41: icmp_seq=8 ttl=255 time=0.940 ms
64 bytes from 192.168.0.41: icmp_seq=9 ttl=255 time=5.031 ms
64 bytes from 192.168.0.41: icmp_seq=10 ttl=255 time=97.047 ms
64 bytes from 192.168.0.41: icmp_seq=11 ttl=255 time=7.243 ms
64 bytes from 192.168.0.41: icmp_seq=12 ttl=255 time=0.920 ms
64 bytes from 192.168.0.41: icmp_seq=13 ttl=255 time=0.959 ms
64 bytes from 192.168.0.41: icmp_seq=14 ttl=255 time=67.528 ms
64 bytes from 192.168.0.41: icmp_seq=15 ttl=255 time=11.874 ms
64 bytes from 192.168.0.41: icmp_seq=16 ttl=255 time=0.828 ms
64 bytes from 192.168.0.41: icmp_seq=17 ttl=255 time=0.861 ms
64 bytes from 192.168.0.41: icmp_seq=18 ttl=255 time=85.606 ms
64 bytes from 192.168.0.41: icmp_seq=19 ttl=255 time=1.197 ms
64 bytes from 192.168.0.41: icmp_seq=20 ttl=255 time=0.827 ms
64 bytes from 192.168.0.41: icmp_seq=21 ttl=255 time=101.695 ms
64 bytes from 192.168.0.41: icmp_seq=22 ttl=255 time=2.692 ms
64 bytes from 192.168.0.41: icmp_seq=23 ttl=255 time=0.913 ms
armSeb commented 6 years ago

Mine is more stable:

64 bytes from 192.168.1.2: icmp_seq=0 ttl=128 time=72.497 ms
64 bytes from 192.168.1.2: icmp_seq=1 ttl=128 time=4.317 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=128 time=3.169 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=128 time=10.710 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=128 time=31.852 ms
64 bytes from 192.168.1.2: icmp_seq=5 ttl=128 time=5.967 ms
64 bytes from 192.168.1.2: icmp_seq=6 ttl=128 time=10.196 ms
64 bytes from 192.168.1.2: icmp_seq=7 ttl=128 time=22.208 ms
64 bytes from 192.168.1.2: icmp_seq=8 ttl=128 time=10.469 ms
64 bytes from 192.168.1.2: icmp_seq=9 ttl=128 time=5.658 ms
64 bytes from 192.168.1.2: icmp_seq=10 ttl=128 time=5.760 ms
64 bytes from 192.168.1.2: icmp_seq=11 ttl=128 time=6.304 ms
64 bytes from 192.168.1.2: icmp_seq=12 ttl=128 time=15.903 ms
64 bytes from 192.168.1.2: icmp_seq=13 ttl=128 time=11.712 ms
64 bytes from 192.168.1.2: icmp_seq=14 ttl=128 time=2.975 ms
64 bytes from 192.168.1.2: icmp_seq=15 ttl=128 time=21.010 ms
64 bytes from 192.168.1.2: icmp_seq=16 ttl=128 time=8.289 ms
64 bytes from 192.168.1.2: icmp_seq=17 ttl=128 time=12.555 ms
64 bytes from 192.168.1.2: icmp_seq=18 ttl=128 time=4.964 ms
64 bytes from 192.168.1.2: icmp_seq=19 ttl=128 time=8.784 ms
64 bytes from 192.168.1.2: icmp_seq=20 ttl=128 time=35.620 ms
64 bytes from 192.168.1.2: icmp_seq=21 ttl=128 time=20.904 ms
64 bytes from 192.168.1.2: icmp_seq=22 ttl=128 time=23.099 ms
gerardwr commented 6 years ago

Switched to another ESP8266 module, slightly better, but MP3 hickups remain :-(

Possibly my streaming experiments result in a network overhaul :-(

armSeb commented 6 years ago

Try to share a mp3 file (for example with python -m SimpleHTTPServer) on your LAN, to spot the issue (Wifi or WAN issue)

Your streams plays very nicely, with very good sound, and no hiccups.

Can you try without the buffer ?

gerardwr commented 6 years ago

As said before in this (now ) looooong topic, the only stream I use on a daily basis is the Morow Radio stream. The fact that it plays "very nicely" on your ESP keeps me motivated.

Your support and from @earlephilhower is greatly appreciated.

Wow, neat trick with the local server, would have never thought of this!

...Connecting to WiFi
...Connecting to WiFi
...Connecting to WiFi
Buffering...
Decoding error 0x0101 (lost synchronization) at byte offset 0
Buffering...
Buffering...
Buffering...

Tried sketch without buffer, result sounds similar as with buffers (hickup every second, followed by "Decoding error"

...Connecting to WiFi
...Connecting to WiFi
Decoding error 0x0101 (lost synchronization) at byte offset 0
Decoding error 0x0101 (lost synchronization) at byte offset 11790
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 11809
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 12227
Decoding error 0x0101 (lost synchronization) at byte offset 30551
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 30618
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 31036
Decoding error 0x0101 (lost synchronization) at byte offset 49311
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 49426
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 49844
Decoding error 0x0101 (lost synchronization) at byte offset 68071
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 68234
Decoding error 0x0235 (bad main_data_begin pointer) at byte offset 68652

I'm lost.

armSeb commented 6 years ago

Did you select the correct ESP frequency ? You have to set it to 160MHz (Sometimes the Arduino IDE can reset this setting).