Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
ESP32-audioI2S
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
ESP32-audioI2S
Commits
17fb2b85
Commit
17fb2b85
authored
Mar 31, 2024
by
schreibfaul1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
error management part1
parent
e0135a45
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
127 additions
and
140 deletions
+127
-140
src/Audio.cpp
src/Audio.cpp
+45
-61
src/Audio.h
src/Audio.h
+82
-79
No files found.
src/Audio.cpp
View file @
17fb2b85
...
...
@@ -3,8 +3,8 @@
*
* Created on: Oct 26.2018
*
* Version 3.0.8
t
* Updated on: Mar
28
.2024
* Version 3.0.8
u
* Updated on: Mar
31
.2024
* Author: Wolle (schreibfaul1)
*
*/
...
...
@@ -810,7 +810,7 @@ void Audio::UTF8toASCII(char* str) {
bool
Audio
::
connecttoFS
(
fs
::
FS
&
fs
,
const
char
*
path
,
int32_t
resumeFilePos
)
{
if
(
!
path
)
{
// guard
AUDIO_INFO
(
"The given path is empty"
);
printProcessLog
(
AUDIOLOG_PATH_IS_NULL
);
return
false
;
}
...
...
@@ -819,70 +819,31 @@ bool Audio::connecttoFS(fs::FS& fs, const char* path, int32_t resumeFilePos) {
m_resumeFilePos
=
resumeFilePos
;
setDefaults
();
// free buffers an set defaults
{
// open audiofile scope
const
char
*
audioName
=
nullptr
;
// pointer for the final file path
char
*
audioNameAlternative
=
nullptr
;
// possible buffer for alternative versions of the audioName
if
(
fs
.
exists
(
path
))
{
// use given path if it exists (issue #86)
audioName
=
path
;
}
else
{
// try alternative path variants
size_t
len
=
strlen
(
path
);
size_t
copyMemSize
=
len
+
2
;
// 2 extra bytes for possible leading / and \0 terminator
size_t
copyOffset
=
0
;
audioNameAlternative
=
(
char
*
)
__malloc_heap_psram
(
copyMemSize
);
if
(
!
audioNameAlternative
)
{
log_e
(
"out of memory"
);
xSemaphoreGiveRecursive
(
mutex_audio
);
return
false
;
}
// make sure the path starts with a /
if
(
path
[
0
]
!=
'/'
)
{
audioNameAlternative
[
0
]
=
'/'
;
copyOffset
=
1
;
}
// copy original path to audioNameAlternative buffer
strncpy
(
audioNameAlternative
+
copyOffset
,
path
,
copyMemSize
-
copyOffset
);
if
(
fs
.
exists
(
audioNameAlternative
))
{
// use path with extra leading / if it exists
audioName
=
audioNameAlternative
;
}
else
{
// use ASCII version of the path if it exists
UTF8toASCII
(
audioNameAlternative
);
if
(
fs
.
exists
(
audioNameAlternative
))
{
audioName
=
audioNameAlternative
;
}
}
}
char
*
audioPath
=
(
char
*
)
__malloc_heap_psram
(
strlen
(
path
)
+
2
);
if
(
!
audioPath
){
printProcessLog
(
AUDIOLOG_OUT_OF_MEMORY
);
xSemaphoreGiveRecursive
(
mutex_audio
);
return
false
;
}
if
(
path
[
0
]
==
'/'
){
strcpy
(
audioPath
,
path
);}
else
{
audioPath
[
0
]
=
'/'
;
strcpy
(
audioPath
+
1
,
path
);}
if
(
!
audioName
)
{
AUDIO_INFO
(
"File doesn't exist:
\"
%s
\"
"
,
path
);
if
(
!
fs
.
exists
(
audioPath
))
{
UTF8toASCII
(
audioPath
);
if
(
!
fs
.
exists
(
audioPath
)){
printProcessLog
(
AUDIOLOG_FILE_NOT_FOUND
,
audioPath
);
xSemaphoreGiveRecursive
(
mutex_audio
);
if
(
audioNameAlternative
)
{
free
(
audioNameAlternative
);
}
free
(
audioPath
);
return
false
;
}
AUDIO_INFO
(
"Reading file:
\"
%s
\"
"
,
audioName
);
vTaskDelay
(
2
);
audiofile
=
fs
.
open
(
audioName
);
// free audioNameAlternative if used
if
(
audioNameAlternative
)
{
free
(
audioNameAlternative
);
}
}
AUDIO_INFO
(
"Reading file:
\"
%s
\"
"
,
audioPath
);
audiofile
=
fs
.
open
(
audioPath
);
if
(
!
audiofile
)
{
if
(
audio_info
)
{
vTaskDelay
(
2
);
audio_info
(
"Failed to open file for reading"
);
}
printProcessLog
(
AUDIOLOG_FILE_READ_ERR
,
audioPath
);
free
(
audioPath
);
xSemaphoreGiveRecursive
(
mutex_audio
);
return
false
;
}
...
...
@@ -911,6 +872,7 @@ bool Audio::connecttoFS(fs::FS& fs, const char* path, int32_t resumeFilePos) {
free
(
afn
);
afn
=
NULL
;
}
free
(
audioPath
);
bool
ret
=
initializeDecoder
();
if
(
ret
)
m_f_running
=
true
;
...
...
@@ -4562,6 +4524,28 @@ void Audio::compute_audioCurrentTime(int bd) {
cnt
++
;
if
(
cnt
==
100
)
cnt
=
0
;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void
Audio
::
printProcessLog
(
int
r
,
const
char
*
s
){
const
char
*
e
;
const
char
*
f
=
""
;
uint8_t
logLevel
;
// 1 Error, 2 Warn, 3 Info,
switch
(
r
)
{
case
AUDIOLOG_PATH_IS_NULL
:
e
=
"The path ore file name is empty"
;
logLevel
=
1
;
break
;
case
AUDIOLOG_OUT_OF_MEMORY
:
e
=
"Out of memory"
;
logLevel
=
1
;
break
;
case
AUDIOLOG_FILE_NOT_FOUND
:
e
=
"File doesn't exist: "
;
logLevel
=
1
;
f
=
s
;
break
;
case
AUDIOLOG_FILE_READ_ERR
:
e
=
"Failed to open file for reading"
;
logLevel
=
1
;
break
;
default:
e
=
"UNKNOWN EVENT"
;
logLevel
=
3
;
break
;
}
if
(
audio_log
){
audio_log
(
logLevel
,
e
,
f
);
}
else
{
if
(
logLevel
==
1
)
{
AUDIO_INFO
(
"ERROR: %s%s"
,
e
,
f
);}
else
if
(
logLevel
==
2
)
{
AUDIO_INFO
(
"WARNING: %s%s"
,
e
,
f
);}
else
{
AUDIO_INFO
(
"INFO: %s%s"
,
e
,
f
);}
}
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void
Audio
::
printDecodeError
(
int
r
)
{
const
char
*
e
;
...
...
@@ -4829,8 +4813,8 @@ bool Audio::setSampleRate(uint32_t sampRate) {
if
(
m_sampleRate
==
sampRate
)
return
true
;
m_sampleRate
=
sampRate
;
#if ESP_IDF_VERSION_MAJOR == 5
m_i2s_std_cfg
.
clk_cfg
.
sample_rate_hz
=
sampRate
;
I2Sstop
(
0
);
m_i2s_std_cfg
.
clk_cfg
.
sample_rate_hz
=
sampRate
;
i2s_channel_reconfig_std_clock
(
m_i2s_tx_handle
,
&
m_i2s_std_cfg
.
clk_cfg
);
I2Sstart
(
0
);
#else
...
...
src/Audio.h
View file @
17fb2b85
...
...
@@ -3,8 +3,8 @@
*
* Created on: Oct 28,2018
*
* Version 3.0.8
s
* Updated on: Mar
23
.2024
* Version 3.0.8
u
* Updated on: Mar
31
.2024
* Author: Wolle (schreibfaul1)
*/
...
...
@@ -52,6 +52,7 @@ extern __attribute__((weak)) void audio_eof_speech(const char*);
extern
__attribute__
((
weak
))
void
audio_eof_stream
(
const
char
*
);
// The webstream comes to an end
extern
__attribute__
((
weak
))
void
audio_process_extern
(
int16_t
*
buff
,
uint16_t
len
,
bool
*
continueI2S
);
// record audiodata or send via BT
extern
__attribute__
((
weak
))
void
audio_process_i2s
(
uint32_t
*
sample
,
bool
*
continueI2S
);
// record audiodata or send via BT
extern
__attribute__
((
weak
))
void
audio_log
(
uint8_t
logLevel
,
const
char
*
msg
,
const
char
*
arg
);
//----------------------------------------------------------------------------------------------------------------------
...
...
@@ -184,83 +185,85 @@ private:
#define ESP_ARDUINO_VERSION_PATCH 0
#endif
void
UTF8toASCII
(
char
*
str
);
bool
latinToUTF8
(
char
*
buff
,
size_t
bufflen
);
void
setDefaults
();
// free buffers and set defaults
void
initInBuff
();
bool
httpPrint
(
const
char
*
host
);
void
processLocalFile
();
void
processWebStream
();
void
processWebFile
();
void
processWebStreamTS
();
void
processWebStreamHLS
();
void
playAudioData
();
bool
readPlayListData
();
const
char
*
parsePlaylist_M3U
();
const
char
*
parsePlaylist_PLS
();
const
char
*
parsePlaylist_ASX
();
const
char
*
parsePlaylist_M3U8
();
const
char
*
m3u8redirection
();
uint64_t
m3u8_findMediaSeqInURL
();
bool
STfromEXTINF
(
char
*
str
);
void
showCodecParams
();
int
findNextSync
(
uint8_t
*
data
,
size_t
len
);
int
sendBytes
(
uint8_t
*
data
,
size_t
len
);
void
setDecoderItems
();
void
compute_audioCurrentTime
(
int
bd
);
void
printDecodeError
(
int
r
);
void
showID3Tag
(
const
char
*
tag
,
const
char
*
val
);
size_t
readAudioHeader
(
uint32_t
bytes
);
int
read_WAV_Header
(
uint8_t
*
data
,
size_t
len
);
int
read_FLAC_Header
(
uint8_t
*
data
,
size_t
len
);
int
read_ID3_Header
(
uint8_t
*
data
,
size_t
len
);
int
read_M4A_Header
(
uint8_t
*
data
,
size_t
len
);
size_t
process_m3u8_ID3_Header
(
uint8_t
*
packet
);
bool
setSampleRate
(
uint32_t
hz
);
bool
setBitsPerSample
(
int
bits
);
bool
setChannels
(
int
channels
);
bool
setBitrate
(
int
br
);
void
playChunk
();
bool
playSample
(
int16_t
sample
[
2
]);
void
computeVUlevel
(
int16_t
sample
[
2
]);
void
computeLimit
();
int32_t
Gain
(
int16_t
s
[
2
]);
void
showstreamtitle
(
const
char
*
ml
);
bool
parseContentType
(
char
*
ct
);
bool
parseHttpResponseHeader
();
bool
initializeDecoder
();
esp_err_t
I2Sstart
(
uint8_t
i2s_num
);
esp_err_t
I2Sstop
(
uint8_t
i2s_num
);
void
urlencode
(
char
*
buff
,
uint16_t
buffLen
,
bool
spacesOnly
=
false
);
int16_t
*
IIR_filterChain0
(
int16_t
iir_in
[
2
],
bool
clear
=
false
);
int16_t
*
IIR_filterChain1
(
int16_t
iir_in
[
2
],
bool
clear
=
false
);
int16_t
*
IIR_filterChain2
(
int16_t
iir_in
[
2
],
bool
clear
=
false
);
inline
void
setDatamode
(
uint8_t
dm
){
m_datamode
=
dm
;}
inline
uint8_t
getDatamode
(){
return
m_datamode
;}
inline
uint32_t
streamavail
(){
return
_client
?
_client
->
available
()
:
0
;}
void
IIR_calculateCoefficients
(
int8_t
G1
,
int8_t
G2
,
int8_t
G3
);
bool
ts_parsePacket
(
uint8_t
*
packet
,
uint8_t
*
packetStart
,
uint8_t
*
packetLength
);
//+++ W E B S T R E A M - H E L P F U N C T I O N S +++
uint16_t
readMetadata
(
uint16_t
b
,
bool
first
=
false
);
size_t
chunkedDataTransfer
(
uint8_t
*
bytes
);
bool
readID3V1Tag
();
boolean
streamDetection
(
uint32_t
bytesAvail
);
void
seek_m4a_stsz
();
void
seek_m4a_ilst
();
uint32_t
m4a_correctResumeFilePos
(
uint32_t
resumeFilePos
);
uint32_t
flac_correctResumeFilePos
(
uint32_t
resumeFilePos
);
uint32_t
mp3_correctResumeFilePos
(
uint32_t
resumeFilePos
);
uint8_t
determineOggCodec
(
uint8_t
*
data
,
uint16_t
len
);
//++++ implement several function with respect to the index of string ++++
void
strlower
(
char
*
str
){
unsigned
char
*
p
=
(
unsigned
char
*
)
str
;
while
(
*
p
)
{
*
p
=
tolower
((
unsigned
char
)
*
p
);
p
++
;
}
enum
:
int8_t
{
AUDIOLOG_PATH_IS_NULL
=
-
1
,
AUDIOLOG_FILE_NOT_FOUND
=
-
2
,
AUDIOLOG_OUT_OF_MEMORY
=
-
3
,
AUDIOLOG_FILE_READ_ERR
=
-
4
,
AUDIOLOG_ERR_UNKNOWN
=
-
127
};
void
UTF8toASCII
(
char
*
str
);
bool
latinToUTF8
(
char
*
buff
,
size_t
bufflen
);
void
setDefaults
();
// free buffers and set defaults
void
initInBuff
();
bool
httpPrint
(
const
char
*
host
);
void
processLocalFile
();
void
processWebStream
();
void
processWebFile
();
void
processWebStreamTS
();
void
processWebStreamHLS
();
void
playAudioData
();
bool
readPlayListData
();
const
char
*
parsePlaylist_M3U
();
const
char
*
parsePlaylist_PLS
();
const
char
*
parsePlaylist_ASX
();
const
char
*
parsePlaylist_M3U8
();
const
char
*
m3u8redirection
();
uint64_t
m3u8_findMediaSeqInURL
();
bool
STfromEXTINF
(
char
*
str
);
void
showCodecParams
();
int
findNextSync
(
uint8_t
*
data
,
size_t
len
);
int
sendBytes
(
uint8_t
*
data
,
size_t
len
);
void
setDecoderItems
();
void
compute_audioCurrentTime
(
int
bd
);
void
printProcessLog
(
int
r
,
const
char
*
s
=
""
);
void
printDecodeError
(
int
r
);
void
showID3Tag
(
const
char
*
tag
,
const
char
*
val
);
size_t
readAudioHeader
(
uint32_t
bytes
);
int
read_WAV_Header
(
uint8_t
*
data
,
size_t
len
);
int
read_FLAC_Header
(
uint8_t
*
data
,
size_t
len
);
int
read_ID3_Header
(
uint8_t
*
data
,
size_t
len
);
int
read_M4A_Header
(
uint8_t
*
data
,
size_t
len
);
size_t
process_m3u8_ID3_Header
(
uint8_t
*
packet
);
bool
setSampleRate
(
uint32_t
hz
);
bool
setBitsPerSample
(
int
bits
);
bool
setChannels
(
int
channels
);
bool
setBitrate
(
int
br
);
void
playChunk
();
bool
playSample
(
int16_t
sample
[
2
]);
void
computeVUlevel
(
int16_t
sample
[
2
]);
void
computeLimit
();
int32_t
Gain
(
int16_t
s
[
2
]);
void
showstreamtitle
(
const
char
*
ml
);
bool
parseContentType
(
char
*
ct
);
bool
parseHttpResponseHeader
();
bool
initializeDecoder
();
esp_err_t
I2Sstart
(
uint8_t
i2s_num
);
esp_err_t
I2Sstop
(
uint8_t
i2s_num
);
void
urlencode
(
char
*
buff
,
uint16_t
buffLen
,
bool
spacesOnly
=
false
);
int16_t
*
IIR_filterChain0
(
int16_t
iir_in
[
2
],
bool
clear
=
false
);
int16_t
*
IIR_filterChain1
(
int16_t
iir_in
[
2
],
bool
clear
=
false
);
int16_t
*
IIR_filterChain2
(
int16_t
iir_in
[
2
],
bool
clear
=
false
);
inline
void
setDatamode
(
uint8_t
dm
)
{
m_datamode
=
dm
;
}
inline
uint8_t
getDatamode
()
{
return
m_datamode
;
}
inline
uint32_t
streamavail
()
{
return
_client
?
_client
->
available
()
:
0
;
}
void
IIR_calculateCoefficients
(
int8_t
G1
,
int8_t
G2
,
int8_t
G3
);
bool
ts_parsePacket
(
uint8_t
*
packet
,
uint8_t
*
packetStart
,
uint8_t
*
packetLength
);
//+++ W E B S T R E A M - H E L P F U N C T I O N S +++
uint16_t
readMetadata
(
uint16_t
b
,
bool
first
=
false
);
size_t
chunkedDataTransfer
(
uint8_t
*
bytes
);
bool
readID3V1Tag
();
boolean
streamDetection
(
uint32_t
bytesAvail
);
void
seek_m4a_stsz
();
void
seek_m4a_ilst
();
uint32_t
m4a_correctResumeFilePos
(
uint32_t
resumeFilePos
);
uint32_t
flac_correctResumeFilePos
(
uint32_t
resumeFilePos
);
uint32_t
mp3_correctResumeFilePos
(
uint32_t
resumeFilePos
);
uint8_t
determineOggCodec
(
uint8_t
*
data
,
uint16_t
len
);
//++++ implement several function with respect to the index of string ++++
void
strlower
(
char
*
str
)
{
unsigned
char
*
p
=
(
unsigned
char
*
)
str
;
while
(
*
p
)
{
*
p
=
tolower
((
unsigned
char
)
*
p
);
p
++
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment