Skip to content

[Probably solved] - Problems loading another web stream, buffer only cleaning up after 10-20 seconds. #229

@CelliesProjects

Description

@CelliesProjects

I have a problem loading a stream after I opened and played a stream on a M5 Stack Fire board.

First time a stream is opened it plays within seconds. If I change to another stream it takes between 0.5 and 20 seconds to clear the previous buffer.
Am I missing something here?
Log output: (note the pauses when cleaning the buffer.

12:28:43.093 -> ��⸮⸮��⸮��⸮⸮⸮⸮⸮⸮�⸮��⸮�⸮����⸮⸮����⸮��⸮��⸮����⸮�@bb⸮⸮⸮4
12:28:43.093 -> load:0x3fff001c,len:1044
12:28:43.093 -> load:0x40078000,len:8896
12:28:43.093 -> load:0x40080400,len:5816
12:28:43.093 -> entry 0x400806ac
12:28:44.815 -> [D][esp32-hal-psram.c:47] psramInit(): PSRAM enabled
12:28:45.311 -> [D][WiFiGeneric.cpp:332] _eventCallback(): Event: 0 - WIFI_READY
12:28:45.311 -> [D][WiFiGeneric.cpp:332] _eventCallback(): Event: 2 - STA_START
12:28:45.476 -> [D][WiFiGeneric.cpp:332] _eventCallback(): Event: 4 - STA_CONNECTED
12:28:45.509 -> [D][WiFiGeneric.cpp:332] _eventCallback(): Event: 7 - STA_GOT_IP
12:28:45.509 -> [D][WiFiGeneric.cpp:376] _eventCallback(): STA IP: 192.168.0.108, MASK: 255.255.255.0, GW: 192.168.0.1
12:28:45.509 -> [I][MP3_AllocatedBuffer.ino:97] setup(): Connected
12:28:45.509 -> [I][MP3_AllocatedBuffer.ino:99] setup(): Opening icystream http://icecast.omroep.nl/3fm-bb-mp3...
12:28:45.543 -> [D][HTTPClient.cpp:276] beginInternal(): host: icecast.omroep.nl port: 80 url: /3fm-bb-mp3
12:28:45.576 -> [D][HTTPClient.cpp:1025] connect():  connected to icecast.omroep.nl:80
12:28:45.642 -> [D][HTTPClient.cpp:1158] handleHeaderResponse(): code: 200
12:28:45.642 -> [I][MP3_AllocatedBuffer.ino:103] setup(): Buffering...
12:28:45.642 -> [I][MP3_AllocatedBuffer.ino:106] setup(): Filled buffer
12:28:45.642 -> [I][MP3_AllocatedBuffer.ino:116] setup(): created I2S output
12:28:45.642 -> [I][MP3_AllocatedBuffer.ino:118] setup(): created MP3 decoder
12:28:45.642 -> [I][MP3_AllocatedBuffer.ino:120] setup(): Start decoding http://icecast.omroep.nl/3fm-bb-mp3
12:28:51.137 -> [D][HTTPClient.cpp:361] disconnect(): still data in buffer (3758), clean up.
12:28:51.137 -> 
12:29:08.880 -> [D][HTTPClient.cpp:370] disconnect(): tcp stop
12:29:08.880 -> 
12:29:08.880 -> [D][HTTPClient.cpp:276] beginInternal(): host: icecast.omroep.nl port: 80 url: /radio6-bb-mp3
12:29:08.880 -> [D][HTTPClient.cpp:1025] connect():  connected to icecast.omroep.nl:80
12:29:08.946 -> [D][HTTPClient.cpp:1158] handleHeaderResponse(): code: 200
12:29:14.938 -> [D][HTTPClient.cpp:361] disconnect(): still data in buffer (7000), clean up.
12:29:14.938 -> 
12:29:32.666 -> [D][HTTPClient.cpp:370] disconnect(): tcp stop
12:29:32.666 -> 
12:29:32.666 -> [D][HTTPClient.cpp:276] beginInternal(): host: icecast.omroep.nl port: 80 url: /3fm-bb-mp3
12:29:32.699 -> [D][HTTPClient.cpp:1025] connect():  connected to icecast.omroep.nl:80
12:29:32.766 -> [D][HTTPClient.cpp:1158] handleHeaderResponse(): code: 200

The source code:

#include <WiFi.h>
#include <TFT_eSPI.h>
#include "AudioFileSourceICYStream.h"
#include "AudioFileSourceBuffer.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"

#define BUTTON_A                39
#define BUTTON_B                38
#define BUTTON_C                37
#define microphone              34
#define backlight               32
#define DAC                     25

const int preallocateBufferSize = 16 * 1024;

void *preallocateBuffer = nullptr;

float volume = 0.25; /* 0-100 */
const char * urlArray[] = { "http://icecast.omroep.nl/3fm-bb-mp3", "http://icecast.omroep.nl/radio6-bb-mp3" };
uint8_t currUrl = 0;

TFT_eSPI    tft      = TFT_eSPI();

AudioGeneratorMP3 *decoder = nullptr;
AudioFileSourceICYStream *file = nullptr;
AudioFileSourceBuffer *buff = nullptr;
AudioOutputI2S *out = nullptr;

// Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc.
void  MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
  const char *ptr = reinterpret_cast<const char *>(cbData);
  (void) isUnicode; // Punt this ball for now
  // Note that the type and string may be in PROGMEM, so copy them to RAM for printf
  char s1[32], s2[64];
  strncpy_P(s1, type, sizeof(s1));
  s1[sizeof(s1) - 1] = 0;
  strncpy_P(s2, string, sizeof(s2));
  s2[sizeof(s2) - 1] = 0;
  ESP_LOGI( TAG,"METADATA(%s) '%s' = '%s'", ptr, s1, s2);
  //Serial.flush();
}

