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
4812e9ae
Commit
4812e9ae
authored
Feb 01, 2024
by
schreibfaul1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new code in opus framepacking
parent
e98000c5
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
74 additions
and
82 deletions
+74
-82
src/Audio.cpp
src/Audio.cpp
+42
-47
src/opus_decoder/opus_decoder.cpp
src/opus_decoder/opus_decoder.cpp
+32
-35
No files found.
src/Audio.cpp
View file @
4812e9ae
...
@@ -4218,15 +4218,10 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
...
@@ -4218,15 +4218,10 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
int
bytesDecoded
=
0
;
int
bytesDecoded
=
0
;
switch
(
m_codec
)
{
switch
(
m_codec
)
{
case
CODEC_WAV
:
case
CODEC_WAV
:
m_decodeError
=
0
;
bytesLeft
=
0
;
break
;
memmove
(
m_outBuff
,
data
,
len
);
// copy len data in outbuff and set validsamples and bytesdecoded=len
case
CODEC_MP3
:
m_decodeError
=
MP3Decode
(
data
,
&
bytesLeft
,
m_outBuff
,
0
);
break
;
if
(
getBitsPerSample
()
==
16
)
m_validSamples
=
len
/
(
2
*
getChannels
());
case
CODEC_AAC
:
m_decodeError
=
AACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
if
(
getBitsPerSample
()
==
8
)
m_validSamples
=
len
/
2
;
case
CODEC_M4A
:
m_decodeError
=
AACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
bytesLeft
=
0
;
break
;
case
CODEC_MP3
:
m_decodeError
=
MP3Decode
(
data
,
&
bytesLeft
,
m_outBuff
,
0
);
break
;
case
CODEC_AAC
:
m_decodeError
=
AACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_M4A
:
m_decodeError
=
AACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_FLAC
:
m_decodeError
=
FLACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_FLAC
:
m_decodeError
=
FLACDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_OPUS
:
m_decodeError
=
OPUSDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_OPUS
:
m_decodeError
=
OPUSDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_VORBIS
:
m_decodeError
=
VORBISDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
case
CODEC_VORBIS
:
m_decodeError
=
VORBISDecode
(
data
,
&
bytesLeft
,
m_outBuff
);
break
;
...
@@ -4272,45 +4267,45 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
...
@@ -4272,45 +4267,45 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
return
1
;
return
1
;
}
}
// status: bytesDecoded > 0 and m_decodeError >= 0
// status: bytesDecoded > 0 and m_decodeError >= 0
{
switch
(
m_codec
)
{
if
(
m_codec
==
CODEC_MP3
)
{
m_validSamples
=
MP3GetOutputSamps
()
/
getChannels
();
}
case
CODEC_WAV
:
memmove
(
m_outBuff
,
data
,
len
);
// copy len data in outbuff and set validsamples and bytesdecoded=len
if
((
m_codec
==
CODEC_AAC
)
||
(
m_codec
==
CODEC_M4A
))
{
m_validSamples
=
AACGetOutputSamps
()
/
getChannels
();
}
if
(
getBitsPerSample
()
==
16
)
m_validSamples
=
len
/
(
2
*
getChannels
());
if
(
m_codec
==
CODEC_FLAC
)
{
if
(
getBitsPerSample
()
==
8
)
m_validSamples
=
len
/
2
;
const
uint8_t
FLAC_PARSE_OGG_DONE
=
100
;
break
;
if
(
m_decodeError
==
FLAC_PARSE_OGG_DONE
)
return
bytesDecoded
;
// nothing to play
case
CODEC_MP3
:
m_validSamples
=
MP3GetOutputSamps
()
/
getChannels
();
m_validSamples
=
FLACGetOutputSamps
()
/
getChannels
();
break
;
char
*
st
=
FLACgetStreamTitle
();
case
CODEC_AAC
:
m_validSamples
=
AACGetOutputSamps
()
/
getChannels
();
if
(
st
)
{
break
;
AUDIO_INFO
(
st
);
case
CODEC_M4A
:
m_validSamples
=
AACGetOutputSamps
()
/
getChannels
();
if
(
audio_showstreamtitle
)
audio_showstreamtitle
(
st
);
break
;
}
case
CODEC_FLAC
:
if
(
m_decodeError
==
FLAC_PARSE_OGG_DONE
)
return
bytesDecoded
;
// nothing to play
}
m_validSamples
=
FLACGetOutputSamps
()
/
getChannels
();
if
(
m_codec
==
CODEC_OPUS
)
{
if
(
FLACgetStreamTitle
())
{
const
uint8_t
OPUS_PARSE_OGG_DONE
=
100
;
AUDIO_INFO
(
FLACgetStreamTitle
());
if
(
m_decodeError
==
OPUS_PARSE_OGG_DONE
)
return
bytesDecoded
;
// nothing to play
if
(
audio_showstreamtitle
)
audio_showstreamtitle
(
FLACgetStreamTitle
());
m_validSamples
=
OPUSGetOutputSamps
();
}
char
*
st
=
OPUSgetStreamTitle
();
break
;
if
(
st
)
{
case
CODEC_OPUS
:
if
(
m_decodeError
==
OPUS_PARSE_OGG_DONE
)
return
bytesDecoded
;
// nothing to play
AUDIO_INFO
(
st
);
m_validSamples
=
OPUSGetOutputSamps
();
if
(
audio_showstreamtitle
)
audio_showstreamtitle
(
st
);
if
(
OPUSgetStreamTitle
())
{
}
AUDIO_INFO
(
OPUSgetStreamTitle
());
}
if
(
audio_showstreamtitle
)
audio_showstreamtitle
(
OPUSgetStreamTitle
());
if
(
m_codec
==
CODEC_VORBIS
)
{
}
const
uint8_t
VORBIS_PARSE_OGG_DONE
=
100
;
break
;
if
(
m_decodeError
==
VORBIS_PARSE_OGG_DONE
)
return
bytesDecoded
;
// nothing to play
case
CODEC_VORBIS
:
if
(
m_decodeError
==
VORBIS_PARSE_OGG_DONE
)
return
bytesDecoded
;
// nothing to play
m_validSamples
=
VORBISGetOutputSamps
();
m_validSamples
=
VORBISGetOutputSamps
();
char
*
st
=
VORBISgetStreamTitle
();
if
(
VORBISgetStreamTitle
())
{
if
(
st
)
{
AUDIO_INFO
(
VORBISgetStreamTitle
());
AUDIO_INFO
(
st
);
if
(
audio_showstreamtitle
)
audio_showstreamtitle
(
VORBISgetStreamTitle
());
if
(
audio_showstreamtitle
)
audio_showstreamtitle
(
st
);
}
}
break
;
}
}
if
(
f_setDecodeParamsOnce
)
{
if
(
f_setDecodeParamsOnce
)
{
f_setDecodeParamsOnce
=
false
;
f_setDecodeParamsOnce
=
false
;
setDecoderItems
();
setDecoderItems
();
m_PlayingStartTime
=
millis
();
m_PlayingStartTime
=
millis
();
}
}
}
compute_audioCurrentTime
(
bytesDecoded
);
compute_audioCurrentTime
(
bytesDecoded
);
if
(
audio_process_extern
)
{
if
(
audio_process_extern
)
{
...
...
src/opus_decoder/opus_decoder.cpp
View file @
4812e9ae
...
@@ -23,7 +23,6 @@ uint16_t s_opusSamplerate = 0;
...
@@ -23,7 +23,6 @@ uint16_t s_opusSamplerate = 0;
uint32_t
s_opusSegmentLength
=
0
;
uint32_t
s_opusSegmentLength
=
0
;
char
*
s_opusChbuf
=
NULL
;
char
*
s_opusChbuf
=
NULL
;
int32_t
s_opusValidSamples
=
0
;
int32_t
s_opusValidSamples
=
0
;
uint8_t
s_opusOldMode
=
0
;
uint16_t
*
s_opusSegmentTable
;
uint16_t
*
s_opusSegmentTable
;
uint8_t
s_opusSegmentTableSize
=
0
;
uint8_t
s_opusSegmentTableSize
=
0
;
...
@@ -66,7 +65,6 @@ void OPUSsetDefaults(){
...
@@ -66,7 +65,6 @@ void OPUSsetDefaults(){
s_opusSegmentLength
=
0
;
s_opusSegmentLength
=
0
;
s_opusValidSamples
=
0
;
s_opusValidSamples
=
0
;
s_opusSegmentTableSize
=
0
;
s_opusSegmentTableSize
=
0
;
s_opusOldMode
=
0xFF
;
s_opusSegmentTableRdPtr
=
-
1
;
s_opusSegmentTableRdPtr
=
-
1
;
s_opusCountCode
=
0
;
s_opusCountCode
=
0
;
...
@@ -79,7 +77,9 @@ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
...
@@ -79,7 +77,9 @@ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
static
uint16_t
fs
=
0
;
static
uint16_t
fs
=
0
;
static
uint8_t
M
=
0
;
static
uint8_t
M
=
0
;
static
uint8_t
configNr
=
0
;
static
uint16_t
paddingBytes
=
0
;
static
uint16_t
paddingBytes
=
0
;
uint8_t
paddingLength
=
0
;
static
uint16_t
samplesPerFrame
=
0
;
static
uint16_t
samplesPerFrame
=
0
;
int
ret
=
ERR_OPUS_NONE
;
int
ret
=
ERR_OPUS_NONE
;
int
len
=
0
;
int
len
=
0
;
...
@@ -94,7 +94,7 @@ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
...
@@ -94,7 +94,7 @@ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
else
return
ret
;
// error
else
return
ret
;
// error
}
}
if
(
s_opusCountCode
==
3
)
goto
FramePacking
;
if
(
s_opusCountCode
>
0
)
goto
FramePacking
;
// more than one frame in the packet
if
(
s_f_opusFramePacket
){
if
(
s_f_opusFramePacket
){
if
(
s_opusSegmentTableSize
>
0
){
if
(
s_opusSegmentTableSize
>
0
){
...
@@ -103,17 +103,13 @@ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
...
@@ -103,17 +103,13 @@ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
len
=
s_opusSegmentTable
[
s_opusSegmentTableRdPtr
];
len
=
s_opusSegmentTable
[
s_opusSegmentTableRdPtr
];
}
}
ret
=
parseOpusTOC
(
inbuf
[
0
]);
configNr
=
parseOpusTOC
(
inbuf
[
0
]);
samplesPerFrame
=
opus_packet_get_samples_per_frame
(
inbuf
,
48000
);
samplesPerFrame
=
opus_packet_get_samples_per_frame
(
inbuf
,
s_opusSamplerate
);
if
(
ret
<
0
)
goto
exit
;
// error
}
FramePacking:
// https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2.html 3.2. Frame Packing
FramePacking:
switch
(
s_opusCountCode
){
case
0
:
// Code 0: One Frame in the Packet
// https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2.html 3.2. Frame Packing
if
(
s_opusCountCode
==
0
){
// Code 0: One Frame in the Packet
*
bytesLeft
-=
len
;
*
bytesLeft
-=
len
;
ret
=
parseOpusTOC
(
inbuf
[
0
]);
if
(
ret
<
0
)
goto
exit
;
// error
len
--
;
len
--
;
inbuf
++
;
inbuf
++
;
ec_dec_init
((
uint8_t
*
)
inbuf
,
len
);
ec_dec_init
((
uint8_t
*
)
inbuf
,
len
);
...
@@ -121,35 +117,39 @@ FramePacking:
...
@@ -121,35 +117,39 @@ FramePacking:
if
(
ret
<
0
)
goto
exit
;
// celt error
if
(
ret
<
0
)
goto
exit
;
// celt error
s_opusValidSamples
=
ret
;
s_opusValidSamples
=
ret
;
ret
=
ERR_OPUS_NONE
;
ret
=
ERR_OPUS_NONE
;
}
break
;
if
(
s_opusCountCode
==
1
){
// Code 1: Two Frames in the Packet, Each with Equal Compressed Size
case
1
:
// Code 1: Two Frames in the Packet, Each with Equal Compressed Size
log_e
(
"OPUS countCode 1 not supported yet"
);
vTaskDelay
(
1000
);
// todo
log_e
(
"OPUS countCode 1 not supported yet"
);
vTaskDelay
(
1000
);
// todo
}
break
;
if
(
s_opusCountCode
==
2
){
// Code 2: Two Frames in the Packet, with Different Compressed Sizes
case
2
:
// Code 2: Two Frames in the Packet, with Different Compressed Sizes
log_e
(
"OPUS countCode 2 not supported yet"
);
vTaskDelay
(
1000
);
// todo
log_e
(
"OPUS countCode 2 not supported yet"
);
vTaskDelay
(
1000
);
// todo
}
break
;
if
(
s_opusCountCode
==
3
){
// Code 3: A Signaled Number of Frames in the Packet
case
3
:
// Code 3: A Signaled Number of Frames in the Packet
if
(
M
==
0
){
if
(
M
==
0
){
bool
v
=
((
inbuf
[
1
]
&
0x80
)
==
0x80
);
// VBR indicator
bool
v
=
((
inbuf
[
1
]
&
0x80
)
==
0x80
);
// VBR indicator
(
void
)
v
;
if
(
v
!=
0
)
{
log_e
(
"OPUS countCode 3 with VBR not supported yet"
);
vTaskDelay
(
1000
);}
// todo
bool
p
=
((
inbuf
[
1
]
&
0x40
)
==
0x40
);
// padding bit
bool
p
=
((
inbuf
[
1
]
&
0x40
)
==
0x40
);
// padding bit
M
=
inbuf
[
1
]
&
0x3F
;
// max framecount
M
=
inbuf
[
1
]
&
0x3F
;
// max framecount
// log_i("v %i, p %i, M %i", v, p, M);
// log_i("v %i, p %i, M %i", v, p, M);
paddingBytes
=
0
;
paddingBytes
=
0
;
paddingLength
=
0
;
if
(
p
){
if
(
p
){
paddingLength
=
1
;
int
i
=
0
;
int
i
=
0
;
while
(
inbuf
[
2
+
i
]
==
255
){
while
(
inbuf
[
2
+
i
]
==
255
){
paddingBytes
+=
inbuf
[
2
+
i
];
paddingBytes
+=
inbuf
[
2
+
i
];
i
++
;
i
++
;
}
}
paddingBytes
+=
inbuf
[
2
+
i
];
paddingBytes
+=
inbuf
[
2
+
i
];
fs
=
(
len
-
3
-
i
-
paddingBytes
)
/
M
;
fs
=
(
len
-
(
2
+
paddingLength
+
paddingBytes
))
/
M
;
*
bytesLeft
-=
3
+
i
;
*
bytesLeft
-=
(
3
+
i
);
inbuf
+=
3
+
i
;
paddingLength
+=
i
;
inbuf
+=
2
+
paddingLength
;
// log_e("paddingBytes %i, len %i, fs %i", paddingBytes, len, fs);
}
}
}
}
*
bytesLeft
-=
fs
;
*
bytesLeft
-=
fs
;
// samplesPerFrame = opus_packet_get_samples_per_frame(inbuf, s_opusSamplerate);
ec_dec_init
((
uint8_t
*
)
inbuf
,
fs
);
ec_dec_init
((
uint8_t
*
)
inbuf
,
fs
);
ret
=
celt_decode_with_ec
(
inbuf
,
fs
,
(
int16_t
*
)
outbuf
,
samplesPerFrame
);
ret
=
celt_decode_with_ec
(
inbuf
,
fs
,
(
int16_t
*
)
outbuf
,
samplesPerFrame
);
if
(
ret
<
0
)
goto
exit
;
// celt error
if
(
ret
<
0
)
goto
exit
;
// celt error
...
@@ -159,7 +159,11 @@ FramePacking:
...
@@ -159,7 +159,11 @@ FramePacking:
ret
=
ERR_OPUS_NONE
;
ret
=
ERR_OPUS_NONE
;
if
(
M
==
0
)
{
s_opusCountCode
=
0
;
*
bytesLeft
-=
paddingBytes
;
goto
exit
;}
if
(
M
==
0
)
{
s_opusCountCode
=
0
;
*
bytesLeft
-=
paddingBytes
;
goto
exit
;}
return
ret
;
return
ret
;
}
break
;
default:
log_e
(
"unknown countCode %i"
,
s_opusCountCode
);
break
;
}
}
exit:
exit:
...
@@ -219,7 +223,6 @@ char* OPUSgetStreamTitle(){
...
@@ -219,7 +223,6 @@ char* OPUSgetStreamTitle(){
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
int
parseOpusTOC
(
uint8_t
TOC_Byte
){
// https://www.rfc-editor.org/rfc/rfc6716 page 16 ff
int
parseOpusTOC
(
uint8_t
TOC_Byte
){
// https://www.rfc-editor.org/rfc/rfc6716 page 16 ff
uint8_t
mode
=
0
;
uint8_t
configNr
=
0
;
uint8_t
configNr
=
0
;
uint8_t
s
=
0
;
// stereo flag
uint8_t
s
=
0
;
// stereo flag
uint8_t
c
=
0
;
(
void
)
c
;
// count code
uint8_t
c
=
0
;
(
void
)
c
;
// count code
...
@@ -227,12 +230,6 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716
...
@@ -227,12 +230,6 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716
configNr
=
(
TOC_Byte
&
0b11111000
)
>>
3
;
configNr
=
(
TOC_Byte
&
0b11111000
)
>>
3
;
s
=
(
TOC_Byte
&
0b00000100
)
>>
2
;
s
=
(
TOC_Byte
&
0b00000100
)
>>
2
;
c
=
(
TOC_Byte
&
0b00000011
);
c
=
(
TOC_Byte
&
0b00000011
);
if
(
TOC_Byte
&
0x80
)
mode
=
2
;
else
mode
=
1
;
if
(
s_opusOldMode
!=
mode
)
{
s_opusOldMode
=
mode
;
// if(mode == 2) log_i("opus mode is MODE_CELT_ONLY");
}
/* Configuration Mode Bandwidth FrameSizes Audio Bandwidth Sample Rate (Effective)
/* Configuration Mode Bandwidth FrameSizes Audio Bandwidth Sample Rate (Effective)
configNr 16 ... 19 CELT NB (narrowband) 2.5, 5, 10, 20ms 4 kHz 8 kHz
configNr 16 ... 19 CELT NB (narrowband) 2.5, 5, 10, 20ms 4 kHz 8 kHz
...
@@ -255,9 +252,9 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716
...
@@ -255,9 +252,9 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716
if
(
configNr
<
12
)
return
ERR_OPUS_SILK_MODE_UNSUPPORTED
;
if
(
configNr
<
12
)
return
ERR_OPUS_SILK_MODE_UNSUPPORTED
;
if
(
configNr
<
16
)
return
ERR_OPUS_HYBRID_MODE_UNSUPPORTED
;
if
(
configNr
<
16
)
return
ERR_OPUS_HYBRID_MODE_UNSUPPORTED
;
if
(
configNr
<
20
)
return
ERR_OPUS_NARROW_BAND_UNSUPPORTED
;
//
if(configNr < 20) return ERR_OPUS_NARROW_BAND_UNSUPPORTED;
if
(
configNr
<
24
)
return
ERR_OPUS_WIDE_BAND_UNSUPPORTED
;
//
if(configNr < 24) return ERR_OPUS_WIDE_BAND_UNSUPPORTED;
if
(
configNr
<
28
)
return
ERR_OPUS_SUPER_WIDE_BAND_UNSUPPORTED
;
//
if(configNr < 28) return ERR_OPUS_SUPER_WIDE_BAND_UNSUPPORTED;
return
configNr
;
return
configNr
;
}
}
...
...
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