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
1037680b
Unverified
Commit
1037680b
authored
Jul 16, 2022
by
Wolle
Committed by
GitHub
Jul 16, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
readMetadata() rewritten
parent
beb5ea49
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
44 additions
and
80 deletions
+44
-80
src/Audio.cpp
src/Audio.cpp
+39
-75
src/Audio.h
src/Audio.h
+5
-5
No files found.
src/Audio.cpp
View file @
1037680b
...
@@ -3,8 +3,8 @@
...
@@ -3,8 +3,8 @@
*
*
* Created on: Oct 26.2018
* Created on: Oct 26.2018
*
*
* Version 2.0.4
d
* Version 2.0.4
e
* Updated on: Jul 1
1
.2022
* Updated on: Jul 1
6
.2022
* Author: Wolle (schreibfaul1)
* Author: Wolle (schreibfaul1)
*
*
*/
*/
...
@@ -440,7 +440,7 @@ bool Audio::connecttohost(const char* host, const char* user, const char* pwd) {
...
@@ -440,7 +440,7 @@ bool Audio::connecttohost(const char* host, const char* user, const char* pwd) {
strcat
(
rqh
,
"GET "
);
strcat
(
rqh
,
"GET "
);
strcat
(
rqh
,
extension
);
strcat
(
rqh
,
extension
);
strcat
(
rqh
,
" HTTP/1.
0
\r\n
"
);
strcat
(
rqh
,
" HTTP/1.
1
\r\n
"
);
strcat
(
rqh
,
"Host: "
);
strcat
(
rqh
,
"Host: "
);
strcat
(
rqh
,
hostwoext
);
strcat
(
rqh
,
hostwoext
);
strcat
(
rqh
,
"
\r\n
"
);
strcat
(
rqh
,
"
\r\n
"
);
...
@@ -2338,7 +2338,7 @@ const char* Audio::parsePlaylist_M3U(){
...
@@ -2338,7 +2338,7 @@ const char* Audio::parsePlaylist_M3U(){
// AUDIO_INFO("Entry in playlist found: %s", pl);
// AUDIO_INFO("Entry in playlist found: %s", pl);
pos
=
indexOf
(
m_playlistContent
[
i
],
"http"
,
0
);
// Search for "http"
pos
=
indexOf
(
m_playlistContent
[
i
],
"http"
,
0
);
// Search for "http"
if
(
pos
>=
0
)
{
// Does URL contain "http://"?
if
(
pos
>=
0
)
{
// Does URL contain "http://"?
log_e
(
"%s pos=%i"
,
m_playlistContent
[
i
],
pos
);
//
log_e("%s pos=%i", m_playlistContent[i], pos);
host
=
m_playlistContent
[
i
]
+
pos
;
// Yes, set new host
host
=
m_playlistContent
[
i
]
+
pos
;
// Yes, set new host
break
;
break
;
}
}
...
@@ -2755,7 +2755,7 @@ void Audio::processLocalFile() {
...
@@ -2755,7 +2755,7 @@ void Audio::processLocalFile() {
void
Audio
::
processWebStream
()
{
void
Audio
::
processWebStream
()
{
const
uint16_t
maxFrameSize
=
InBuff
.
getMaxBlockSize
();
// every mp3/aac frame is not bigger
const
uint16_t
maxFrameSize
=
InBuff
.
getMaxBlockSize
();
// every mp3/aac frame is not bigger
int32_t
availableBytes
;
// available bytes in stream
uint32_t
availableBytes
;
// available bytes in stream
static
bool
f_tmr_1s
;
static
bool
f_tmr_1s
;
static
bool
f_stream
;
// first audio data received
static
bool
f_stream
;
// first audio data received
static
bool
f_webFileDataComplete
;
// all file data received
static
bool
f_webFileDataComplete
;
// all file data received
...
@@ -2765,7 +2765,6 @@ void Audio::processWebStream() {
...
@@ -2765,7 +2765,6 @@ void Audio::processWebStream() {
static
uint32_t
chunksize
;
// chunkcount read from stream
static
uint32_t
chunksize
;
// chunkcount read from stream
static
uint32_t
tmr_1s
;
// timer 1 sec
static
uint32_t
tmr_1s
;
// timer 1 sec
static
uint32_t
loopCnt
;
// count loops if clientbuffer is empty
static
uint32_t
loopCnt
;
// count loops if clientbuffer is empty
static
uint32_t
metacount
;
// counts down bytes between metadata
static
size_t
audioDataCount
;
// counts the decoded audiodata only
static
size_t
audioDataCount
;
// counts the decoded audiodata only
// first call, set some values to default - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// first call, set some values to default - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
...
@@ -2781,7 +2780,7 @@ void Audio::processWebStream() {
...
@@ -2781,7 +2780,7 @@ void Audio::processWebStream() {
audioDataCount
=
0
;
audioDataCount
=
0
;
tmr_1s
=
millis
();
tmr_1s
=
millis
();
m_t0
=
millis
();
m_t0
=
millis
();
metacount
=
m_metaint
;
m
_m
etacount
=
m_metaint
;
readMetadata
(
0
,
true
);
// reset all static vars
readMetadata
(
0
,
true
);
// reset all static vars
}
}
...
@@ -2840,51 +2839,14 @@ void Audio::processWebStream() {
...
@@ -2840,51 +2839,14 @@ void Audio::processWebStream() {
}
}
// if we have metadata: get them - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// if we have metadata: get them - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if
(
!
metacount
&&
!
m_f_swm
&&
availableBytes
){
if
(
!
m_metacount
&&
!
m_f_swm
){
static
uint16_t
pos_ml
=
0
;
// determines the current position in metaline
int
bytes
=
0
;
static
uint16_t
metalen
=
0
;
int
res
=
0
;
if
(
m_f_chunked
)
bytes
=
min
(
m_chunkcount
,
availableBytes
);
if
(
!
metalen
)
{
// First byte of metadata?
else
bytes
=
availableBytes
;
int
b
=
_client
->
read
();
res
=
readMetadata
(
bytes
);
if
(
m_f_chunked
)
m_chunkcount
--
;
if
(
m_f_chunked
)
m_chunkcount
-=
res
;
metalen
=
b
*
16
;
// New count for metadata including length byte
if
(
!
m_metacount
)
return
;
if
(
metalen
>
512
){
AUDIO_INFO
(
"Metadata block to long! Skipping all Metadata from now on."
);
m_f_swm
=
true
;
// expect stream without metadata
}
pos_ml
=
0
;
chbuf
[
pos_ml
]
=
0
;
// Prepare for new line
}
int
i
=
0
;
if
(
m_f_chunked
)
i
=
min
((
uint32_t
)
metalen
,
m_chunkcount
);
else
i
=
metalen
;
int
bytes
=
_client
->
readBytes
(
&
chbuf
[
pos_ml
],
i
);
if
(
m_f_chunked
)
m_chunkcount
-=
bytes
;
pos_ml
+=
bytes
;
if
(
pos_ml
==
metalen
)
{
metalen
=
0
;
chbuf
[
pos_ml
]
=
'\0'
;
pos_ml
=
0
;
metacount
=
m_metaint
;
if
(
strlen
(
chbuf
))
{
// Any info present?
// metaline contains artist and song name. For example:
// "StreamTitle='Don McLean - American Pie';StreamUrl='';"
// Sometimes it is just other info like:
// "StreamTitle='60s 03 05 Magic60s';StreamUrl='';"
// Isolate the StreamTitle, remove leading and trailing quotes if present.
// log_i("ST %s", metaline);
latinToUTF8
(
chbuf
,
sizeof
(
chbuf
));
// convert to UTF-8 if necessary
int
pos
=
indexOf
(
chbuf
,
"song_spot"
,
0
);
// remove some irrelevant infos
if
(
pos
>
3
)
{
// e.g. song_spot="T" MediaBaseId="0" itunesTrackId="0"
chbuf
[
pos
]
=
0
;
}
log_e
(
"%s"
,
chbuf
);
if
(
!
m_f_localfile
)
showstreamtitle
(
chbuf
);
// Show artist and title if present in metadata
}
}
return
;
}
}
// if the buffer is often almost empty issue a warning - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// if the buffer is often almost empty issue a warning - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
...
@@ -2913,7 +2875,7 @@ void Audio::processWebStream() {
...
@@ -2913,7 +2875,7 @@ void Audio::processWebStream() {
// buffer fill routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// buffer fill routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if
(
true
)
{
// statement has no effect
if
(
true
)
{
// statement has no effect
uint32_t
bytesCanBeWritten
=
InBuff
.
writeSpace
();
uint32_t
bytesCanBeWritten
=
InBuff
.
writeSpace
();
if
(
!
m_f_swm
)
bytesCanBeWritten
=
min
(
metacount
,
bytesCanBeWritten
);
if
(
!
m_f_swm
)
bytesCanBeWritten
=
min
(
m
_m
etacount
,
bytesCanBeWritten
);
if
(
m_f_chunked
)
bytesCanBeWritten
=
min
(
m_chunkcount
,
bytesCanBeWritten
);
if
(
m_f_chunked
)
bytesCanBeWritten
=
min
(
m_chunkcount
,
bytesCanBeWritten
);
int16_t
bytesAddedToBuffer
=
0
;
int16_t
bytesAddedToBuffer
=
0
;
...
@@ -2942,7 +2904,7 @@ void Audio::processWebStream() {
...
@@ -2942,7 +2904,7 @@ void Audio::processWebStream() {
if
(
bytesAddedToBuffer
>
0
)
{
if
(
bytesAddedToBuffer
>
0
)
{
if
(
m_f_webfile
)
byteCounter
+=
bytesAddedToBuffer
;
// Pull request #42
if
(
m_f_webfile
)
byteCounter
+=
bytesAddedToBuffer
;
// Pull request #42
if
(
!
m_f_swm
)
m
etacount
-=
bytesAddedToBuffer
;
if
(
!
m_f_swm
)
m
_metacount
-=
bytesAddedToBuffer
;
if
(
m_f_chunked
)
m_chunkcount
-=
bytesAddedToBuffer
;
if
(
m_f_chunked
)
m_chunkcount
-=
bytesAddedToBuffer
;
InBuff
.
bytesWritten
(
bytesAddedToBuffer
);
InBuff
.
bytesWritten
(
bytesAddedToBuffer
);
}
}
...
@@ -3032,7 +2994,7 @@ void Audio::processWebStream() {
...
@@ -3032,7 +2994,7 @@ void Audio::processWebStream() {
if
(
byteCounter
==
m_contentlength
){
if
(
byteCounter
==
m_contentlength
){
if
(
m_playlistFormat
==
FORMAT_M3U8
){
if
(
m_playlistFormat
==
FORMAT_M3U8
){
byteCounter
=
0
;
byteCounter
=
0
;
metacount
=
m_metaint
;
m
_m
etacount
=
m_metaint
;
m_f_continue
=
true
;
m_f_continue
=
true
;
return
;
return
;
}
}
...
@@ -3130,7 +3092,7 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque
...
@@ -3130,7 +3092,7 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque
idx
=
indexOf
(
rhl
,
"content-type:"
,
0
);
// content-type: text/html; charset=UTF-8
idx
=
indexOf
(
rhl
,
"content-type:"
,
0
);
// content-type: text/html; charset=UTF-8
if
(
idx
>=
0
)
{
if
(
idx
>=
0
)
{
AUDIO_INFO
(
"%s"
,
rhl
);
//
AUDIO_INFO("%s", rhl);
idx
=
indexOf
(
rhl
+
13
,
";"
);
idx
=
indexOf
(
rhl
+
13
,
";"
);
if
(
idx
>
0
)
rhl
[
13
+
idx
]
=
'\0'
;
if
(
idx
>
0
)
rhl
[
13
+
idx
]
=
'\0'
;
if
(
parseContentType
(
rhl
+
13
))
ct_seen
=
true
;
if
(
parseContentType
(
rhl
+
13
))
ct_seen
=
true
;
...
@@ -3250,7 +3212,6 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque
...
@@ -3250,7 +3212,6 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque
}
// outer while
}
// outer while
exit:
// termination condition
exit:
// termination condition
log_e
(
"exit"
);
if
(
audio_showstation
)
audio_showstation
(
""
);
if
(
audio_showstation
)
audio_showstation
(
""
);
if
(
audio_icydescription
)
audio_icydescription
(
""
);
if
(
audio_icydescription
)
audio_icydescription
(
""
);
if
(
audio_icyurl
)
audio_icyurl
(
""
);
if
(
audio_icyurl
)
audio_icyurl
(
""
);
...
@@ -3325,34 +3286,39 @@ bool Audio:: initializeDecoder(){
...
@@ -3325,34 +3286,39 @@ bool Audio:: initializeDecoder(){
return
false
;
return
false
;
}
}
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
bool
Audio
::
readMetadata
(
uint8_t
b
,
bool
first
)
{
uint16_t
Audio
::
readMetadata
(
uint16_t
maxBytes
,
bool
first
)
{
static
uint16_t
pos_ml
=
0
;
// determines the current position in metaline
static
uint16_t
pos_ml
=
0
;
// determines the current position in metaline
static
uint16_t
metalen
=
0
;
static
uint16_t
metalen
=
0
;
uint16_t
res
=
0
;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if
(
first
){
if
(
first
){
pos_ml
=
0
;
pos_ml
=
0
;
metalen
=
0
;
metalen
=
0
;
return
true
;
return
0
;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if
(
!
metalen
)
{
// First byte of metadata?
if
(
!
maxBytes
)
return
0
;
// guard
int
b
=
_client
->
read
();
metalen
=
b
*
16
+
1
;
// New count for metadata including length byte
if
(
!
metalen
)
{
if
(
metalen
>
512
){
int
b
=
_client
->
read
();
// First byte of metadata?
metalen
=
b
*
16
;
// New count for metadata including length byte
if
(
metalen
>
512
){
AUDIO_INFO
(
"Metadata block to long! Skipping all Metadata from now on."
);
AUDIO_INFO
(
"Metadata block to long! Skipping all Metadata from now on."
);
m_f_swm
=
true
;
// expect stream without metadata
m_f_swm
=
true
;
// expect stream without metadata
}
}
pos_ml
=
0
;
chbuf
[
pos_ml
]
=
0
;
// Prepare for new line
pos_ml
=
0
;
chbuf
[
pos_ml
]
=
0
;
// Prepare for new line
res
=
1
;
}
}
chbuf
[
pos_ml
]
=
(
char
)
b
;
// Put new char in +++++
if
(
!
metalen
)
{
m_metacount
=
m_metaint
;
return
res
;}
if
(
pos_ml
<
510
)
pos_ml
++
;
chbuf
[
pos_ml
]
=
0
;
if
(
pos_ml
==
509
)
{
log_e
(
"metaline overflow in AUDIO_METADATA! metaline=%s"
,
chbuf
);
}
if
(
pos_ml
==
510
)
{
;
/* last current char in b */
}
if
(
--
metalen
==
0
)
{
uint16_t
a
=
_client
->
readBytes
(
&
chbuf
[
pos_ml
],
min
(
metalen
,
(
uint16_t
)(
maxBytes
-
1
)));
res
+=
a
;
pos_ml
+=
a
;
if
(
pos_ml
==
metalen
)
{
metalen
=
0
;
chbuf
[
pos_ml
]
=
'\0'
;
m_metacount
=
m_metaint
;
if
(
strlen
(
chbuf
))
{
// Any info present?
if
(
strlen
(
chbuf
))
{
// Any info present?
// metaline contains artist and song name. For example:
// metaline contains artist and song name. For example:
// "StreamTitle='Don McLean - American Pie';StreamUrl='';"
// "StreamTitle='Don McLean - American Pie';StreamUrl='';"
...
@@ -3360,18 +3326,16 @@ bool Audio::readMetadata(uint8_t b, bool first) {
...
@@ -3360,18 +3326,16 @@ bool Audio::readMetadata(uint8_t b, bool first) {
// "StreamTitle='60s 03 05 Magic60s';StreamUrl='';"
// "StreamTitle='60s 03 05 Magic60s';StreamUrl='';"
// Isolate the StreamTitle, remove leading and trailing quotes if present.
// Isolate the StreamTitle, remove leading and trailing quotes if present.
// log_i("ST %s", metaline);
// log_i("ST %s", metaline);
latinToUTF8
(
chbuf
,
sizeof
(
chbuf
));
// convert to UTF-8 if necessary
latinToUTF8
(
chbuf
,
sizeof
(
chbuf
));
// convert to UTF-8 if necessary
int
pos
=
indexOf
(
chbuf
,
"song_spot"
,
0
);
// remove some irrelevant infos
int
pos
=
indexOf
(
chbuf
,
"song_spot"
,
0
);
// remove some irrelevant infos
if
(
pos
>
3
)
{
// e.g. song_spot="T" MediaBaseId="0" itunesTrackId="0"
if
(
pos
>
3
)
{
// e.g. song_spot="T" MediaBaseId="0" itunesTrackId="0"
chbuf
[
pos
]
=
0
;
chbuf
[
pos
]
=
0
;
}
}
if
(
!
m_f_localfile
)
showstreamtitle
(
chbuf
);
// Show artist and title if present in metadata
showstreamtitle
(
chbuf
);
// Show artist and title if present in metadata
}
}
return
true
;
pos_ml
=
0
;
}
}
return
false
;
// end_METADATA
return
res
;
}
}
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
bool
Audio
::
parseContentType
(
char
*
ct
)
{
bool
Audio
::
parseContentType
(
char
*
ct
)
{
...
...
src/Audio.h
View file @
1037680b
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* Audio.h
* Audio.h
*
*
* Created on: Oct 26,2018
* Created on: Oct 26,2018
* Updated on: Jul 1
1
,2022
* Updated on: Jul 1
6
,2022
* Author: Wolle (schreibfaul1)
* Author: Wolle (schreibfaul1)
*/
*/
...
@@ -248,7 +248,7 @@ private:
...
@@ -248,7 +248,7 @@ private:
bool
parseContentType
(
char
*
ct
);
bool
parseContentType
(
char
*
ct
);
bool
parseHttpResponseHeader
();
bool
parseHttpResponseHeader
();
bool
initializeDecoder
();
bool
initializeDecoder
();
bool
readMetadata
(
uint8
_t
b
,
bool
first
=
false
);
uint16_t
readMetadata
(
uint16
_t
b
,
bool
first
=
false
);
esp_err_t
I2Sstart
(
uint8_t
i2s_num
);
esp_err_t
I2Sstart
(
uint8_t
i2s_num
);
esp_err_t
I2Sstop
(
uint8_t
i2s_num
);
esp_err_t
I2Sstop
(
uint8_t
i2s_num
);
void
urlencode
(
char
*
buff
,
uint16_t
buffLen
,
bool
spacesOnly
=
false
);
void
urlencode
(
char
*
buff
,
uint16_t
buffLen
,
bool
spacesOnly
=
false
);
...
@@ -459,13 +459,13 @@ private:
...
@@ -459,13 +459,13 @@ private:
uint32_t
m_sampleRate
=
16000
;
uint32_t
m_sampleRate
=
16000
;
uint32_t
m_bitRate
=
0
;
// current bitrate given fom decoder
uint32_t
m_bitRate
=
0
;
// current bitrate given fom decoder
uint32_t
m_avr_bitrate
=
0
;
// average bitrate, median computed by VBR
uint32_t
m_avr_bitrate
=
0
;
// average bitrate, median computed by VBR
int
m_readbytes
=
0
;
// bytes read
int
m_readbytes
=
0
;
// bytes read
int
m_metalen
=
0
;
// Number of bytes i
n metadata
uint32_t
m_metacount
=
0
;
// counts down bytes betwee
n metadata
int
m_controlCounter
=
0
;
// Status within readID3data() and readWaveHeader()
int
m_controlCounter
=
0
;
// Status within readID3data() and readWaveHeader()
int8_t
m_balance
=
0
;
// -16 (mute left) ... +16 (mute right)
int8_t
m_balance
=
0
;
// -16 (mute left) ... +16 (mute right)
uint8_t
m_vol
=
64
;
// volume
uint8_t
m_vol
=
64
;
// volume
uint8_t
m_bitsPerSample
=
16
;
// bitsPerSample
uint8_t
m_bitsPerSample
=
16
;
// bitsPerSample
uint8_t
m_channels
=
2
;
uint8_t
m_channels
=
2
;
uint8_t
m_i2s_num
=
I2S_NUM_0
;
// I2S_NUM_0 or I2S_NUM_1
uint8_t
m_i2s_num
=
I2S_NUM_0
;
// I2S_NUM_0 or I2S_NUM_1
uint8_t
m_playlistFormat
=
0
;
// M3U, PLS, ASX
uint8_t
m_playlistFormat
=
0
;
// M3U, PLS, ASX
uint8_t
m_m3u8codec
=
CODEC_NONE
;
// M4A
uint8_t
m_m3u8codec
=
CODEC_NONE
;
// M4A
...
...
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