33 *
44 * Created on: Oct 28.2018
55 *
6- * Version 3.0.13zh
7- * Updated on: Jan 04 .2025
6+ * Version 3.0.13zi
7+ * Updated on: Jan 06 .2025
88 * Author: Wolle (schreibfaul1)
99 *
1010 */
@@ -274,6 +274,7 @@ Audio::~Audio() {
274274 x_ps_free (&m_outBuff);
275275 x_ps_free (&m_ibuff);
276276 x_ps_free (&m_lastM3U8host);
277+ x_ps_free (&m_speechtxt);
277278
278279 stopAudioTask ();
279280 vSemaphoreDelete (mutex_playAudioData);
@@ -338,6 +339,7 @@ void Audio::setDefaults() {
338339 _client = static_cast <WiFiClient*>(&client); /* default to *something* so that no NULL deref can happen */
339340 ts_parsePacket (0 , 0 , 0 ); // reset ts routine
340341 x_ps_free (&m_lastM3U8host);
342+ x_ps_free (&m_speechtxt);
341343
342344 AUDIO_INFO (" buffers freed, free Heap: %lu bytes" , (long unsigned int )ESP.getFreeHeap ());
343345
@@ -931,17 +933,9 @@ bool Audio::connecttospeech(const char* speech, const char* lang) {
931933 char host[] = " translate.google.com.vn" ;
932934 char path[] = " /translate_tts" ;
933935
934- uint16_t speechLen = strlen (speech);
935- uint16_t speechBuffLen = speechLen + 300 ;
936- char * speechBuff = (char *)malloc (speechBuffLen);
937- if (!speechBuff) {
938- log_e (" out of memory" );
939- xSemaphoreGiveRecursive (mutex_playAudioData);
940- return false ;
941- }
942- memcpy (speechBuff, speech, speechLen);
943- speechBuff[speechLen] = ' \0 ' ;
944- char * urlStr = urlencode (speechBuff, false ); // percent encoding
936+ x_ps_free (&m_speechtxt);
937+ m_speechtxt = x_ps_strdup (speech);
938+ char * urlStr = urlencode (speech, false ); // percent encoding
945939 if (!urlStr) {
946940 log_e (" out of memory" );
947941 xSemaphoreGiveRecursive (mutex_playAudioData);
@@ -964,7 +958,6 @@ bool Audio::connecttospeech(const char* speech, const char* lang) {
964958 strcat (resp, " Accept: text/html\r\n " );
965959 strcat (resp, " Connection: close\r\n\r\n " );
966960
967- x_ps_free (&speechBuff);
968961 x_ps_free (&urlStr);
969962
970963 _client = static_cast <WiFiClient*>(&client);
@@ -981,6 +974,7 @@ bool Audio::connecttospeech(const char* speech, const char* lang) {
981974 m_f_ssl = false ;
982975 m_f_tts = true ;
983976 m_dataMode = HTTP_RESPONSE_HEADER;
977+ x_ps_free (&m_lastHost); m_lastHost = x_ps_strdup (host);
984978 xSemaphoreGiveRecursive (mutex_playAudioData);
985979 return true ;
986980}
@@ -3299,40 +3293,46 @@ void Audio::processWebFile() {
32993293 const uint32_t maxFrameSize = InBuff.getMaxBlockSize (); // every mp3/aac frame is not bigger
33003294 static uint32_t chunkSize; // chunkcount read from stream
33013295 static size_t audioDataCount; // counts the decoded audiodata only
3296+ static uint32_t byteCounter; // count received data
33023297
33033298 // first call, set some values to default - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33043299 if (m_f_firstCall) { // runs only ont time per connection, prepare for start
33053300 m_f_firstCall = false ;
33063301 m_t0 = millis ();
3302+ byteCounter = 0 ;
33073303 chunkSize = 0 ;
33083304 audioDataCount = 0 ;
33093305 m_f_stream = false ;
33103306 m_audioDataSize = m_contentlength;
33113307 m_webFilePos = 0 ;
33123308 }
33133309
3314- if (!m_contentlength && !m_f_tts) {
3315- log_e (" webfile without contentlength!" );
3316- stopSong ();
3317- return ;
3318- } // guard
33193310
33203311 uint32_t availableBytes = _client->available (); // available from stream
33213312
33223313 // chunked data tramsfer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3323- if (m_f_chunked) {
3314+ if (m_f_chunked && availableBytes ) {
33243315 uint8_t readedBytes = 0 ;
3325- if (!chunkSize) chunkSize = chunkedDataTransfer (&readedBytes);
3326- availableBytes = min (availableBytes, chunkSize);
3327- if (m_f_tts) m_contentlength = chunkSize;
3316+ if (m_f_chunked && chunkSize == byteCounter) {
3317+ chunkSize += chunkedDataTransfer (&readedBytes);
3318+ m_contentlength += chunkSize;
3319+ }
3320+ availableBytes = min (availableBytes, chunkSize - byteCounter);
33283321 }
33293322
3323+ if (!m_contentlength && !chunkSize) {
3324+ log_e (" webfile is not chunked or is without contentlength!" );
3325+ stopSong ();
3326+ return ;
3327+ } // guard
3328+
33303329 // if the buffer is often almost empty issue a warning - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33313330 if (m_f_stream) {if (streamDetection (availableBytes)) return ;}
33323331 availableBytes = min (availableBytes, (uint32_t )InBuff.writeSpace ());
33333332 int32_t bytesAddedToBuffer = _client->read (InBuff.getWritePtr (), availableBytes);
33343333 if (bytesAddedToBuffer > 0 ) {
33353334 m_webFilePos += bytesAddedToBuffer;
3335+ byteCounter += bytesAddedToBuffer;
33363336 if (m_f_chunked) m_chunkcount -= bytesAddedToBuffer;
33373337 if (m_controlCounter == 100 ) audioDataCount += bytesAddedToBuffer;
33383338 InBuff.bytesWritten (bytesAddedToBuffer);
@@ -3376,8 +3376,9 @@ void Audio::processWebFile() {
33763376 if (m_codec == CODEC_VORBIS) VORBISDecoder_FreeBuffers ();
33773377 m_codec = CODEC_NONE;
33783378 if (m_f_tts) {
3379- AUDIO_INFO (" End of speech: \" %s\" " , m_lastHost);
3380- if (audio_eof_speech) audio_eof_speech (m_lastHost);
3379+ AUDIO_INFO (" End of speech \" %s\" " , m_speechtxt);
3380+ if (audio_eof_speech) audio_eof_speech (m_speechtxt);
3381+ x_ps_free (&m_speechtxt);
33813382 }
33823383 else {
33833384 AUDIO_INFO (" End of webstream: \" %s\" " , m_lastHost);
@@ -5719,9 +5720,9 @@ size_t Audio::chunkedDataTransfer(uint8_t* bytes) {
57195720 stopSong ();
57205721 return 0 ;
57215722 }
5722- b = _client->read ();
5723- byteCounter++;
5724- if (b < 0 ) continue ; // -1 no data available
5723+ b = _client->read (); // e.g. 0x66 0x34 0x31 0x37 0x0D 0x0A --> 62487 Bytes + CR LF
5724+ byteCounter++; // 0x30 0x0D 0x0A --> last chunk, CAN
5725+ if (b < 0 ) continue ; // -1 nothing to read
57255726 if (b == ' \n ' ) break ;
57265727 if (b < ' 0' ) continue ;
57275728 // We have received a hexadecimal character. Decode it and add to the result.
0 commit comments