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
dda1071b
Unverified
Commit
dda1071b
authored
Jan 27, 2023
by
Wolle
Committed by
GitHub
Jan 27, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add files via upload
parent
cf8dea21
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
64 additions
and
9 deletions
+64
-9
src/Audio.cpp
src/Audio.cpp
+62
-8
src/Audio.h
src/Audio.h
+2
-1
No files found.
src/Audio.cpp
View file @
dda1071b
...
...
@@ -4,7 +4,7 @@
* Created on: Oct 26.2018
*
* Version 2.0.8d
* Updated on: Jan
13
.2023
* Updated on: Jan
27
.2023
* Author: Wolle (schreibfaul1)
*
*/
...
...
@@ -12,6 +12,7 @@
#include "mp3_decoder/mp3_decoder.h"
#include "aac_decoder/aac_decoder.h"
#include "flac_decoder/flac_decoder.h"
#include "opus_decoder/opus_decoder.h"
#ifdef SDFATFS_USED
fs
::
SDFATFS
SD_SDFAT
;
...
...
@@ -310,6 +311,7 @@ void Audio::setDefaults() {
MP3Decoder_FreeBuffers
();
FLACDecoder_FreeBuffers
();
AACDecoder_FreeBuffers
();
OPUSDecoder_FreeBuffers
();
if
(
m_playlistBuff
)
{
free
(
m_playlistBuff
);
m_playlistBuff
=
NULL
;}
// free if stream is not m3u8
vector_clear_and_shrink
(
m_playlistURL
);
vector_clear_and_shrink
(
m_playlistContent
);
...
...
@@ -503,6 +505,8 @@ bool Audio::connecttohost(const char* host, const char* user, const char* pwd) {
if
(
endsWith
(
extension
,
".wav"
))
m_expectedCodec
=
CODEC_WAV
;
if
(
endsWith
(
extension
,
".m4a"
))
m_expectedCodec
=
CODEC_M4A
;
if
(
endsWith
(
extension
,
".flac"
))
m_expectedCodec
=
CODEC_FLAC
;
if
(
endsWith
(
extension
,
".opus"
))
m_expectedCodec
=
CODEC_OPUS
;
if
(
endsWith
(
extension
,
"/opus"
))
m_expectedCodec
=
CODEC_OPUS
;
if
(
endsWith
(
extension
,
".asx"
))
m_expectedPlsFmt
=
FORMAT_ASX
;
if
(
endsWith
(
extension
,
".m3u"
))
m_expectedPlsFmt
=
FORMAT_M3U
;
if
(
endsWith
(
extension
,
".m3u8"
))
m_expectedPlsFmt
=
FORMAT_M3U8
;
...
...
@@ -738,6 +742,7 @@ bool Audio::connecttoFS(fs::FS &fs, const char* path, uint32_t resumeFilePos) {
if
(
endsWith
(
afn
,
".aac"
))
m_codec
=
CODEC_AAC
;
if
(
endsWith
(
afn
,
".wav"
))
m_codec
=
CODEC_WAV
;
if
(
endsWith
(
afn
,
".flac"
))
m_codec
=
CODEC_FLAC
;
if
(
endsWith
(
afn
,
".opus"
))
m_codec
=
CODEC_OPUS
;
if
(
m_codec
==
CODEC_NONE
)
AUDIO_INFO
(
"The %s format is not supported"
,
afn
+
dotPos
);
...
...
@@ -1191,6 +1196,9 @@ size_t Audio::readAudioHeader(uint32_t bytes){
m_controlCounter
=
100
;
}
}
if
(
m_codec
==
CODEC_OPUS
){
m_controlCounter
=
100
;
}
if
(
!
isRunning
()){
log_e
(
"Processing stopped due to invalid audio header"
);
return
0
;
...
...
@@ -2811,6 +2819,7 @@ void Audio::processLocalFile() {
if
(
m_codec
==
CODEC_AAC
)
AACDecoder_FreeBuffers
();
if
(
m_codec
==
CODEC_M4A
)
AACDecoder_FreeBuffers
();
if
(
m_codec
==
CODEC_FLAC
)
FLACDecoder_FreeBuffers
();
if
(
m_codec
==
CODEC_OPUS
)
OPUSDecoder_FreeBuffers
();
AUDIO_INFO
(
"End of file
\"
%s
\"
"
,
afn
);
if
(
audio_eof_mp3
)
audio_eof_mp3
(
afn
);
if
(
afn
)
{
free
(
afn
);
afn
=
NULL
;}
...
...
@@ -3282,6 +3291,7 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque
}
else
if
(
startsWith
(
rhl
,
"content-type:"
)){
// content-type: text/html; charset=UTF-8
log_i
(
"cT: %s"
,
rhl
);
int
idx
=
indexOf
(
rhl
+
13
,
";"
);
if
(
idx
>
0
)
rhl
[
13
+
idx
]
=
'\0'
;
if
(
parseContentType
(
rhl
+
13
))
ct_seen
=
true
;
...
...
@@ -3445,20 +3455,29 @@ bool Audio::parseHttpResponseHeader() { // this is the response to a GET / reque
bool
Audio
::
initializeDecoder
(){
switch
(
m_codec
){
case
CODEC_MP3
:
if
(
!
MP3Decoder_AllocateBuffers
())
goto
exit
;
if
(
!
MP3Decoder_AllocateBuffers
()){
AUDIO_INFO
(
"The MP3Decoder could not be initialized"
);
goto
exit
;
}
AUDIO_INFO
(
"MP3Decoder has been initialized, free Heap: %u bytes"
,
ESP
.
getFreeHeap
());
InBuff
.
changeMaxBlockSize
(
m_frameSizeMP3
);
break
;
case
CODEC_AAC
:
if
(
!
AACDecoder_IsInit
()){
if
(
!
AACDecoder_AllocateBuffers
())
goto
exit
;
if
(
!
AACDecoder_AllocateBuffers
()){
AUDIO_INFO
(
"The AACDecoder could not be initialized"
);
goto
exit
;
}
AUDIO_INFO
(
"AACDecoder has been initialized, free Heap: %u bytes"
,
ESP
.
getFreeHeap
());
InBuff
.
changeMaxBlockSize
(
m_frameSizeAAC
);
}
break
;
case
CODEC_M4A
:
if
(
!
AACDecoder_IsInit
()){
if
(
!
AACDecoder_AllocateBuffers
())
goto
exit
;
if
(
!
AACDecoder_AllocateBuffers
()){
AUDIO_INFO
(
"The AACDecoder could not be initialized"
);
goto
exit
;
}
AUDIO_INFO
(
"AACDecoder has been initialized, free Heap: %u bytes"
,
ESP
.
getFreeHeap
());
InBuff
.
changeMaxBlockSize
(
m_frameSizeAAC
);
}
...
...
@@ -3468,10 +3487,22 @@ bool Audio:: initializeDecoder(){
AUDIO_INFO
(
"FLAC works only with PSRAM!"
);
goto
exit
;
}
if
(
!
FLACDecoder_AllocateBuffers
())
goto
exit
;
if
(
!
FLACDecoder_AllocateBuffers
()){
AUDIO_INFO
(
"The FLACDecoder could not be initialized"
);
goto
exit
;
}
InBuff
.
changeMaxBlockSize
(
m_frameSizeFLAC
);
AUDIO_INFO
(
"FLACDecoder has been initialized, free Heap: %u bytes"
,
ESP
.
getFreeHeap
());
break
;
case
CODEC_OPUS
:
if
(
!
OPUSDecoder_AllocateBuffers
()){
AUDIO_INFO
(
"The OPUSDecoder could not be initialized"
);
goto
exit
;
}
AUDIO_INFO
(
"OPUSDecoder has been initialized, free Heap: %u bytes"
,
ESP
.
getFreeHeap
());
InBuff
.
changeMaxBlockSize
(
m_frameSizeOPUS
);
break
;
case
CODEC_WAV
:
InBuff
.
changeMaxBlockSize
(
m_frameSizeWav
);
break
;
...
...
@@ -3489,7 +3520,7 @@ bool Audio:: initializeDecoder(){
bool
Audio
::
parseContentType
(
char
*
ct
)
{
enum
:
int
{
CT_NONE
,
CT_MP3
,
CT_AAC
,
CT_M4A
,
CT_WAV
,
CT_FLAC
,
CT_PLS
,
CT_M3U
,
CT_ASX
,
CT_M3U8
,
CT_TXT
,
CT_AACP
};
CT_M3U8
,
CT_TXT
,
CT_AACP
,
CT_OPUS
};
strlwr
(
ct
);
trim
(
ct
);
...
...
@@ -3526,8 +3557,8 @@ bool Audio::parseContentType(char* ct) {
else
if
(
!
strcmp
(
ct
,
"video/x-ms-asf"
))
ct_val
=
CT_ASX
;
else
if
(
!
strcmp
(
ct
,
"audio/x-ms-asx"
))
ct_val
=
CT_ASX
;
// #413
else
if
(
!
strcmp
(
ct
,
"application/ogg"
))
ct_val
=
CT_FLAC
;
// assume ogg wrapper
else
if
(
!
strcmp
(
ct
,
"audio/ogg"
))
ct_val
=
CT_FLAC
;
// auusme ogg wrapper
else
if
(
!
strcmp
(
ct
,
"application/ogg"
))
{
ct_val
=
CT_FLAC
;
if
(
m_expectedCodec
==
CODEC_OPUS
)
ct_val
=
CT_OPUS
;}
else
if
(
!
strcmp
(
ct
,
"audio/ogg"
))
{
ct_val
=
CT_FLAC
;
if
(
m_expectedCodec
==
CODEC_OPUS
)
ct_val
=
CT_OPUS
;}
else
if
(
!
strcmp
(
ct
,
"application/vnd.apple.mpegurl"
))
ct_val
=
CT_M3U8
;
else
if
(
!
strcmp
(
ct
,
"application/x-mpegurl"
))
ct_val
=
CT_M3U8
;
...
...
@@ -3559,6 +3590,10 @@ bool Audio::parseContentType(char* ct) {
m_codec
=
CODEC_FLAC
;
if
(
m_f_Log
)
{
log_i
(
"ContentType %s, format is flac"
,
ct
);
}
break
;
case
CT_OPUS
:
m_codec
=
CODEC_OPUS
;
if
(
m_f_Log
)
{
log_i
(
"ContentType %s, format is opus"
,
ct
);
}
break
;
case
CT_WAV
:
m_codec
=
CODEC_WAV
;
if
(
m_f_Log
)
{
log_i
(
"ContentType %s, format is wav"
,
ct
);
}
...
...
@@ -3757,6 +3792,9 @@ int Audio::findNextSync(uint8_t* data, size_t len){
m_flacBitsPerSample
,
m_flacTotalSamplesInStream
,
m_audioDataSize
);
nextSync
=
FLACFindSyncWord
(
data
,
len
);
}
if
(
m_codec
==
CODEC_OPUS
)
{
nextSync
=
OPUSFindSyncWord
(
data
,
len
);
}
if
(
nextSync
==
-
1
)
{
if
(
audio_info
&&
swnf
==
0
)
audio_info
(
"syncword not found"
);
else
{
...
...
@@ -3803,6 +3841,7 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
case
CODEC_AAC
:
ret
=
AACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_M4A
:
ret
=
AACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_FLAC
:
ret
=
FLACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_OPUS
:
ret
=
OPUSDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
default:
{
log_e
(
"no valid codec found codec = %d"
,
m_codec
);
stopSong
();}
}
...
...
@@ -3853,6 +3892,13 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
setBitsPerSample
(
FLACGetBitsPerSample
());
setBitrate
(
FLACGetBitRate
());
}
if
(
m_codec
==
CODEC_OPUS
){
setChannels
(
OPUSGetChannels
());
setSampleRate
(
OPUSGetSampRate
());
setBitsPerSample
(
OPUSGetBitsPerSample
());
setBitrate
(
OPUSGetBitRate
());
}
showCodecParams
();
}
if
(
m_codec
==
CODEC_MP3
){
...
...
@@ -3869,6 +3915,14 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
if
(
audio_showstreamtitle
)
audio_showstreamtitle
(
st
);
}
}
if
(
m_codec
==
CODEC_OPUS
){
m_validSamples
=
OPUSGetOutputSamps
()
/
getChannels
();
char
*
st
=
OPUSgetStreamTitle
();
if
(
st
){
AUDIO_INFO
(
st
);
if
(
audio_showstreamtitle
)
audio_showstreamtitle
(
st
);
}
}
}
compute_audioCurrentTime
(
bytesDecoded
);
...
...
src/Audio.h
View file @
dda1071b
...
...
@@ -442,7 +442,7 @@ private:
enum
:
int
{
M4A_BEGIN
=
0
,
M4A_FTYP
=
1
,
M4A_CHK
=
2
,
M4A_MOOV
=
3
,
M4A_FREE
=
4
,
M4A_TRAK
=
5
,
M4A_MDAT
=
6
,
M4A_ILST
=
7
,
M4A_MP4A
=
8
,
M4A_AMRDY
=
99
,
M4A_OKAY
=
100
};
enum
:
int
{
CODEC_NONE
=
0
,
CODEC_WAV
=
1
,
CODEC_MP3
=
2
,
CODEC_AAC
=
3
,
CODEC_M4A
=
4
,
CODEC_FLAC
=
5
,
CODEC_AACP
=
6
};
CODEC_AACP
=
6
,
CODEC_OPUS
=
7
};
enum
:
int
{
ST_NONE
=
0
,
ST_WEBFILE
=
1
,
ST_WEBSTREAM
=
2
};
typedef
enum
{
LEFTCHANNEL
=
0
,
RIGHTCHANNEL
=
1
}
SampleIndex
;
typedef
enum
{
LOWSHELF
=
0
,
PEAKEQ
=
1
,
HIFGSHELF
=
2
}
FilterType
;
...
...
@@ -478,6 +478,7 @@ private:
const
size_t
m_frameSizeMP3
=
1600
;
const
size_t
m_frameSizeAAC
=
1600
;
const
size_t
m_frameSizeFLAC
=
4096
*
4
;
const
size_t
m_frameSizeOPUS
=
1024
;
static
const
uint8_t
m_tsPacketSize
=
188
;
static
const
uint8_t
m_tsHeaderSize
=
4
;
...
...
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