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
2b54e39a
Commit
2b54e39a
authored
Apr 04, 2024
by
schreibfaul1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new compute_audioCurrentTime()
and check for FLACMetadataBlock
parent
6b25ca00
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
75 additions
and
68 deletions
+75
-68
src/Audio.cpp
src/Audio.cpp
+65
-63
src/Audio.h
src/Audio.h
+4
-3
src/flac_decoder/flac_decoder.cpp
src/flac_decoder/flac_decoder.cpp
+6
-2
No files found.
src/Audio.cpp
View file @
2b54e39a
...
...
@@ -3,8 +3,8 @@
*
* Created on: Oct 26.2018
*
* Version 3.0.9
* Updated on: Apr 0
3
.2024
* Version 3.0.9
a
* Updated on: Apr 0
4
.2024
* Author: Wolle (schreibfaul1)
*
*/
...
...
@@ -329,8 +329,9 @@ void Audio::setDefaults() {
m_f_ssl
=
false
;
m_f_metadata
=
false
;
m_f_tts
=
false
;
m_f_firstCall
=
true
;
// InitSequence for processWebstream and processLokalFile
m_f_firstM3U8call
=
true
;
// InitSequence for parsePlaylist_M3U8
m_f_firstCall
=
true
;
// InitSequence for processWebstream and processLocalFile
m_f_firstCurTimeCall
=
true
;
// InitSequence for compute_audioCurrentTime
m_f_firstM3U8call
=
true
;
// InitSequence for parsePlaylist_M3U8
m_f_running
=
false
;
m_f_loop
=
false
;
// Set if audio file should loop
m_f_unsync
=
false
;
// set within ID3 tag but not used
...
...
@@ -3228,7 +3229,7 @@ void Audio::processWebFile() {
const
uint32_t
maxFrameSize
=
InBuff
.
getMaxBlockSize
();
// every mp3/aac frame is not bigger
static
bool
f_stream
;
// first audio data received
static
bool
f_webFileDataComplete
;
// all file data received
static
uint32_t
byteCounter
;
static
uint32_t
byteCounter
;
static
uint32_t
chunkSize
;
// chunkcount read from stream
static
size_t
audioDataCount
;
// counts the decoded audiodata only
...
...
@@ -4319,6 +4320,7 @@ void Audio::setDecoderItems() {
setBitrate
(
FLACGetBitRate
());
if
(
FLACGetAudioDataStart
()
>
0
){
// only flac-ogg, native flac sets audioDataStart in readFlacHeader()
m_audioDataStart
=
FLACGetAudioDataStart
();
if
(
getFileSize
())
m_audioDataSize
=
getFileSize
()
-
m_audioDataStart
;
}
}
if
(
m_codec
==
CODEC_OPUS
)
{
...
...
@@ -4328,6 +4330,7 @@ void Audio::setDecoderItems() {
setBitrate
(
OPUSGetBitRate
());
if
(
OPUSGetAudioDataStart
()
>
0
){
m_audioDataStart
=
OPUSGetAudioDataStart
();
if
(
getFileSize
())
m_audioDataSize
=
getFileSize
()
-
m_audioDataStart
;
}
}
if
(
m_codec
==
CODEC_VORBIS
)
{
...
...
@@ -4337,6 +4340,7 @@ void Audio::setDecoderItems() {
setBitrate
(
VORBISGetBitRate
());
if
(
VORBISGetAudioDataStart
()
>
0
){
m_audioDataStart
=
VORBISGetAudioDataStart
();
if
(
getFileSize
())
m_audioDataSize
=
getFileSize
()
-
m_audioDataStart
;
}
}
if
(
getBitsPerSample
()
!=
8
&&
getBitsPerSample
()
!=
16
)
{
...
...
@@ -4484,7 +4488,10 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
m_PlayingStartTime
=
millis
();
}
compute_audioCurrentTime
(
bytesDecoded
);
uint16_t
bytesDecoderOut
=
m_validSamples
;
if
(
m_channels
==
2
)
bytesDecoderOut
/=
2
;
if
(
m_bitsPerSample
==
16
)
bytesDecoderOut
*=
2
;
compute_audioCurrentTime
(
bytesDecoded
,
bytesDecoderOut
);
if
(
audio_process_extern
)
{
bool
continueI2S
=
false
;
...
...
@@ -4496,50 +4503,53 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
return
bytesDecoded
;
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void
Audio
::
compute_audioCurrentTime
(
int
bd
)
{
static
uint16_t
loop_counter
=
0
;
static
int
old_bitrate
=
0
;
static
uint64_t
sum_bitrate
=
0
;
static
boolean
f_CBR
=
true
;
// constant bitrate
static
uint8_t
cnt
=
0
;
if
(
m_codec
==
CODEC_MP3
)
{
setBitrate
(
MP3GetBitrate
());
}
// if not CBR, bitrate can be changed
if
(
m_codec
==
CODEC_M4A
)
{
setBitrate
(
AACGetBitrate
());
}
// if not CBR, bitrate can be changed
if
(
m_codec
==
CODEC_AAC
)
{
setBitrate
(
AACGetBitrate
());
}
// if not CBR, bitrate can be changed
if
(
m_codec
==
CODEC_FLAC
)
{
setBitrate
(
FLACGetBitRate
());
}
// if not CBR, bitrate can be changed
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if
(
m_avr_bitrate
==
0
)
{
// first time
loop_counter
=
1
;
old_bitrate
=
0
;
sum_bitrate
=
0
;
f_CBR
=
true
;
m_avr_bitrate
=
getBitRate
();
old_bitrate
=
getBitRate
();
cnt
=
0
;
}
if
(
!
getBitRate
())
return
;
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if
((
old_bitrate
!=
getBitRate
())
&&
f_CBR
)
{
if
(
audio_info
)
audio_info
(
"VBR recognized, audioFileDuration is estimated"
);
f_CBR
=
false
;
// variable bitrate
}
old_bitrate
=
getBitRate
();
if
(
loop_counter
<
10000
)
{
// then the bit rate is determined with sufficient precision
sum_bitrate
+=
getBitRate
();
m_avr_bitrate
=
sum_bitrate
/
loop_counter
;
loop_counter
++
;
}
m_audioCurrentTime
+=
((
float
)
bd
/
m_avr_bitrate
)
*
8
;
if
(
cnt
==
1
)
{
m_audioCurrentTime
=
((
float
)(
getFilePos
()
-
m_audioDataStart
-
inBufferFilled
())
/
m_avr_bitrate
)
*
8
;
// #293
}
cnt
++
;
if
(
cnt
==
100
)
cnt
=
0
;
void
Audio
::
compute_audioCurrentTime
(
uint16_t
bytesDecoderIn
,
uint16_t
bytesDecoderOut
)
{
if
(
getDatamode
()
!=
AUDIO_LOCALFILE
&&
m_streamType
!=
ST_WEBFILE
)
return
;
//guard
static
uint64_t
sumBytesIn
=
0
;
static
uint64_t
sumBytesOut
=
0
;
static
uint32_t
sumBitRate
=
0
;
static
uint32_t
counter
=
0
;
static
uint32_t
timeStamp
=
0
;
static
uint32_t
deltaBytesIn
=
0
;
static
float
audioCurrentTime
=
0
;
float
compressionRatio
=
0
;
if
(
m_f_firstCurTimeCall
)
{
// first call
m_f_firstCurTimeCall
=
false
;
sumBytesIn
=
0
;
sumBytesOut
=
0
;
sumBitRate
=
0
;
counter
=
0
;
timeStamp
=
millis
();
deltaBytesIn
=
0
;
audioCurrentTime
=
0
;
}
sumBytesIn
+=
bytesDecoderIn
;
deltaBytesIn
+=
bytesDecoderIn
;
sumBytesOut
+=
bytesDecoderOut
;
if
(
timeStamp
+
950
<
millis
()){
// compressionRatio = (float)sumBytesIn / sumBytesOut;
(
void
)
compressionRatio
;
// unused yet
uint32_t
t
=
millis
();
uint32_t
delta_t
=
t
-
timeStamp
;
timeStamp
=
t
;
// we know the time and bytesIn to compute the bitrate
uint32_t
bitRate
=
((
deltaBytesIn
*
8000
)
/
delta_t
);
sumBitRate
+=
bitRate
;
counter
++
;
m_avr_bitrate
=
sumBitRate
/
counter
;
audioCurrentTime
+=
((
float
)(
deltaBytesIn
*
8
)
/
m_avr_bitrate
);
m_audioCurrentTime
=
audioCurrentTime
;
deltaBytesIn
=
0
;
}
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void
Audio
::
printProcessLog
(
int
r
,
const
char
*
s
){
...
...
@@ -4706,13 +4716,10 @@ bool Audio::setPinout(uint8_t BCLK, uint8_t LRC, uint8_t DOUT, int8_t MCLK) {
return
(
result
==
ESP_OK
);
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint32_t
Audio
::
getFileSize
()
{
uint32_t
Audio
::
getFileSize
()
{
// returns the size of webfile or local file
if
(
!
audiofile
)
{
if
(
m_contentlength
>
0
)
{
return
m_contentlength
;
}
else
{
return
0
;
}
if
(
m_contentlength
>
0
)
{
return
m_contentlength
;}
return
0
;
}
return
audiofile
.
size
();
}
...
...
@@ -4735,13 +4742,8 @@ uint32_t Audio::getAudioFileDuration() {
if
(
!
m_contentlength
)
return
0
;
}
if
(
m_avr_bitrate
&&
m_codec
==
CODEC_MP3
)
m_audioFileDuration
=
8
*
((
float
)
m_audioDataSize
/
m_avr_bitrate
);
// #289
else
if
(
m_avr_bitrate
&&
m_codec
==
CODEC_WAV
)
m_audioFileDuration
=
8
*
((
float
)
m_audioDataSize
/
m_avr_bitrate
);
else
if
(
m_avr_bitrate
&&
m_codec
==
CODEC_M4A
)
m_audioFileDuration
=
8
*
((
float
)
m_audioDataSize
/
m_avr_bitrate
);
else
if
(
m_avr_bitrate
&&
m_codec
==
CODEC_AAC
)
m_audioFileDuration
=
8
*
((
float
)
m_audioDataSize
/
m_avr_bitrate
);
else
if
(
m_codec
==
CODEC_FLAC
)
m_audioFileDuration
=
FLACGetAudioFileDuration
();
else
return
0
;
return
m_audioFileDuration
;
if
(
!
m_avr_bitrate
)
return
0
;
return
m_audioFileDuration
=
8
*
((
float
)
m_audioDataSize
/
m_avr_bitrate
);
}
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint32_t
Audio
::
getAudioCurrentTime
()
{
// return current time in seconds
...
...
src/Audio.h
View file @
2b54e39a
...
...
@@ -3,8 +3,8 @@
*
* Created on: Oct 28,2018
*
* Version 3.0.9
* Updated on: Apr 0
3
.2024
* Version 3.0.9
a
* Updated on: Apr 0
4
.2024
* Author: Wolle (schreibfaul1)
*/
...
...
@@ -210,7 +210,7 @@ private:
int
findNextSync
(
uint8_t
*
data
,
size_t
len
);
int
sendBytes
(
uint8_t
*
data
,
size_t
len
);
void
setDecoderItems
();
void
compute_audioCurrentTime
(
int
bd
);
void
compute_audioCurrentTime
(
uint16_t
bytesDecoderIn
,
uint16_t
bytesDecoderOut
);
void
printProcessLog
(
int
r
,
const
char
*
s
=
""
);
void
printDecodeError
(
int
r
);
void
showID3Tag
(
const
char
*
tag
,
const
char
*
val
);
...
...
@@ -553,6 +553,7 @@ private:
bool
m_f_ssl
=
false
;
bool
m_f_running
=
false
;
bool
m_f_firstCall
=
false
;
// InitSequence for processWebstream and processLokalFile
bool
m_f_firstCurTimeCall
=
false
;
// InitSequence for compute_audioCurrentTime
bool
m_f_firstM3U8call
=
false
;
// InitSequence for m3u8 parsing
bool
m_f_chunked
=
false
;
// Station provides chunked transfer
bool
m_f_firstmetabyte
=
false
;
// True if first metabyte (counter)
...
...
src/flac_decoder/flac_decoder.cpp
View file @
2b54e39a
...
...
@@ -4,7 +4,7 @@
* adapted to ESP32
*
* Created on: Jul 03,2020
* Updated on: Apr 0
3
,2024
* Updated on: Apr 0
4
,2024
*
* Author: Wolle
*
...
...
@@ -845,18 +845,22 @@ uint16_t FLACGetOutputSamps(){
}
//----------------------------------------------------------------------------------------------------------------------
uint64_t
FLACGetTotoalSamplesInStream
(){
if
(
!
FLACMetadataBlock
)
return
0
;
return
FLACMetadataBlock
->
totalSamples
;
}
//----------------------------------------------------------------------------------------------------------------------
uint8_t
FLACGetBitsPerSample
(){
if
(
!
FLACMetadataBlock
)
return
0
;
return
FLACMetadataBlock
->
bitsPerSample
;
}
//----------------------------------------------------------------------------------------------------------------------
uint8_t
FLACGetChannels
(){
if
(
!
FLACMetadataBlock
)
return
0
;
return
FLACMetadataBlock
->
numChannels
;
}
//----------------------------------------------------------------------------------------------------------------------
uint32_t
FLACGetSampRate
(){
if
(
!
FLACMetadataBlock
)
return
0
;
return
FLACMetadataBlock
->
sampleRate
;
}
//----------------------------------------------------------------------------------------------------------------------
...
...
@@ -869,7 +873,7 @@ uint32_t FLACGetAudioDataStart(){
}
//----------------------------------------------------------------------------------------------------------------------
uint32_t
FLACGetAudioFileDuration
()
{
if
(
FLACGetSampRate
()){
if
(
FLACGetSampRate
()){
// DIV0
uint32_t
afd
=
FLACGetTotoalSamplesInStream
()
/
FLACGetSampRate
();
// AudioFileDuration
return
afd
;
}
...
...
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