Skip to content

Commit 69240fd

Browse files
authored
Merge pull request #1090 from schreibfaul1/new-info-management
New info management fore some decoders
2 parents 97df548 + ad955c1 commit 69240fd

File tree

14 files changed

+837
-614
lines changed

14 files changed

+837
-614
lines changed

src/Audio.cpp

Lines changed: 35 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
audio.cpp
44
55
Created on: Oct 28.2018 */char audioI2SVers[] ="\
6-
Version 3.3.2i ";
7-
/* Updated on: Jul 01.2025
6+
Version 3.3.2j ";
7+
/* Updated on: Jul 03.2025
88
99
Author: Wolle (schreibfaul1)
1010
Audio library for ESP32, ESP32-S3 or ESP32-P4
@@ -91,7 +91,7 @@ void AUDIO_ERROR_IMPL(const char* path, int line, const char* fmt, Args&&... arg
9191

9292
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
9393
AudioBuffer::AudioBuffer(size_t maxBlockSize) {
94-
if(maxBlockSize) m_resBuffSizeRAM = maxBlockSize;
94+
if(maxBlockSize) m_resBuffSize = maxBlockSize;
9595
if(maxBlockSize) m_maxBlockSize = maxBlockSize;
9696
}
9797

@@ -103,19 +103,17 @@ AudioBuffer::~AudioBuffer() {
103103
int32_t AudioBuffer::getBufsize() { return m_buffSize; }
104104

105105
void AudioBuffer::setBufsize(size_t mbs) {
106-
m_buffSizePSRAM = m_buffSizeRAM = m_buffSize = mbs;
106+
if(mbs < 2 * m_resBuffSize) AUDIO_ERROR("not allowed buffer size must be greater than %i", 2 * m_resBuffSize);
107+
m_buffSize = mbs;
107108
return;
108109
}
109110

110111
size_t AudioBuffer::init() {
111112
if(m_buffer) free(m_buffer);
112113
m_buffer = NULL;
113-
if(m_buffSizePSRAM > 0) { // PSRAM found, AudioBuffer will be allocated in PSRAM
114-
m_f_psram = true;
115-
m_buffSize = m_buffSizePSRAM;
116-
m_buffer = (uint8_t*)ps_calloc(m_buffSize, sizeof(uint8_t));
117-
m_buffSize = m_buffSizePSRAM - m_resBuffSizePSRAM;
118-
}
114+
m_buffer = (uint8_t*)ps_calloc(m_buffSize, sizeof(uint8_t));
115+
m_buffSize = m_buffSize - m_resBuffSize;
116+
119117
if(!m_buffer) return 0;
120118
m_f_init = true;
121119
resetBuffer();
@@ -287,7 +285,7 @@ void Audio::initInBuff() {
287285
if(!InBuff.isInitialized()) {
288286
size_t size = InBuff.init();
289287
if(size > 0) {
290-
AUDIO_INFO("PSRAM %sfound, inputBufferSize: %u bytes", InBuff.havePSRAM() ? "" : "not ", size - 1);
288+
AUDIO_INFO("inputBufferSize: %u bytes", size - 1);
291289
}
292290
}
293291
changeMaxBlockSize(1600); // default size mp3 or aac
@@ -3433,7 +3431,6 @@ void Audio::processWebStream() {
34333431
m_pwst.availableBytes = min(m_pwst.availableBytes, (uint32_t)InBuff.writeSpace());
34343432
int32_t bytesAddedToBuffer = _client->read(InBuff.getWritePtr(), m_pwst.availableBytes);
34353433
if(bytesAddedToBuffer > 0) {
3436-
34373434
if(m_f_metadata) m_metacount -= bytesAddedToBuffer;
34383435
if(m_f_chunked) m_pwst.chunkSize -= bytesAddedToBuffer;
34393436
InBuff.bytesWritten(bytesAddedToBuffer);
@@ -3661,13 +3658,7 @@ void Audio::processWebStreamTS() {
36613658
}
36623659
}
36633660
if(m_pwsst.f_chunkFinished) {
3664-
if(m_f_psramFound) {
3665-
if(InBuff.bufferFilled() < 60000) {
3666-
m_pwsst.f_chunkFinished = false;
3667-
m_f_continue = true;
3668-
}
3669-
}
3670-
else {
3661+
if(InBuff.bufferFilled() < 60000) {
36713662
m_pwsst.f_chunkFinished = false;
36723663
m_f_continue = true;
36733664
}
@@ -3774,13 +3765,7 @@ void Audio::processWebStreamHLS() {
37743765
}
37753766

37763767
if(m_pwsHLS.f_chunkFinished) {
3777-
if(m_f_psramFound) {
3778-
if(InBuff.bufferFilled() < 50000) {
3779-
m_pwsHLS.f_chunkFinished = false;
3780-
m_f_continue = true;
3781-
}
3782-
}
3783-
else {
3768+
if(InBuff.bufferFilled() < 50000) {
37843769
m_pwsHLS.f_chunkFinished = false;
37853770
m_f_continue = true;
37863771
}
@@ -4539,14 +4524,14 @@ int Audio::findNextSync(uint8_t* data, size_t len) {
45394524

45404525
m_fnsy.nextSync = 0;
45414526

4542-
45434527
if(m_codec == CODEC_WAV) {
45444528
m_f_playing = true;
45454529
m_fnsy.nextSync = 0;
45464530
}
45474531
if(m_codec == CODEC_MP3) {
45484532
m_fnsy.nextSync = MP3FindSyncWord(data, len);
45494533
if(m_fnsy.nextSync == -1) return len; // syncword not found, search next block
4534+
MP3Decoder_ClearBuffer();
45504535
}
45514536
if(m_codec == CODEC_AAC) { m_fnsy.nextSync = AACFindSyncWord(data, len); }
45524537
if(m_codec == CODEC_M4A) {
@@ -4656,7 +4641,7 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
46564641
m_sbyt.isPS = 0;
46574642
m_sbyt.f_setDecodeParamsOnce = true;
46584643
m_sbyt.nextSync = findNextSync(data, len);
4659-
if(m_sbyt.nextSync < 0) return len;
4644+
if(m_sbyt.nextSync < 0) return len; // no syncword found
46604645
if(m_sbyt.nextSync == 0) { m_f_playing = true; }
46614646
if(m_sbyt.nextSync > 0) return m_sbyt.nextSync;
46624647
}
@@ -4681,31 +4666,26 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
46814666
stopSong();
46824667
}
46834668
}
4669+
bytesDecoded = len - m_sbyt.bytesLeft;
46844670

46854671
// m_decodeError - possible values are:
46864672
// 0: okay, no error
46874673
// 100: the decoder needs more data
46884674
// < 0: there has been an error
4675+
// -100: serious error, stop song
46894676

46904677
if(m_decodeError < 0) { // Error, skip the frame...
4691-
if((m_codec == CODEC_MP3) && (m_f_chunked == true)){ // http://bestof80s.stream.laut.fm/best_of_80s
4692-
// AUDIO_ERROR("%02X %02X %02X %02X %02X %02X %02X %02X %02X", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
4693-
if(specialIndexOf(data, "ID3", 4) == 0){
4694-
uint16_t id3Size = bigEndian(data + 6, 4, 7);
4695-
id3Size += 10;
4696-
AUDIO_INFO("ID3 tag found, skip %i bytes", id3Size);
4697-
return id3Size; // skip ID3 tag
4698-
}
4699-
if(m_decodeError == ERR_MP3_INVALID_HUFFCODES) {
4700-
AUDIO_INFO("last mp3 frame is invalid");
4701-
MP3Decoder_ClearBuffer();
4702-
return findNextSync(data, m_sbyt.bytesLeft); // skip last mp3 frame and search for next syncword
4703-
}
4678+
// AUDIO_ERROR("0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X '%c%c%c%c%c%c%c%c%c%c'",
4679+
// data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9]);
4680+
if(m_decodeError == -100){stopSong(); return bytesDecoded;} // serious error, e.g. decoder could not be initialized
4681+
if((m_codec == CODEC_MP3) && (m_f_chunked == true)){
4682+
;
47044683
}
4705-
// According to the specification, the channel configuration is transferred in the first ADTS header and no longer changes in the entire
4706-
// stream. Some streams send short mono blocks in a stereo stream. e.g. http://mp3.ffh.de/ffhchannels/soundtrack.aac
4707-
// This triggers error -21 because the faad2 decoder cannot switch automatically.
4684+
47084685
if(m_codec == CODEC_AAC && m_decodeError == -21){ // mono <-> stereo change
4686+
// According to the specification, the channel configuration is transferred in the first ADTS header and no longer changes in the entire
4687+
// stream. Some streams send short mono blocks in a stereo stream. e.g. http://mp3.ffh.de/ffhchannels/soundtrack.aac
4688+
// This triggers error -21 because the faad2 decoder cannot switch automatically.
47094689
m_sbyt.channels = 0;
47104690
if ((data[0] == 0xFF) || ((data[1] & 0xF0) == 0xF0)){
47114691
int channel_config = ((data[2] & 0x01) << 2) | ((data[3] & 0xC0) >> 6);
@@ -4718,25 +4698,17 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
47184698
AACDecoder_AllocateBuffers();
47194699
return 0;
47204700
}
4721-
4722-
printDecodeError(m_decodeError);
4723-
m_f_playing = false; // seek for new syncword
47244701
if(m_codec == CODEC_FLAC) {
4725-
// if(m_decodeError == ERR_FLAC_BITS_PER_SAMPLE_TOO_BIG) stopSong();
4726-
// if(m_decodeError == ERR_FLAC_RESERVED_CHANNEL_ASSIGNMENT) stopSong();
4702+
;
47274703
}
47284704
if(m_codec == CODEC_OPUS) {
4729-
if(m_decodeError == ERR_OPUS_HYBRID_MODE_UNSUPPORTED) stopSong();
4730-
if(m_decodeError == ERR_OPUS_SILK_MODE_UNSUPPORTED) stopSong();
4731-
if(m_decodeError == ERR_OPUS_NARROW_BAND_UNSUPPORTED) stopSong();
4732-
if(m_decodeError == ERR_OPUS_WIDE_BAND_UNSUPPORTED) stopSong();
4733-
if(m_decodeError == ERR_OPUS_SUPER_WIDE_BAND_UNSUPPORTED) stopSong();
4734-
if(m_decodeError == ERR_OPUS_INVALID_SAMPLERATE) stopSong();
4735-
return 0;
4705+
;
47364706
}
4737-
return 1; // skip one byte and seek for the next sync word
4707+
printDecodeError(m_decodeError);
4708+
m_f_playing = false; // seek for new syncword
4709+
if(bytesDecoded == 0) return 1; // skip one byte and seek for the next sync word
4710+
return bytesDecoded;
47384711
}
4739-
bytesDecoded = len - m_sbyt.bytesLeft;
47404712

47414713
if(bytesDecoded == 0 && m_decodeError == 0) { // unlikely framesize
47424714
AUDIO_INFO("framesize is 0, start decoding again");
@@ -4913,67 +4885,21 @@ void Audio::printDecodeError(int r) {
49134885
const char* e;
49144886

49154887
if(m_codec == CODEC_MP3) {
4916-
switch(r) {
4917-
case ERR_MP3_NONE: e = "NONE"; break;
4918-
case ERR_MP3_INDATA_UNDERFLOW: e = "INDATA_UNDERFLOW"; break;
4919-
case ERR_MP3_MAINDATA_UNDERFLOW: e = "MAINDATA_UNDERFLOW"; break;
4920-
case ERR_MP3_FREE_BITRATE_SYNC: e = "FREE_BITRATE_SYNC"; break;
4921-
case ERR_MP3_OUT_OF_MEMORY: e = "OUT_OF_MEMORY"; break;
4922-
case ERR_MP3_NULL_POINTER: e = "NULL_POINTER"; break;
4923-
case ERR_MP3_INVALID_FRAMEHEADER: e = "INVALID_FRAMEHEADER"; break;
4924-
case ERR_MP3_INVALID_SIDEINFO: e = "INVALID_SIDEINFO"; break;
4925-
case ERR_MP3_INVALID_SCALEFACT: e = "INVALID_SCALEFACT"; break;
4926-
case ERR_MP3_INVALID_HUFFCODES: e = "INVALID_HUFFCODES"; break;
4927-
case ERR_MP3_INVALID_DEQUANTIZE: e = "INVALID_DEQUANTIZE"; break;
4928-
case ERR_MP3_INVALID_IMDCT: e = "INVALID_IMDCT"; break;
4929-
case ERR_MP3_INVALID_SUBBAND: e = "INVALID_SUBBAND"; break;
4930-
default: e = "ERR_UNKNOWN";
4931-
}
4932-
AUDIO_INFO("MP3 decode error %d : %s", r, e);
4888+
;
49334889
}
49344890
if(m_codec == CODEC_AAC || m_codec == CODEC_M4A) {
49354891
e = AACGetErrorMessage(abs(r));
49364892
AUDIO_INFO("AAC decode error %d : %s", r, e);
49374893
}
49384894
if(m_codec == CODEC_FLAC) {
4939-
switch(r) {
4940-
case ERR_FLAC_NONE: e = "NONE"; break;
4941-
case ERR_FLAC_BLOCKSIZE_TOO_BIG: e = "BLOCKSIZE TOO BIG"; break;
4942-
case ERR_FLAC_RESERVED_BLOCKSIZE_UNSUPPORTED: e = "Reserved Blocksize unsupported"; break;
4943-
case ERR_FLAC_SYNC_CODE_NOT_FOUND: e = "SYNC CODE NOT FOUND"; break;
4944-
case ERR_FLAC_UNKNOWN_CHANNEL_ASSIGNMENT: e = "UNKNOWN CHANNEL ASSIGNMENT"; break;
4945-
case ERR_FLAC_RESERVED_CHANNEL_ASSIGNMENT: e = "RESERVED CHANNEL ASSIGNMENT"; break;
4946-
case ERR_FLAC_RESERVED_SUB_TYPE: e = "RESERVED SUB TYPE"; break;
4947-
case ERR_FLAC_PREORDER_TOO_BIG: e = "PREORDER TOO BIG"; break;
4948-
case ERR_FLAC_RESERVED_RESIDUAL_CODING: e = "RESERVED RESIDUAL CODING"; break;
4949-
case ERR_FLAC_WRONG_RICE_PARTITION_NR: e = "WRONG RICE PARTITION NR"; break;
4950-
case ERR_FLAC_BITS_PER_SAMPLE_TOO_BIG: e = "BITS PER SAMPLE > 16"; break;
4951-
case ERR_FLAC_BITS_PER_SAMPLE_UNKNOWN: e = "BITS PER SAMPLE UNKNOWN"; break;
4952-
case ERR_FLAC_DECODER_ASYNC: e = "DECODER ASYNCHRON"; break;
4953-
case ERR_FLAC_BITREADER_UNDERFLOW: e = "BITREADER ERROR"; break;
4954-
case ERR_FLAC_OUTBUFFER_TOO_SMALL: e = "OUTBUFFER TOO SMALL"; break;
4955-
default: e = "ERR_UNKNOWN";
4956-
}
4957-
AUDIO_INFO("FLAC decode error %d : %s", r, e);
4895+
;
49584896
}
49594897
if(m_codec == CODEC_OPUS) {
4960-
e = OPUSGetErrorMessage(r);
4961-
AUDIO_INFO("OPUS decode error %d : %s", r, e);
4898+
;
49624899
}
49634900
if(m_codec == CODEC_VORBIS) {
4964-
switch(r) {
4965-
case ERR_VORBIS_NONE: e = "NONE"; break;
4966-
case ERR_VORBIS_CHANNELS_OUT_OF_RANGE: e = "CHANNELS OUT OF RANGE"; break;
4967-
case ERR_VORBIS_INVALID_SAMPLERATE: e = "INVALID SAMPLERATE"; break;
4968-
case ERR_VORBIS_EXTRA_CHANNELS_UNSUPPORTED: e = "EXTRA CHANNELS UNSUPPORTED"; break;
4969-
case ERR_VORBIS_DECODER_ASYNC: e = "DECODER ASYNC"; break;
4970-
case ERR_VORBIS_OGG_SYNC_NOT_FOUND: e = "SYNC NOT FOUND"; break;
4971-
case ERR_VORBIS_BAD_HEADER: e = "BAD HEADER"; break;
4972-
case ERR_VORBIS_NOT_AUDIO: e = "NOT AUDIO"; break;
4973-
case ERR_VORBIS_BAD_PACKET: e = "BAD PACKET"; break;
4974-
default: e = "ERR_UNKNOWN";
4975-
}
4976-
AUDIO_INFO("VORBIS decode error %d : %s", r, e);
4901+
;
4902+
49774903
}
49784904
}
49794905
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -5336,11 +5262,6 @@ uint32_t Audio::inBufferSize() {
53365262
return InBuff.getBufsize();
53375263
}
53385264
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
5339-
void Audio::setBufferSize(size_t mbs) {
5340-
// set audio input buffer size in bytes
5341-
return InBuff.setBufsize(mbs);
5342-
}
5343-
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
53445265
// *** D i g i t a l b i q u a d r a t i c f i l t e r ***
53455266
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
53465267
void Audio::IIR_calculateCoefficients(int8_t G0, int8_t G1, int8_t G2) { // Infinite Impulse Response (IIR) filters

src/Audio.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,25 +98,20 @@ class AudioBuffer {
9898
uint32_t getWritePos(); // write position relative to the beginning
9999
uint32_t getReadPos(); // read position relative to the beginning
100100
void resetBuffer(); // restore defaults
101-
bool havePSRAM() { return m_f_psram; };
102101

103102
protected:
104-
size_t m_buffSizePSRAM = UINT16_MAX * 10; // most webstreams limit the advance to 100...300Kbytes
105-
size_t m_buffSizeRAM = 1600 * 10;
106-
size_t m_buffSize = 0;
103+
size_t m_buffSize = UINT16_MAX * 10; // most webstreams limit the advance to 100...300Kbytes
107104
size_t m_freeSpace = 0;
108105
size_t m_writeSpace = 0;
109106
size_t m_dataLength = 0;
110-
size_t m_resBuffSizeRAM = 4096; // reserved buffspace, >= one wav frame
111-
size_t m_resBuffSizePSRAM = 4096 * 6; // reserved buffspace, >= one flac frame
107+
size_t m_resBuffSize = 4096 * 6; // reserved buffspace, >= one flac frame
112108
size_t m_maxBlockSize = 1600;
113109
uint8_t* m_buffer = NULL;
114110
uint8_t* m_writePtr = NULL;
115111
uint8_t* m_readPtr = NULL;
116112
uint8_t* m_endPtr = NULL;
117113
bool m_f_init = false;
118114
bool m_f_isEmpty = true;
119-
bool m_f_psram = false; // PSRAM is available (and used...)
120115
};
121116
//----------------------------------------------------------------------------------------------------------------------
122117

@@ -506,7 +501,6 @@ class Audio : private AudioBuffer{
506501
}
507502
}
508503

509-
510504
void trim(char *str) {
511505
char *start = str; // keep the original pointer
512506
char *end;
@@ -791,7 +785,7 @@ class Audio : private AudioBuffer{
791785
std::vector<uint32_t> m_hashQueue;
792786

793787
const size_t m_frameSizeWav = 4096;
794-
const size_t m_frameSizeMP3 = 1600;
788+
const size_t m_frameSizeMP3 = 1600 * 2;
795789
const size_t m_frameSizeAAC = 1600;
796790
const size_t m_frameSizeFLAC = 4096 * 6; // 24576
797791
const size_t m_frameSizeOPUS = 2048;

0 commit comments

Comments
 (0)