Skip to content

Fixed: chunk boundaries plus metadata in chunked streams - #205

Merged
CelliesProjects merged 13 commits into
masterfrom
collect-all-metadata-first-for-chunked-streams-also
Aug 28, 2026
Merged

Fixed: chunk boundaries plus metadata in chunked streams#205
CelliesProjects merged 13 commits into
masterfrom
collect-all-metadata-first-for-chunked-streams-also

Conversation

@CelliesProjects

Copy link
Copy Markdown
Owner

No description provided.

@CelliesProjects

Copy link
Copy Markdown
Owner Author

@Frank-Bemelman

Thanks a lot for fixing the issue for http stream and showing that _musicDataPosition == _metaDataStart is a usefull invariant.

I started work on fixing the metadata issue for chunked streams.
This is a bit more involved and an extra pair of eyes would be appreciated.

@CelliesProjects

Copy link
Copy Markdown
Owner Author

I use
{"Grolloo Radio", "https://de4.streamingpulse.com/ssl/7053"},

as a test stream as it very quick to fail.

@Frank-Bemelman

Copy link
Copy Markdown

Well, at a quick glance I see that you changed _nextChunkSize() a bit. Looks fine by me, although I have not seen it enter without enough available the last days, has been behaving quite nicely. But checking on stream->available() rather than counting, that can never harm. And to be honest, it things fail here, some disaster already has happened. But, yes, looks good.

Also see that you moved all that metadata work to a seperate function. Makes it at least a bit more readable, I guess. I can't give any comments on the details, my mental model still is rather shaky.

I'll try to implement your new approach, right now I am still chasing a stubborn Australian station that just stops sending data for no apperent reason. And you know, the more I am geared up for it, the less it drops out, not giving me a chance to make up my mind ;-)

@Frank-Bemelman

Copy link
Copy Markdown

It is also tempting to move _playFromRingBuffer(); to a seperate task, rather than having it run as part of the big loop.

@CelliesProjects

CelliesProjects commented Aug 26, 2026

Copy link
Copy Markdown
Owner Author

I changed _bytesLeftInChunk from a size_t to an int32_t so I can use -1 as a not yet ready flag.

If there is not enough data available in_nextChunkSize() a library member array is filled with what is available and -1 returned.
Only when the closing /r/n is read the _nextChunkSize(WiFiClient *stream) uses that array and returns a valid chunksize.
There is a bit more to fix yet, but thats basically it.

@CelliesProjects

Copy link
Copy Markdown
Owner Author

It is also tempting to move _playFromRingBuffer(); to a seperate task, rather than having it run as part of the big loop.

For multiple reasons, yes.

@Frank-Bemelman

Copy link
Copy Markdown

Maybe safer to replace all if (!_bytesLeftInChunk) into if (_bytesLeftInChunk>0)
Just in case..

@Frank-Bemelman

Frank-Bemelman commented Aug 26, 2026

Copy link
Copy Markdown

But it's a very nice fix of _nextChunkSize(); Good work.
This way, you can even fall into that function that with only 2-3 bytes available, use that, and finish it the next round.
And I actually did see it happen, entering there with only 3 bytes, as rare as it is.

For some reason I think it is good to leave stream.loop() always empty handed.
Like to believe the underlying wifi buffers appreciate that.

@CelliesProjects

CelliesProjects commented Aug 26, 2026

Copy link
Copy Markdown
Owner Author

I just wanted to dump an idea I had before it vanishes.

Combine _checkSync() and _nextChunkSize() into a single function.

This massively reduces the complexity around chunk ends if done right.

Same idea for the rest, use -1 as a not ready flag but now for the whole /r/n/chunksize/r/n piece.

@Frank-Bemelman

Copy link
Copy Markdown

I'm lacking insight re sync and chunksize, protocol wise, but if that really always comes as /r/n/chuncksize/r/n/ then, yes indeed, why not lift that out of the stream as one entity...

@Frank-Bemelman

Copy link
Copy Markdown

About vanishing ideas, inside loop, before a return, early or at the very end, check if available is 0, which would indicate, if >0, some oppertunity is missed. Sure, leftovers will still be there in the next round, but just a gut feeling to consume every byte availaible.

@CelliesProjects

Copy link
Copy Markdown
Owner Author

There might be a full ringbuffer ofcourse. But the idea has merit.

@Frank-Bemelman

Frank-Bemelman commented Aug 26, 2026

Copy link
Copy Markdown

So true. Ideally, you would like to be able to always store in the ringbuffer, which, btw, is usally filled up almost completely. That sortof bothers me, and actually can't get my head around it (yet) how that give&take game works.

Something is about to burst, if we receive data faster than we can play away. And vice verca, if the station runs with a slower clock, would eventually give tiny silent hicks, possibly unnoticable. . I already fooled around a bit with that, but it doesn't seem to work. Didn't investigate much further, got distracted by other things. Here some preliminary stuff I wrote but didn't work. Maybe I don't have the right patches loaded.

#define SCI_AUDATA   0x05
#define SCI_WRAMADDR 0x07
#define SCI_WRAM     0x06

void ESP32_VS1053_Stream::setPlaybackSpeedTune(long ppm2) {
  _vs1053->writeRegister(SCI_WRAMADDR, 0x1e07);
  _vs1053->writeRegister(SCI_WRAM, ppm2 & 0xFFFF);        // lower 16-bits
  _vs1053->writeRegister(SCI_WRAM, (ppm2 >> 16) & 0xFFFF); // higher 16-bits

  _vs1053->writeRegister(SCI_WRAMADDR, 0x5b1c);
  _vs1053->writeRegister(SCI_WRAM, 0);

  uint16_t currentAudata = _vs1053->readRegister(SCI_AUDATA);
  _vs1053->writeRegister(SCI_AUDATA, currentAudata);
}

void ESP32_VS1053_Stream::adjustStreamSync() {
  // calculate relative fill level (0.0 tot 1.0)
  float bufferFillLevel = (float)(VS1053_PSRAM_BUFFER_SIZE - xRingbufferGetCurFreeSize(_ringbuffer_handle)) / VS1053_PSRAM_BUFFER_SIZE;

  if (bufferFillLevel > 0.85) {
    // buffer too full -> speed up VS1053 with ~0.5% to create more room
    setPlaybackSpeedTune(20000); 
    Serial.printf("faster %lu\n", xRingbufferGetCurFreeSize(_ringbuffer_handle));
  } 
  else if (bufferFillLevel < 0.20) {
    // buffer running low -> slow down playback of VS1053 with ~0.5% to increase buffer
    setPlaybackSpeedTune(-20000); 
    Serial.printf("slower %lu\n", xRingbufferGetCurFreeSize(_ringbuffer_handle));
  } 
  else {
    // buffer is stable (between 20% en 85%) -> normal speed
    setPlaybackSpeedTune(0); 
  }
}

The idea was to call this function on a regular basis, trying to keep the buffer from underrunning and overrunning.

@Frank-Bemelman

Frank-Bemelman commented Aug 26, 2026

Copy link
Copy Markdown

Then there is that mechanism where the station/server notices the client is hungry or not, and adjusts the bitrate. Some start somewhat high, and then you see it drop slowly. Or it starts somewhat low, and see it climb up. This you see in particular with ADTS.

With MP3 you sometimes see it drop from 192 kbps to 128 kbps. I also suspect that some MP3 implementations drop an entire MP3 frame, when they notice the client can't keep up. Nobody would hear that, too short. Wild guesses here.

@Frank-Bemelman

Frank-Bemelman commented Aug 27, 2026

Copy link
Copy Markdown

Or make it a bool ESP32_VS1053_Stream::_nextChunkSize(WiFiClient *stream) and return true upon succesful completion since _bytesLeftInChunk is a global variable. Seems that it becomes a little obfuscated how to deal with _bytesLeftInChunk now that it also holds a flag.

Grolloo radio works the first time, bugs out second time
@CelliesProjects

CelliesProjects commented Aug 27, 2026

Copy link
Copy Markdown
Owner Author

By handling the metadata first thing in void ESP32_VS1053_Stream::_handleChunkedStream(WiFiClient *stream) the function becomes a lot cleaner.
It now basically works, only a bug that makes it work just once to fix.

