From 58d16b974cfd002ce68e96fd4d1053542bcf26d7 Mon Sep 17 00:00:00 2001 From: Hendrik Langer Date: Sat, 3 Feb 2018 14:44:05 +0100 Subject: [PATCH] fix mp3 playback --- src/mp3.cpp | 62 ++++++++++++++++++++++++++------ src/mp3.h | 11 +++--- src/screen.cpp | 98 +++++++++++++++++++++++++------------------------- 3 files changed, 104 insertions(+), 67 deletions(-) diff --git a/src/mp3.cpp b/src/mp3.cpp index 95e449c..bc2c1ba 100644 --- a/src/mp3.cpp +++ b/src/mp3.cpp @@ -19,7 +19,10 @@ char titleStr[64]; -MP3::MP3() {} +MP3::MP3() { + strncpy_P(URL, "http://streaming.shoutcast.com/80sPlanet?lang=en-US", sizeof(URL)); + //const char *URL="http://swr-swr1-bw.cast.addradio.de/swr/swr1/bw/mp3/64/stream.mp3"; +} /*gpio_set_direction(GPIO_NUM_13,GPIO_MODE_OUTPUT); // GPIO_MODE_DEF_OUTPUT gpio_set_direction(GPIO_NUM_12,GPIO_MODE_OUTPUT); @@ -40,9 +43,22 @@ void MP3::stop() { Serial.println("Stopping mp3 playback"); strcpy(titleStr, ""); playing = false; +// while (audioTaskHandle && eTaskGetState(audioTaskHandle) != eDeleted) { +// Serial.println("waiting for audio to finish"); + delay(100); +// } +} + +void MP3::start(const char* url) { + strncpy(URL, url, sizeof(URL)); + URL[sizeof(URL)-1] = '\0'; + start(); } void MP3::start() { + if (playing) { + stop(); + } Serial.println("Starting mp3 playback"); Serial.printf("%x\n", audioTaskHandle); if (playing == false) { @@ -57,12 +73,19 @@ void MP3::start() { } void MP3::setVolume(int volume) { - if (playing && out) - if (volume > 0 && volume <= 100) - out->SetGain(((float)volume)/100.0); + if (volume > 0 && volume <= 100) { + this->volume = volume; + volumeChanged = true; + } } void MP3::mp3_decoder_task(void *pvParameters) { + AudioGenerator *decoder = nullptr; + AudioFileSourceICYStream *file = nullptr; + AudioFileSourceBuffer *buff = nullptr; + AudioOutputI2S *out = nullptr; + + strcpy(titleStr, "..."); file = new AudioFileSourceICYStream(URL); file->RegisterMetadataCB(MDCallback, (void*)"ICY"); @@ -72,10 +95,22 @@ void MP3::mp3_decoder_task(void *pvParameters) { out = new AudioOutputI2S(I2S_NUM_0, false, 0); out->SetPinout(12, 13, 25); } - decoder = new AudioGeneratorMP3(); + decoder = new AudioGeneratorMP3(preallocateCodec, preallocateCodecSize); decoder->RegisterStatusCB(StatusCallback, (void*)"mp3"); + Serial.println("prefilling buffer"); + for (int i=0; i<10; i++) { +// char c; +// buff->read(&c, 1); + buff->loop(); delay(100); // pre-fill buffer + } + Serial.println("prefilling buffer done"); decoder->begin(buff, out); - out->SetGain(0.2); + if (volume > 0 && volume <= 100) { + out->SetGain(((float)volume)/100.0); + } else { + out->SetGain(0.2); + volume = 20; + } playing = true; while(decoder->isRunning()) { @@ -84,6 +119,10 @@ void MP3::mp3_decoder_task(void *pvParameters) { Serial.printf("Running for %d ms...\n", lastms); Serial.flush(); } + if (volumeChanged) { + volumeChanged = false; + out->SetGain(((float)volume)/100.0); + } if (!decoder->loop()) break; if (!playing) break; vTaskDelay(5 / portTICK_PERIOD_MS); @@ -95,19 +134,19 @@ void MP3::mp3_decoder_task(void *pvParameters) { playing = false; if (decoder) { - decoder->stop(); + decoder->stop(); // ToDo: takes long delete decoder; - decoder = NULL; + decoder = nullptr; } if (buff) { buff->close(); delete buff; - buff = NULL; + buff = nullptr; } if (file) { file->close(); delete file; - file = NULL; + file = nullptr; } vTaskDelete(NULL); @@ -119,7 +158,8 @@ bool MP3::begin() { // First, preallocate all the memory needed for the buffering and codecs, never to be freed preallocateBuffer = malloc(preallocateBufferSize); - if (!preallocateBuffer) { + preallocateCodec = malloc(preallocateCodecSize); + if (!preallocateBuffer || !preallocateCodec) { Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize); return false; } diff --git a/src/mp3.h b/src/mp3.h index de20547..2b32700 100644 --- a/src/mp3.h +++ b/src/mp3.h @@ -16,18 +16,15 @@ class MP3 { public: MP3(); bool begin(void); - const char *URL="http://streaming.shoutcast.com/80sPlanet?lang=en-US"; - //const char *URL="http://swr-swr1-bw.cast.addradio.de/swr/swr1/bw/mp3/64/stream.mp3"; + char URL[80]; void stop(void); void start(void); + void start(const char*); void setVolume(int); bool playing = false; + int volume = 20; + bool volumeChanged = true; private: - AudioGenerator *decoder; - AudioFileSourceICYStream *file; - AudioFileSourceBuffer *buff; - AudioOutputI2S *out; - TaskHandle_t audioTaskHandle; void mp3_decoder_task(void*); static void cTaskWrapper(void*); diff --git a/src/screen.cpp b/src/screen.cpp index f0ca85d..3032732 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -57,10 +57,23 @@ uint8_t SelectionList::select() { MainMenu::MainMenu() { string_list = { - "MP3", + "PLAY", + "80s Planet", + "Left Coast 70s", + "laradio Ska", + "French Quarter Jams", "test", - "test2", - "test3"}; + "test3", + "Radio Kol Yavne", + "ROCKIN626.COM", + "Jive Time Radio", + "Live Ireland", + "Ye Ol Celtic Pub", + "Gone Country - NZCMR", + "Return"}; + if (mp3.playing) { + string_list[0] = "STOP"; + } } uint8_t MainMenu::select() { @@ -74,9 +87,39 @@ uint8_t MainMenu::select() { } break; case 1: - iot.mqtt.publish(topic.c_str(), 1, true, "test" ); + mp3.start("http://streaming.shoutcast.com/80sPlanet?lang=en-US"); + break; case 2: + mp3.start("http://ice1.somafm.com/seventies-128-mp3"); + break; + case 3: + mp3.start("http://streaming.radionomy.com/laradiostrong?lang=de"); + break; + case 4: + mp3.start("http://184.171.163.20:8162/stream"); + break; + case 5: + iot.mqtt.publish(topic.c_str(), 1, true, "test" ); + case 6: iot.mqtt.publish(topic.c_str(), 1, true, "foo" ); + case 7: + mp3.start("http://212.83.129.92:8028/;?type=http&nocache=683"); + break; + case 8: + mp3.start("http://192.99.4.210:3574/stream"); + break; + case 9: + mp3.start("http://188.165.192.5:8279/stream?icy=http"); + break; + case 10: + mp3.start("http://69.167.190.234:8080/stream"); + break; + case 11: + mp3.start("http://192.240.102.133:11790/stream"); + break; + case 12: + mp3.start("http://192.99.41.102:5044/stream"); + break; default: Serial.println("unknown entry selected"); break; @@ -85,51 +128,8 @@ uint8_t MainMenu::select() { return current_pos; } -namespace { - - void Drawgauge(int x, byte y, byte r, byte p, int v, int minVal, int maxVal ) { - int n=(r/100.00)*p; // calculate needle percent lenght - - float gs_rad=-1.572; //-90 degrees in radiant - float ge_rad=0; - float i=((v-minVal)*(ge_rad-gs_rad)/(maxVal-minVal)+gs_rad); - int xp = x+(sin(i) * n); - int yp = y-(cos(i) * n); - u8g2.drawCircle(x,y,r, U8G2_DRAW_UPPER_LEFT ); - u8g2.drawLine(x,y,xp,yp); - - gs_rad=0; - ge_rad=1.572; //90 degrees in radiant - i=((v-minVal)*(ge_rad-gs_rad)/(maxVal-minVal)+gs_rad); - xp = x+(cos(i) * n); - yp = y-(sin(i) * n); - u8g2.drawCircle(x,y,r, U8G2_DRAW_UPPER_RIGHT ); - u8g2.drawLine(x,y,xp,yp); - - gs_rad=-1.572; - ge_rad=1.572; - i=((v-minVal)*(ge_rad-gs_rad)/(maxVal-minVal)+gs_rad); - xp = x+(sin(i) * n); - yp = y-(cos(i) * n); - u8g2.drawCircle(x,y,r, U8G2_DRAW_UPPER_LEFT|U8G2_DRAW_UPPER_RIGHT ); - u8g2.drawLine(x,y,xp,yp); - - gs_rad=-3.142; - ge_rad=1.572; - i=((v-minVal)*(ge_rad-gs_rad)/(maxVal-minVal)+gs_rad); - xp = x+(sin(i) * n); - yp = y-(cos(i) * n); - u8g2.drawCircle(x,y,r, U8G2_DRAW_UPPER_LEFT|U8G2_DRAW_UPPER_RIGHT|U8G2_DRAW_LOWER_LEFT ); - u8g2.drawLine(x,y,xp,yp); - - gs_rad=-1.572; - ge_rad=3.141; - i=((v-minVal)*(ge_rad-gs_rad)/(maxVal-minVal)+gs_rad); - xp = x+(sin(i) * n); - yp = y-(cos(i) * n); - u8g2.drawCircle(x,y,r, U8G2_DRAW_UPPER_LEFT|U8G2_DRAW_UPPER_RIGHT|U8G2_DRAW_LOWER_RIGHT ); - u8g2.drawLine(x,y,xp,yp); - } +namespace { /* anonymous namespace for helper functions */ + } void MainScreen::draw() {