// Called when there's a warning or error (like a buffer underflow or decode hiccup)
void StatusCallback(void *cbData, int code, const char *string)
{
  const char *ptr = reinterpret_cast<const char *>(cbData);
  // Note that the string may be in PROGMEM, so copy it to RAM for printf
  char s1[64];
  strncpy_P(s1, string, sizeof(s1));
  s1[sizeof(s1) - 1] = 0;
  ESP_LOGI( TAG,"STATUS(%s) '%d' = '%s'", ptr, code, s1);
  //Serial.flush();
}

bool StartPlayingURL(const char *url) {
  out->SetGain(0);
  out->stop();
  if ( decoder->isRunning() ) decoder->stop();
  if ( file->isOpen() ) file->close();
  //if ( buff->isOpen() ) buff->close();
  file->open(url);
  out->loop();
  //buff->loop();
  decoder->begin(buff, out);
  if (!decoder->isRunning()) {
    ESP_LOGI( TAG,"Can't connect to URL");
    out->SetGain(0);
    return false;
  }
  out->SetGain(volume);
  return true;
}

void setup() {
  pinMode( microphone, INPUT );
  pinMode( BUTTON_A, INPUT_PULLUP );
  pinMode( BUTTON_B, INPUT_PULLUP );
  pinMode( BUTTON_C, INPUT_PULLUP );
  
  ledcAttachPin( backlight, 0);
  ledcSetup( 0, 1300, 16 );
  ledcWrite( 0, 0xFFFF  / 16  ); //dimming the backlight will produce more base noise
  tft.init();
  tft.setRotation( 1 );
  tft.fillScreen( TFT_BLUE );
  tft.setTextColor( TFT_WHITE, TFT_BLUE );
  tft.setTextFont(2);
  tft.printf("Connecting WiFi. ");
  
  WiFi.mode( WIFI_STA );
  WiFi.setSleep( false );
  WiFi.begin( "...", "...");
  while ( !WiFi.isConnected() ) delay(100);
  tft.printf("Connected");
  ESP_LOGI( TAG,"Connected");

  ESP_LOGI( TAG,"Opening icystream %s...", urlArray[0]);
  file = new AudioFileSourceICYStream(urlArray[0]);
  //file->RegisterMetadataCB(MDCallback, nullptr);
  //if ( !file ) return false;
  ESP_LOGI( TAG,"Buffering...");
  buff = new AudioFileSourceBuffer( file, preallocateBufferSize );
  buff->loop();
  ESP_LOGI( TAG,"Filled buffer");
  //buff->RegisterStatusCB(StatusCallback, nullptr);

  out = new AudioOutputI2S( 0, 1 );
  //out->SetPinout(5, 13, 25);

  out->SetRate(44100);  
  out->SetChannels(2);  
  out->SetGain(0.2);

  ESP_LOGI( TAG,"created I2S output");
  decoder = (AudioGeneratorMP3*) new AudioGeneratorMP3();
  ESP_LOGI( TAG,"created MP3 decoder");
  //decoder->RegisterStatusCB(StatusCallback, nullptr);
  ESP_LOGI( TAG,"Start decoding %s", urlArray[0]);
  decoder->begin(buff, out);
}

void loop() {
  decoder->loop();
  bool BTNA_PRESSED = !digitalRead( BUTTON_A );

  //bool BTNB_PRESSED = !digitalRead( BUTTON_B );
  //bool BTNC_PRESSED = !digitalRead( BUTTON_C );

  
  if ( decoder->isRunning() && BTNA_PRESSED ) {
    currUrl = ( 0 == currUrl ) ? 1:0; 
    StartPlayingURL(urlArray[currUrl]); 
    BTNA_PRESSED = false; 
  }
  

  if ( !file->isOpen() || !decoder->isRunning() || !decoder->loop() ) {
    out->SetGain(0);
    decoder->stop();
  }

  //if ( digitalRead( BUTTON_B ) == LOW  && volume > -1 ) {out->SetGain(--volume / 100.0);delay(50);}
  //if ( digitalRead( BUTTON_C ) == LOW  && volume < 101 ) {out->SetGain(++volume / 100.0);delay(50);}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions