ESP32-Radio
ESP32-Radio copied to clipboard
320kbps playback issues
I'm quite surprised that this ESP32 version has issues with playing 320kbps MP3 and AAC streams. I like to play 149.255.57.97:8148 A1Radio 320Kbps MP3 and 45.43.200.66:25858 GOLD INST HD 320Kbps AAC The first one plays on the older ESP Radio smoothly and the second one with only some occasional gaps, but at the ESP32 player both of them have periodical significant gaps. On the PC connected via wifi both of them are playing smoothly with the 100% full buffer. Any idea what may be wrong?
149.255.57.97:8148 plays well here. The queue is constantly filled up to 380 or more chunks. 45.43.200.66:25858 has difficulties. The queue becomes empty now and then. It looks that the sender provide less than 320 kbps most of the time.
Test both of them on the PC and see the buffer. In my case they have full bitrate.
Same problem here... glitches glitches on all streams above 128k... Tried everything... Maybe chip is bad...
Everything else PERFECT!!!
149.255.57.97:8148 plays well here. 178.79.158.160:8424/stream plays well here. 45.43.200.66:25858 has still difficulties, because the real bitrate is about 304 bps and my software is not capable to cope with that. PC software is capable to adapt to the real bitrate.
I too have issues with anything over 128k stream. eg: http://85.214.231.253:8080/stream 192k stream They work fine on the PC, but playback on the ESP is very bad, plays 0.25 sec then pause 0.25sec repeat. I suspect there are somethings that have changed with the Wifi stack in recent with Arduino-esp32 related to internal buffers.
Using V1.0.0 of the ESP32 for Boards manager (finally!) https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md
Any thoughts?
85.214.231.253:8080/stream (without "http://" of course) plays well here. Dubug output:
D: Connect to new host 85.214.231.253:8080/stream
D: Connect to 85.214.231.253 on port 8080, extension /stream
D: Connected to server
D: Switch to HEADER
D: Headerline: Accept-Ranges:none
D: Headerline: Access-Control-Allow-Origin:*
D: Headerline: Cache-Control:no-cache,no-store,must-revalidate,max-age=0
D: Headerline: Pragma:no-cache,no-store
D: Headerline: Expires:-1
D: Headerline: Connection:close
D: Headerline: icy-name:Dolfijn FM
D: Headerline: icy-genre:Pop, Top 40
D: Headerline: icy-br:192
D: Headerline: icy-sr:44100
D: Headerline: icy-url:http://www.dolfijnfm.com
D: Headerline: icy-pub:1
D: Headerline: content-type:audio/mpeg
D: audio/mpeg seen.
D: Headerline: icy-metaint:16384
D: Headerline: X-Clacks-Overhead:GNU Terry Pratchett
D: Switch to DATA, bitrate is 192, metaint is 16384
D: Metadata block 64 bytes
D: Streamtitle found, 48 bytes
D: StreamTitle='La Bilirrubina - Juan Luis Guerra';
**D: Command: test with parameter 0**
D: Stack maintask is 4876
D: Stack playtask is 1048
D: Stack spftask is 820
D: ADC reading is 34
D: scaniocount is 10
D: Max. mp3_loop duration is 62
D: Free memory is 136592, chunks in queue 389, stream 6964, bitrate 192 kbps
D: Duration mp3loop 14
D: Duration mp3loop 25
D: Duration mp3loop 26
Can you try it on a different WiFi network?
Don't have access to any other wifi at the moment, but PC works fine using same wifi and same stream.
Have you tried using the latest version V1.0.0 of the arduino-esp32 code??? https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md
my output D: Connect to new host 85.214.231.253:8080/stream D: Connect to 85.214.231.253 on port 8080, extension /stream D: Connected to server D: Switch to HEADER D: Headerline: Accept-Ranges:none D: Headerline: Access-Control-Allow-Origin:* D: Headerline: Cache-Control:no-cache,no-store,must-revalidate,max-age=0 D: Headerline: Pragma:no-cache,no-store D: Headerline: Expires:-1 D: Headerline: Connection:close D: Headerline: icy-name:Dolfijn FM D: Headerline: icy-genre:Pop, Top 40 D: Headerline: icy-br:192 D: Headerline: icy-sr:44100 D: Headerline: icy-url:http://www.dolfijnfm.com D: Headerline: icy-pub:1 D: Headerline: content-type:audio/mpeg D: audio/mpeg seen. D: Headerline: icy-metaint:16384 D: Headerline: X-Clacks-Overhead:GNU Terry Pratchett D: Switch to DATA, bitrate is 192, metaint is 16384 D: Metadata block 48 bytes D: Streamtitle found, 36 bytes D: StreamTitle='Shotgun - George Ezra'; D: Command: test with parameter 0 D: Stack maintask is 5900 D: Stack playtask is 1048 D: Stack spftask is 676 D: ADC reading is 0 D: scaniocount is 10 D: Max. mp3_loop duration is 49 D: Free memory is 175016, chunks in queue 0, stream 0, bitrate 114 kbps D: Duration mp3loop 1 D: Duration mp3loop 2 D: Duration mp3loop 4 D: Duration mp3loop 5
Queue is 0. That means: not enough input from the network. I'm using the latest versions of toolchain and libraries.
Yep, but I suspect that is due to network latency and insufficient RX buffers in the network stack. I tried another wifi (my mobile phone hotspot, same issues)
Whats you latency like to this host, my latancy on ADSL is below?
Pinging 85.214.231.253 with 32 bytes of data: Reply from 85.214.231.253: bytes=32 time=381ms TTL=112 Reply from 85.214.231.253: bytes=32 time=368ms TTL=112 Reply from 85.214.231.253: bytes=32 time=368ms TTL=112 Reply from 85.214.231.253: bytes=32 time=369ms TTL=112
Ping statistics for 85.214.231.253: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 368ms, Maximum = 381ms, Average = 371ms
Pinging 85.214.231.253 with 32 bytes of data:
Reply from 85.214.231.253: bytes=32 time=18ms TTL=122
Reply from 85.214.231.253: bytes=32 time=17ms TTL=122
Reply from 85.214.231.253: bytes=32 time=18ms TTL=122
Reply from 85.214.231.253: bytes=32 time=18ms TTL=122
Ping statistics for 85.214.231.253:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 17ms, Maximum = 18ms, Average = 17ms
Holly cow, that's basiclly siting on your lan!
You might need to find a high bitrate with high latency +300ms, and then you will see the issues,
Not all of live in europe!
Maybe try this one it's about 200ms from me, and should be similar for you! http://162.211.86.137:8000/stream 320k
121 msec from here and it's BAD. I will try it with increased buffersize, but I cannot change the internal buffers.
Well that good that you can replicate the issuse!
This sounds lnteresting, Implement RX buffer for WiFi client to speed up small reads https://github.com/espressif/arduino-esp32/commit/9efecc1be03a7f319df1d86b58f56ae73a6ae510
I haven't figured out how to call WiFiClientRxBuffer(10240); yet, keep getting error invalid use of incomplete type 'class WiFiClientRxBuffer'
There are no "small reads" in the radio, it's always trying to read as much as possible. I checked it with the new version, but the result is the same. WiFiClientRxBuffer is called internally. No way (and no need) to call it from a sketch.
I think the issues are related to how TCP works, once the internal WIFI stack buffer is full it starts dropping packets to reduce the window size of the packet so less data gets sent. When the stream starts I'm guessing there is more data sent than the internal buffer can handel and it all slows down, the more latency the slower it recovers. I think the internal buffers are small only 2*1468 bytes from memory.
Thoughts on how to resolve?
I think there is no solution for this. The code and the primary buffers are part of the ROM program.
Are you sure they are in the ROM? Lots of mention of buffers in here C:\Users\Username\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.0\tools\sdk\include\lwip
lwipopts.h lwip/opt.h
I fixed it like this .. you should not read the buffer every time something is available cuz u may read 1 byte and execute butt load of code. do it every 1k bytes . if ( maxchunk > 1000 )
My problem was with this station. preset_1 = 192.95.18.39:5784 # 1 ChroniX | AGGRESSION
av = mp3client.available() ; // Available from stream if ( av < maxchunk ) // Limit read size { maxchunk = av ; } if ( maxchunk > qspace ) // Enough space in queue? { maxchunk = qspace ; // No, limit to free queue space } if ( maxchunk > 1000 ) // Anything to read? { res = mp3client.read ( tmpbuff, maxchunk ) ; // Read a number of bytes from the stream }
It is a good idea, tested it, but it did not work out here for your station. To aggressive I assume :)
Yes it worked a while dont know why but then started again to cut out . Then i googled again and i think i found it ;D
I added those 2 lines but the power saving mode did it i think. Buffer is now always at 400 esp_wifi_set_ps(WIFI_PS_NONE);//turn power saving off esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B); // better range
add extern "C" {
#include <esp_wifi.h>
}
to the include section.
then in connectwifi()
bool connectwifi() { char* pfs ; // Pointer to formatted string char* pfs2 ; // Pointer to formatted string bool localAP = false ; // True if only local AP is left
WifiInfo_t winfo ; // Entry from wifilist
WiFi.disconnect(true) ; // After restart the router could WiFi.softAPdisconnect(true) ; // still keep the old connection if ( wifilist.size() ) // Any AP defined? { if ( wifilist.size() == 1 ) // Just one AP defined in preferences? { winfo = wifilist[0] ; // Get this entry esp_wifi_set_ps(WIFI_PS_NONE); esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B); WiFi.begin ( winfo.ssid, winfo.passphrase ) ; // Connect to single SSID found in wifi_xx dbgprint ( "Try WiFi %s", winfo.ssid ) ; // Message to show during WiFi connect }
Tested like 20 radios now seems to work with the original code with just those 2 lines changed. Found just one that had issues but could be server releated.
Old Pioneer TX 6500 II gets a new life;>
http://gsgrid.net/harb/harb/PitsIphone/PhotoSync/IMG_7165.JPG http://gsgrid.net/harb/harb/PitsIphone/PhotoSync/IMG_7164.JPG
Yes it worked a while dont know why but then started again to cut out . Then i googled again and i think i found it ;D
I added those 2 lines but the power saving mode did it i think. Buffer is now always at 400 esp_wifi_set_ps(WIFI_PS_NONE);//turn power saving off esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B); // better range
add extern "C" {
#include <esp_wifi.h>
} to the include section. then in connectwifi()
bool connectwifi() { char* pfs ; // Pointer to formatted string char* pfs2 ; // Pointer to formatted string bool localAP = false ; // True if only local AP is left
WifiInfo_t winfo ; // Entry from wifilist
WiFi.disconnect(true) ; // After restart the router could WiFi.softAPdisconnect(true) ; // still keep the old connection if ( wifilist.size() ) // Any AP defined? { if ( wifilist.size() == 1 ) // Just one AP defined in preferences? { winfo = wifilist[0] ; // Get this entry esp_wifi_set_ps(WIFI_PS_NONE); esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B); WiFi.begin ( winfo.ssid, winfo.passphrase ) ; // Connect to single SSID found in wifi_xx dbgprint ( "Try WiFi %s", winfo.ssid ) ; // Message to show during WiFi connect }
Great Job, i adopted your 3 lines of code and enjoy 320kbit@48kHz :) Greets
The HTTP requests do not lag anymore the pages of the esp32 are faster.