@CelliesProjects

Copy link
Copy Markdown
Owner Author

Very satisfied with how this turned out.

Some logging from Grolloo:

[799400][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799450][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799478][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799503][I][ESP32_VS1053_Stream.cpp:909] _handleChunkedStream(): chunksize not fully read
[799515][I][ESP32_VS1053_Stream.cpp:869] _handleChunkedStream(): next chunk size: 1400
[799555][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799582][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799609][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799659][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799687][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799714][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1
[799723][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799765][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799791][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799817][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[799870][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 7000
[800026][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[800078][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[800104][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 601
[800131][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 800
[800141][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[800182][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[800209][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[800235][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[800287][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400
[800315][I][ESP32_VS1053_Stream.cpp:919] _handleChunkedStream(): next chunk size: 1400

Looks good.

Notice the chunksize 1.

@CelliesProjects

Copy link
Copy Markdown
Owner Author

Fixed!

@Frank-Bemelman

Frank-Bemelman commented Aug 27, 2026

Copy link
Copy Markdown

Well, forget about trying to adjust the playback speed. It's a nightmare. So I ditched that.

To always have enough room in the ringbuffer, to be able to fully store a really large stream->available() when it comes in, I added something to keep the max fill level around 80 percent, in loop();

    if(((VS1053_PSRAM_BUFFER_SIZE - xRingbufferGetCurFreeSize(_ringbuffer_handle)) * 100 / VS1053_PSRAM_BUFFER_SIZE) > 80)
    { _playFromRingBuffer();
      return;
    }

    const bool data = stream->available();
    const auto now = millis();
    const auto currentStallTimeMS = now - _streamStallStartMS;

Not that it helped stopping that AU station from sometimes dropping out. But hey, at least I tried. Also tried a blunt auto reconnect, which 9 out of 10 gets it running again, but sometimes still keeps dropping out 5-10 times in a row with only a short blip of sound. Which is proof (for now and for me) it is simply an unreliable station.

Also added a fill percentage displayed on my puck. Sort of fun to see it go up and down. Added the necessary calback to make that happen.

Overall, it's definitely getting better.

@Frank-Bemelman

Frank-Bemelman commented Aug 27, 2026

Copy link
Copy Markdown

Nice, to see a chunksize of 1, keeps the station running.
I pasted in your new _nextChunkSize(), but with https://tcom-s1.tcom.net.au/2ten it gives me a 'no sync' immediately.
Maybe false alarm, my code here is quite a mess now.

[EDIT] Oops, seems I have to remove all the old _checkSync() stuff too.

@CelliesProjects

Copy link
Copy Markdown
Owner Author

@Frank-Bemelman

I am listening to https://tcom-s1.tcom.net.au/2ten

Runs ok now.

[ 17404][I][ESP32_VS1053_Stream.cpp:523] connectToHost(): redirected 0 times to https://tcom-s1.tcom.net.au/2ten
[ 17417][I][ESP32_VS1053_Stream.cpp:87] _nextChunkSize(): reading first chunk header
[ 17707][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 17995][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 18282][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 3816
[ 18609][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 18916][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 19225][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4019
[ 19514][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 19801][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 20080][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 20386][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4053
[ 20432][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 20723][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 21036][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 21323][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 3782
[ 21611][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 22244][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 22347][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 22661][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 22948][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 23191][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 24102][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 24472][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 24762][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 25697][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 26005][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 26293][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 27698][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 30559][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 33855][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 36734][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096
[ 39567][I][ESP32_VS1053_Stream.cpp:868] _handleChunkedStream(): next chunk size: 4096

@CelliesProjects

Copy link
Copy Markdown
Owner Author

Still some minor issues but this is fixing a lot of stations on my todo list.

@Frank-Bemelman

Copy link
Copy Markdown

Looks good! I added that last _chunkHeaderIndex = 0; too now. And let's how it holds up, as it runs now.
Regardless the outcome, I think it is more than fair to say you can now rightfully claim that title of 'Lord of the Ringbuffer'.
This stuff is so much out of my comfort zone..

@CelliesProjects

CelliesProjects commented Aug 27, 2026

Copy link
Copy Markdown
Owner Author

Stations like these now run fine:

[267147][I][ESP32_VS1053_Stream.cpp:523] connectToHost(): redirected 1 times to https://stream-204.surfernetwork.com/0psw13g10a0uv?zt=eyJhbGciOiJIUzI1NiJ9.eyJzdHJlYW0iOiIwcHN3MTNnMTBhMHV2IiwiaG9zdCI6InN0cmVhbS0yMDQuc3VyZmVybmV0d29yay5jb20iLCJ0bSI6ZmFsc2UsInJ0dGwiOjUsImp0aSI6InV3dEhfZzhIVEtXVWMtMmJXUVZKYlEiLCJpYXQiOjE3ODc4NTI3NzUsImV4cCI6MTc4Nzg1MjgzNX0.kyHb9kgqzQ3SGZ6JE0-ePbKbIOUUZZYOVqHtddUrijQ
[267206][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 16000
[267250][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 33
[267464][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 16000
[267527][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 1
[267654][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 7360
[267851][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 8640
[267882][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 1
[268094][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 16000
[268145][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 1
[268391][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 15680
[268436][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 320
[268448][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 1
[268772][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 16000
[268821][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 1
[269082][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 16000
[269132][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 1
[269281][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 8000
[269406][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 8000
[269434][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 1
[269708][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 16000
[269758][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 1
[270000][I][ESP32_VS1053_Stream.cpp:871] _handleChunkedStream(): next chunk size: 15360
[270044][I][ESP32_VS1053_Stream.cpp:918] _handleChunkedStream(): next chunk size: 640

@CelliesProjects CelliesProjects changed the title Fixed: collect all metadata first for chunked streams Fixed: chunk boundaries plus metadata in chunked streams Aug 27, 2026
@Frank-Bemelman

Copy link
Copy Markdown

Wow, that's a lot of small chunks there. What were they thinking..

@Frank-Bemelman

Copy link
Copy Markdown

@CelliesProjects You can remove bool ESP32_VS1053_Stream::_checkSync(WiFiClient *stream) too now. Great work!

@Frank-Bemelman

Copy link
Copy Markdown

I have added/changed this now:

void AudioPlayTask(void * pvParameters) {
  // keep a copy of the given pointer
  ESP32_VS1053_Stream* streamPointer = (ESP32_VS1053_Stream*) pvParameters;

  for(;;) {
    streamPointer->_playFromRingBuffer(); 
    vTaskDelay(1 / portTICK_PERIOD_MS); 
  }
}

bool ESP32_VS1053_Stream::startDecoder(const uint8_t CS, const uint8_t DCS, const uint8_t DREQ)
{
    if (_vs1053)
        return false;
    _vs1053 = new VS1053(CS, DCS, DREQ);
    if (!_vs1053)
        return false;
    _vs1053->begin();
    _vs1053->switchToMp3Mode();
    if (_vs1053->getChipVersion() == 4)
    {
        log_d("Patching vs1053 firmware");
        _vs1053->loadUserCode(PATCHES_FLAC, PATCHES_FLAC_SIZE);
    }
    _allocateRingbuffer();

    xTaskCreatePinnedToCore(
      AudioPlayTask,    
      "AudioPlayTask",  
      4096,                
      this,             
      3,                   // high  prioritity, music is important
      NULL,                
      1                    // core 1 
    );

    return true;
}

Also commented out all refences to _playFromRingBuffer(); to keep things safe. I think this helps a bit with these obnoxious streams that are not-so-steady, causing short stalls that freeze/halt the normal loop() from doing its work, which gives short audio gaps.

@CelliesProjects

CelliesProjects commented Aug 28, 2026

Copy link
Copy Markdown
Owner Author

Codacy complaining here is to be ignored as its wrong.

Technically correct, but code also shows intent.

@CelliesProjects

CelliesProjects commented Aug 28, 2026

Copy link
Copy Markdown
Owner Author

Fixes yet another set of non working stations for me.
This is close to merging now.
Ended up as very clean code.

@CelliesProjects
CelliesProjects merged commit 84c65ac into master Aug 28, 2026
1 check passed
@CelliesProjects
CelliesProjects deleted the collect-all-metadata-first-for-chunked-streams-also branch August 28, 2026 19:05
@Frank-Bemelman

Copy link
Copy Markdown

Excellent work! Pasted in your changes. I was still entertaining myself with https://tcom-s1.tcom.net.au/2ten which is 320kbps chunked station in Australia. Still gives me buffer empty so every now and then. Also doubled the VS1053_PSRAM_BUFFER_SIZE (65536*2) which makes it behave a lot better, but still drops out sometimes. And when it does drop out, it is with a perfect chunksize of 0 with 0/r/n. Weird that my buffer size apperently has an effect on what they send.

I like the move of _playFromRingBuffer() to a dedicated task. When this station consistently refuses to send more data, at least it dies more graciously now, without preliminary hicks/sputtering.

I was not able to link this to other network activity I do, like display communication, getting time/geolocation/wheater/mqtt etc.

@CelliesProjects

Copy link
Copy Markdown
Owner Author

At what timescales? I played the au station a while but it was not dropping at all.

@CelliesProjects

CelliesProjects commented Aug 28, 2026

Copy link
Copy Markdown
Owner Author

I do a lot of websocket in the same and other tasks, and do searches through an api then parsing 40kB without any hickups.

I would just try to keep the psram buffer filled btw.

@Frank-Bemelman

Frank-Bemelman commented Aug 28, 2026

Copy link
Copy Markdown

With a 65K buffer it could end in 5-10 minutes, 130KB seems to give instant relief. But I have seen also run for > 1 hour with 65K, so difficult to decide. And I went back to buffer filling max, to keep it around 80% was just a silly experiment.

Oops, it just stopped after 6 minutes..

21:43:50.506 -> >98 NextChunkSize = 1 available now 3
21:43:50.599 -> >98 NextChunkSize = 8000 available now 8002
21:43:50.787 -> >98 NextChunkSize = 8000 available now 8002
21:43:50.865 -> >98 NextChunkSize = 1 available now 3
21:43:51.297 -> TELL PUCK: ToDisplay.QueueCnt=0 (QueueIndexIn 46): STATUS_LINE 2 -> Streaming MP3 - 320 kbps 87% buffered
21:43:51.297 -> ESPNOW esp_now_send() ToDisplay.QueueCnt 1 -> ToDisplay.QueueIndexOut 46 != ToDisplay.QueueIndexIn 47
21:43:52.277 -> TELL PUCK: ToDisplay.QueueCnt=0 (QueueIndexIn 47): STATUS_LINE 2 -> Streaming MP3 - 320 kbps 56% buffered
21:43:52.320 -> ESPNOW esp_now_send() ToDisplay.QueueCnt 1 -> ToDisplay.QueueIndexOut 47 != ToDisplay.QueueIndexIn 48
21:43:53.306 -> TELL PUCK: ToDisplay.QueueCnt=0 (QueueIndexIn 48): STATUS_LINE 2 -> Streaming MP3 - 320 kbps 26% buffered
21:43:53.306 -> ESPNOW esp_now_send() ToDisplay.QueueCnt 1 -> ToDisplay.QueueIndexOut 48 != ToDisplay.QueueIndexIn 49
21:43:54.242 -> Error from VS1053 -> Ringbuffer empty
21:43:54.242 -> TELL PUCK: ToDisplay.QueueCnt=0 (QueueIndexIn 49): STATUS_LINE 2 -> Ringbuffer empty
21:43:54.275 -> 1105 FRANK _eofStream() called
21:43:54.311 -> snprintf made this string:EOF -> (Ringbuffer empty) url=https://stream.zeno.fm/0psw13g10a0uv stopped after 351300mS
21:43:54.311 -> TELL PUCK: ToDisplay.QueueCnt=1 (QueueIndexIn 0): CONNECTTOHOST_FAILURE 41 -> EOF -> (Ringbuffer empty) url=https://stream.zeno.fm/0psw13g10a0uv stopped after 351300mS

It's another station, sorry https://stream.zeno.fm/0psw13g10a0uv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants