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// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
9393AudioBuffer::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() {
103103int32_t AudioBuffer::getBufsize () { return m_buffSize; }
104104
105105void 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
110111size_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// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
53465267void Audio::IIR_calculateCoefficients (int8_t G0, int8_t G1, int8_t G2) { // Infinite Impulse Response (IIR) filters
0 commit comments