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
6bedb144
Commit
6bedb144
authored
Feb 05, 2024
by
schreibfaul1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
opus detect metadata blockpicture correct
parent
cf88468f
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
239 additions
and
122 deletions
+239
-122
src/Audio.cpp
src/Audio.cpp
+3
-3
src/Audio.h
src/Audio.h
+2
-2
src/opus_decoder/celt.cpp
src/opus_decoder/celt.cpp
+44
-45
src/opus_decoder/celt.h
src/opus_decoder/celt.h
+15
-11
src/opus_decoder/opus_decoder.cpp
src/opus_decoder/opus_decoder.cpp
+171
-60
src/opus_decoder/opus_decoder.h
src/opus_decoder/opus_decoder.h
+4
-1
No files found.
src/Audio.cpp
View file @
6bedb144
...
...
@@ -3,8 +3,8 @@
*
* Created on: Oct 26.2018
*
* Version 3.0.8
j
* Updated on: Feb 0
2
.2024
* Version 3.0.8
k
* Updated on: Feb 0
5
.2024
* Author: Wolle (schreibfaul1)
*
*/
...
...
@@ -2960,7 +2960,7 @@ void Audio::processLocalFile() {
}
}
}
AUDIO_INFO
(
"audio file is corrupt --> send EOF"
);
// no return, fall through
if
(
m_codec
==
CODEC_MP3
)
AUDIO_INFO
(
"audio file is corrupt --> send EOF"
);
// no return, fall through
}
}
...
...
src/Audio.h
View file @
6bedb144
...
...
@@ -3,8 +3,8 @@
*
* Created on: Oct 28,2018
*
* Version 3.0.8
j
* Updated on: Feb 0
2
.2024
* Version 3.0.8
k
* Updated on: Feb 0
5
.2024
* Author: Wolle (schreibfaul1)
*/
...
...
src/opus_decoder/celt.cpp
View file @
6bedb144
...
...
@@ -5,7 +5,7 @@
*
* Created on: Sep 01.2022
*
* Updated on: Feb 0
3
.2024
* Updated on: Feb 0
5
.2024
* Author: Wolle (schreibfaul1)
*/
...
...
@@ -31,7 +31,6 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------------------------------------------------*/
#include <Arduino.h>
#include "celt.h"
#include "opus_decoder.h"
...
...
@@ -841,8 +840,8 @@ void comb_filter(int32_t *y, int32_t *x, int32_t T0, int32_t T1, int32_t N, int1
}
/* When the gain is zero, T0 and/or T1 is set to zero. We need
to have then be at least 2 to avoid processing garbage data. */
T0
=
max
(
T0
,
COMBFILTER_MINPERIOD
);
T1
=
max
(
T1
,
COMBFILTER_MINPERIOD
);
T0
=
_
max
(
T0
,
COMBFILTER_MINPERIOD
);
T1
=
_
max
(
T1
,
COMBFILTER_MINPERIOD
);
g00
=
MULT16_16_P15
(
g0
,
gains
[
tapset0
][
0
]);
g01
=
MULT16_16_P15
(
g0
,
gains
[
tapset0
][
1
]);
g02
=
MULT16_16_P15
(
g0
,
gains
[
tapset0
][
2
]);
...
...
@@ -1021,7 +1020,7 @@ void anti_collapse(int16_t *X_, uint8_t *collapse_masks, int32_t LM, int32_t C,
depth
=
((
1
+
pulses
[
i
])
/
(
eband5ms
[
i
+
1
]
-
eband5ms
[
i
]))
>>
LM
;
thresh32
=
celt_exp2
(
-
SHL16
(
depth
,
10
-
BITRES
))
>>
1
;
thresh
=
MULT16_32_Q15
(
QCONST16
(
0.5
f
,
15
),
min
(
32767
,
thresh32
));
{
thresh
=
MULT16_32_Q15
(
QCONST16
(
0.5
f
,
15
),
_
min
(
32767
,
thresh32
));
{
int32_t
t
;
t
=
N0
<<
LM
;
if
(
t
<
1
)
log_e
(
"celt_ilog2 %i"
,
t
);
...
...
@@ -1045,17 +1044,17 @@ void anti_collapse(int16_t *X_, uint8_t *collapse_masks, int32_t LM, int32_t C,
prev2
=
max
(
prev2
,
prev2logE
[
m_CELTMode
.
nbEBands
+
i
]);
}
Ediff
=
EXTEND32
(
logE
[
c
*
m_CELTMode
.
nbEBands
+
i
])
-
EXTEND32
(
min
(
prev1
,
prev2
));
Ediff
=
max
(
0
,
Ediff
);
Ediff
=
_
max
(
0
,
Ediff
);
if
(
Ediff
<
16384
)
{
int32_t
r32
=
celt_exp2
(
-
(
int16_t
)(
Ediff
>>
1
));
r
=
2
*
min
(
16383
,
r32
);
r
=
2
*
_
min
(
16383
,
r32
);
}
else
{
r
=
0
;
}
if
(
LM
==
3
)
r
=
MULT16_16_Q14
(
23170
,
min
(
23169
,
r
));
r
=
MULT16_16_Q14
(
23170
,
_
min
(
23169
,
r
));
r
=
SHR16
(
min
(
thresh
,
r
),
1
);
r
=
MULT16_16_Q15
(
sqrt_1
,
r
)
>>
shift
;
...
...
@@ -1090,13 +1089,13 @@ void compute_channel_weights(int32_t Ex, int32_t Ey, int16_t w[2]) {
int32_t
shift
;
minE
=
min
(
Ex
,
Ey
);
minE
=
_
min
(
Ex
,
Ey
);
/* Adjustment to make the weights a bit more conservative. */
Ex
=
ADD32
(
Ex
,
minE
/
3
);
Ey
=
ADD32
(
Ey
,
minE
/
3
);
if
(
EPSILON
+
max
(
Ex
,
Ey
)
<
1
)
log_e
(
"celt_ilog2 %i"
,
EPSILON
+
max
(
Ex
,
Ey
));
shift
=
celt_ilog2
(
EPSILON
+
max
(
Ex
,
Ey
))
-
14
;
if
(
EPSILON
+
_max
(
Ex
,
Ey
)
<
1
)
log_e
(
"celt_ilog2 %i"
,
EPSILON
+
_
max
(
Ex
,
Ey
));
shift
=
celt_ilog2
(
EPSILON
+
_
max
(
Ex
,
Ey
))
-
14
;
w
[
0
]
=
VSHR32
(
Ex
,
shift
);
w
[
1
]
=
VSHR32
(
Ey
,
shift
);
...
...
@@ -1243,9 +1242,9 @@ int32_t compute_qn(int32_t N, int32_t b, int32_t offset, int32_t pulse_cap, int3
always have enough bits left over to code at least one pulse in the
side; otherwise it would collapse, since it doesn't get folded. */
qb
=
celt_sudiv
(
b
+
N2
*
offset
,
N2
);
qb
=
min
(
b
-
pulse_cap
-
(
4
<<
BITRES
),
qb
);
qb
=
_
min
(
b
-
pulse_cap
-
(
4
<<
BITRES
),
qb
);
qb
=
min
(
8
<<
BITRES
,
qb
);
qb
=
_
min
(
8
<<
BITRES
,
qb
);
if
(
qb
<
(
1
<<
BITRES
>>
1
))
{
qn
=
1
;
...
...
@@ -1453,9 +1452,9 @@ uint32_t quant_partition(int16_t *X, int32_t N, int32_t b, int32_t B, int16_t *l
delta
-=
delta
>>
(
4
-
LM
);
else
/* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */
delta
=
min
(
0
,
delta
+
(
N
<<
BITRES
>>
(
5
-
LM
)));
delta
=
_
min
(
0
,
delta
+
(
N
<<
BITRES
>>
(
5
-
LM
)));
}
mbits
=
max
(
0
,
min
(
b
,
(
b
-
delta
)
/
2
));
mbits
=
_max
(
0
,
_
min
(
b
,
(
b
-
delta
)
/
2
));
sbits
=
b
-
mbits
;
s_band_ctx
.
remaining_bits
-=
qalloc
;
...
...
@@ -1731,7 +1730,7 @@ uint32_t quant_band_stereo(int16_t *X, int16_t *Y, int32_t N, int32_t b, int32_t
/* "Normal" split code */
int32_t
rebalance
;
mbits
=
max
(
0
,
min
(
b
,
(
b
-
delta
)
/
2
));
mbits
=
_max
(
0
,
_
min
(
b
,
(
b
-
delta
)
/
2
));
sbits
=
b
-
mbits
;
s_band_ctx
.
remaining_bits
-=
qalloc
;
...
...
@@ -1866,8 +1865,8 @@ void quant_all_bands(int16_t *X_, int16_t *Y_, uint8_t *collapse_masks, int32_t
remaining_bits
=
total_bits
-
tell
-
1
;
s_band_ctx
.
remaining_bits
=
remaining_bits
;
if
(
i
<=
codedBands
-
1
){
curr_balance
=
celt_sudiv
(
balance
,
min
(
3
,
codedBands
-
i
));
b
=
max
(
0
,
min
(
16383
,
min
(
remaining_bits
+
1
,
pulses
[
i
]
+
curr_balance
)));
curr_balance
=
celt_sudiv
(
balance
,
_
min
(
3
,
codedBands
-
i
));
b
=
_max
(
0
,
_min
(
16383
,
_
min
(
remaining_bits
+
1
,
pulses
[
i
]
+
curr_balance
)));
}
else
{
b
=
0
;
...
...
@@ -1896,7 +1895,7 @@ void quant_all_bands(int16_t *X_, int16_t *Y_, uint8_t *collapse_masks, int32_t
int32_t
fold_end
;
int32_t
fold_i
;
/* This ensures we never repeat spectral content within one band */
effective_lowband
=
max
(
0
,
M
*
eBands
[
lowband_offset
]
-
norm_offset
-
N
);
effective_lowband
=
_
max
(
0
,
M
*
eBands
[
lowband_offset
]
-
norm_offset
-
N
);
fold_start
=
lowband_offset
;
while
(
M
*
eBands
[
--
fold_start
]
>
effective_lowband
+
norm_offset
)
;
...
...
@@ -2293,7 +2292,7 @@ int32_t celt_decode_with_ec(const uint8_t *inbuf, int32_t len, int16_t *outbuf,
if
(
len
<=
1
)
{
log_e
(
"OPUS_BAD_ARG"
);
return
ERR_OPUS_CELT_BAD_ARG
;}
if
(
C
==
1
)
{
for
(
i
=
0
;
i
<
nbEBands
;
i
++
)
oldBandE
[
i
]
=
max
(
oldBandE
[
i
],
oldBandE
[
nbEBands
+
i
]);
for
(
i
=
0
;
i
<
nbEBands
;
i
++
)
oldBandE
[
i
]
=
_
max
(
oldBandE
[
i
],
oldBandE
[
nbEBands
+
i
]);
}
total_bits
=
len
*
8
;
...
...
@@ -2361,7 +2360,7 @@ int32_t celt_decode_with_ec(const uint8_t *inbuf, int32_t len, int16_t *outbuf,
width
=
C
*
(
eBands
[
i
+
1
]
-
eBands
[
i
])
<<
LM
;
/* quanta is 6 bits, but no more than 1 bit/sample
and no less than 1/8 bit/sample */
quanta
=
min
(
width
<<
BITRES
,
max
(
6
<<
BITRES
,
width
));
quanta
=
_min
(
width
<<
BITRES
,
_
max
(
6
<<
BITRES
,
width
));
dynalloc_loop_logp
=
dynalloc_logp
;
boost
=
0
;
while
(
tell
+
(
dynalloc_loop_logp
<<
BITRES
)
<
total_bits
&&
boost
<
cap
[
i
])
{
...
...
@@ -2375,7 +2374,7 @@ int32_t celt_decode_with_ec(const uint8_t *inbuf, int32_t len, int16_t *outbuf,
}
offsets
[
i
]
=
boost
;
/* Making dynalloc more likely */
if
(
boost
>
0
)
dynalloc_logp
=
max
(
2
,
dynalloc_logp
-
1
);
if
(
boost
>
0
)
dynalloc_logp
=
_
max
(
2
,
dynalloc_logp
-
1
);
}
int32_t
fine_quant
[
nbEBands
];
...
...
@@ -2421,8 +2420,8 @@ int32_t celt_decode_with_ec(const uint8_t *inbuf, int32_t len, int16_t *outbuf,
c
=
0
;
const
uint8_t
COMBFILTER_MINPERIOD
=
15
;
do
{
s_celtDec
->
postfilter_period
=
max
(
s_celtDec
->
postfilter_period
,
COMBFILTER_MINPERIOD
);
s_celtDec
->
postfilter_period_old
=
max
(
s_celtDec
->
postfilter_period_old
,
COMBFILTER_MINPERIOD
);
s_celtDec
->
postfilter_period
=
_
max
(
s_celtDec
->
postfilter_period
,
COMBFILTER_MINPERIOD
);
s_celtDec
->
postfilter_period_old
=
_
max
(
s_celtDec
->
postfilter_period_old
,
COMBFILTER_MINPERIOD
);
comb_filter
(
out_syn
[
c
],
out_syn
[
c
],
s_celtDec
->
postfilter_period_old
,
s_celtDec
->
postfilter_period
,
m_CELTMode
.
shortMdctSize
,
s_celtDec
->
postfilter_gain_old
,
s_celtDec
->
postfilter_gain
,
s_celtDec
->
postfilter_tapset_old
,
s_celtDec
->
postfilter_tapset
);
...
...
@@ -2457,9 +2456,9 @@ int32_t celt_decode_with_ec(const uint8_t *inbuf, int32_t len, int16_t *outbuf,
max_background_increase
=
M
*
QCONST16
(
0.001
f
,
10
);
for
(
i
=
0
;
i
<
2
*
nbEBands
;
i
++
)
backgroundLogE
[
i
]
=
min
(
backgroundLogE
[
i
]
+
max_background_increase
,
oldBandE
[
i
]);
backgroundLogE
[
i
]
=
_
min
(
backgroundLogE
[
i
]
+
max_background_increase
,
oldBandE
[
i
]);
}
else
{
for
(
i
=
0
;
i
<
2
*
nbEBands
;
i
++
)
oldLogE
[
i
]
=
min
(
oldLogE
[
i
],
oldBandE
[
i
]);
for
(
i
=
0
;
i
<
2
*
nbEBands
;
i
++
)
oldLogE
[
i
]
=
_
min
(
oldLogE
[
i
],
oldBandE
[
i
]);
}
c
=
0
;
do
{
...
...
@@ -3091,8 +3090,8 @@ int32_t ec_laplace_decode(uint32_t fs, int32_t decay) {
assert
(
fl
<
32768
);
assert
(
fs
>
0
);
assert
(
fl
<=
fm
);
assert
(
fm
<
min
(
fl
+
fs
,
32768
));
ec_dec_update
(
fl
,
min
(
fl
+
fs
,
32768
),
32768
);
assert
(
fm
<
_
min
(
fl
+
fs
,
32768
));
ec_dec_update
(
fl
,
_
min
(
fl
+
fs
,
32768
),
32768
);
return
val
;
}
//----------------------------------------------------------------------------------------------------------------------
...
...
@@ -3174,7 +3173,7 @@ static inline int16_t _celt_cos_pi_2(int16_t x) {
x2
=
MULT16_16_P15
(
x
,
x
);
return
ADD16
(
1
,
min
(
32766
,
ADD32
(
SUB16
(
32767
,
x2
),
_
min
(
32766
,
ADD32
(
SUB16
(
32767
,
x2
),
MULT16_16_P15
(
x2
,
ADD32
(
-
7651
,
MULT16_16_P15
(
x2
,
ADD32
(
8277
,
MULT16_16_P15
(
-
626
,
x2
))))))));
}
//----------------------------------------------------------------------------------------------------------------------
...
...
@@ -3372,7 +3371,7 @@ int32_t interp_bits2pulses(int32_t end, int32_t skip_start, const int32_t *bits1
}
else
done
=
1
;
/* Don't allocate more than we can actually use */
tmp
=
min
(
tmp
,
cap
[
j
]);
tmp
=
_
min
(
tmp
,
cap
[
j
]);
bits
[
j
]
=
tmp
;
psum
+=
tmp
;
}
...
...
@@ -3400,7 +3399,7 @@ int32_t interp_bits2pulses(int32_t end, int32_t skip_start, const int32_t *bits1
assert
(
eband5ms
[
codedBands
]
-
eband5ms
[
0
]
>
0
);
percoeff
=
left
/
(
eband5ms
[
codedBands
]
-
eband5ms
[
0
]);
left
-=
(
eband5ms
[
codedBands
]
-
eband5ms
[
0
])
*
percoeff
;
rem
=
max
(
left
-
(
eband5ms
[
j
]
-
eband5ms
[
0
]),
0
);
rem
=
_
max
(
left
-
(
eband5ms
[
j
]
-
eband5ms
[
0
]),
0
);
band_width
=
eband5ms
[
codedBands
]
-
eband5ms
[
j
];
band_bits
=
(
int32_t
)(
bits
[
j
]
+
percoeff
*
band_width
+
rem
);
/*Only code a skip decision if we're above the threshold for this band.
...
...
@@ -3449,7 +3448,7 @@ int32_t interp_bits2pulses(int32_t end, int32_t skip_start, const int32_t *bits1
for
(
j
=
0
;
j
<
codedBands
;
j
++
)
bits
[
j
]
+=
((
int32_t
)
percoeff
*
(
eband5ms
[
j
+
1
]
-
eband5ms
[
j
]));
for
(
j
=
0
;
j
<
codedBands
;
j
++
)
{
int32_t
tmp
=
(
int32_t
)
min
(
left
,
eband5ms
[
j
+
1
]
-
eband5ms
[
j
]);
int32_t
tmp
=
(
int32_t
)
_
min
(
left
,
eband5ms
[
j
+
1
]
-
eband5ms
[
j
]);
bits
[
j
]
+=
tmp
;
left
-=
tmp
;
}
...
...
@@ -3468,7 +3467,7 @@ int32_t interp_bits2pulses(int32_t end, int32_t skip_start, const int32_t *bits1
bit
=
(
int32_t
)
bits
[
j
]
+
balance
;
if
(
N
>
1
)
{
excess
=
max
(
bit
-
cap
[
j
],
0
);
excess
=
_
max
(
bit
-
cap
[
j
],
0
);
bits
[
j
]
=
bit
-
excess
;
/* Compensate for the extra DoF in stereo */
...
...
@@ -3490,7 +3489,7 @@ int32_t interp_bits2pulses(int32_t end, int32_t skip_start, const int32_t *bits1
offset
+=
NClogN
>>
3
;
/* Divide with rounding */
ebits
[
j
]
=
max
(
0
,
(
bits
[
j
]
+
offset
+
(
den
<<
(
BITRES
-
1
))));
ebits
[
j
]
=
_
max
(
0
,
(
bits
[
j
]
+
offset
+
(
den
<<
(
BITRES
-
1
))));
assert
(
den
>
0
);
ebits
[
j
]
=
(
ebits
[
j
]
/
den
)
>>
BITRES
;
...
...
@@ -3498,7 +3497,7 @@ int32_t interp_bits2pulses(int32_t end, int32_t skip_start, const int32_t *bits1
if
(
C
*
ebits
[
j
]
>
(
bits
[
j
]
>>
BITRES
))
ebits
[
j
]
=
bits
[
j
]
>>
stereo
>>
BITRES
;
/* More than that is useless because that's about as far as PVQ can go */
ebits
[
j
]
=
min
(
ebits
[
j
],
MAX_FINE_BITS
);
ebits
[
j
]
=
_
min
(
ebits
[
j
],
MAX_FINE_BITS
);
/* If we rounded down or capped this band, make it a candidate for the
final fine energy pass */
...
...
@@ -3509,7 +3508,7 @@ int32_t interp_bits2pulses(int32_t end, int32_t skip_start, const int32_t *bits1
}
else
{
/* For N=1, all bits go to fine energy except for a single sign bit */
excess
=
max
(
0
,
bit
-
(
C
<<
BITRES
));
excess
=
_
max
(
0
,
bit
-
(
C
<<
BITRES
));
bits
[
j
]
=
bit
-
excess
;
ebits
[
j
]
=
0
;
fine_priority
[
j
]
=
1
;
...
...
@@ -3559,7 +3558,7 @@ int32_t clt_compute_allocation(const int32_t *offsets, const int32_t *cap, int32
int32_t
dual_stereo_rsv
;
const
uint8_t
end
=
s_celtDec
->
end
;
// 21
total
=
max
(
total
,
0
);
total
=
_
max
(
total
,
0
);
len
=
m_CELTMode
.
nbEBands
;
// =21
/* Reserve a bit to signal the end of manually skipped bands. */
skip_rsv
=
total
>=
1
<<
BITRES
?
1
<<
BITRES
:
0
;
...
...
@@ -3585,7 +3584,7 @@ int32_t clt_compute_allocation(const int32_t *offsets, const int32_t *cap, int32
for
(
j
=
0
;
j
<
end
;
j
++
)
{
/* Below this threshold, we're sure not to allocate any PVQ bits */
thresh
[
j
]
=
max
((
C
)
<<
BITRES
,
(
3
*
(
eband5ms
[
j
+
1
]
-
eband5ms
[
j
])
<<
LM
<<
BITRES
)
>>
4
);
thresh
[
j
]
=
_
max
((
C
)
<<
BITRES
,
(
3
*
(
eband5ms
[
j
+
1
]
-
eband5ms
[
j
])
<<
LM
<<
BITRES
)
>>
4
);
/* Tilt of the allocation curve */
trim_offset
[
j
]
=
C
*
(
eband5ms
[
j
+
1
]
-
eband5ms
[
j
])
*
(
alloc_trim
-
5
-
LM
)
*
(
end
-
j
-
1
)
*
(
1
<<
(
LM
+
BITRES
))
>>
6
;
...
...
@@ -3603,7 +3602,7 @@ int32_t clt_compute_allocation(const int32_t *offsets, const int32_t *cap, int32
int32_t
bitsj
;
int32_t
N
=
eband5ms
[
j
+
1
]
-
eband5ms
[
j
];
bitsj
=
C
*
N
*
band_allocation
[
mid
*
len
+
j
]
<<
LM
>>
2
;
if
(
bitsj
>
0
)
bitsj
=
max
(
0
,
bitsj
+
trim_offset
[
j
]);
if
(
bitsj
>
0
)
bitsj
=
_
max
(
0
,
bitsj
+
trim_offset
[
j
]);
bitsj
+=
offsets
[
j
];
if
(
bitsj
>=
thresh
[
j
]
||
done
)
{
done
=
1
;
...
...
@@ -3626,12 +3625,12 @@ int32_t clt_compute_allocation(const int32_t *offsets, const int32_t *cap, int32
int32_t
N
=
eband5ms
[
j
+
1
]
-
eband5ms
[
j
];
bits1j
=
C
*
N
*
band_allocation
[
lo
*
len
+
j
]
<<
LM
>>
2
;
bits2j
=
hi
>=
m_CELTMode
.
nbAllocVectors
?
cap
[
j
]
:
C
*
N
*
band_allocation
[
hi
*
len
+
j
]
<<
LM
>>
2
;
if
(
bits1j
>
0
)
bits1j
=
max
(
0
,
bits1j
+
trim_offset
[
j
]);
if
(
bits2j
>
0
)
bits2j
=
max
(
0
,
bits2j
+
trim_offset
[
j
]);
if
(
bits1j
>
0
)
bits1j
=
_
max
(
0
,
bits1j
+
trim_offset
[
j
]);
if
(
bits2j
>
0
)
bits2j
=
_
max
(
0
,
bits2j
+
trim_offset
[
j
]);
if
(
lo
>
0
)
bits1j
+=
offsets
[
j
];
bits2j
+=
offsets
[
j
];
if
(
offsets
[
j
]
>
0
)
skip_start
=
j
;
bits2j
=
max
(
0
,
bits2j
-
bits1j
);
bits2j
=
_
max
(
0
,
bits2j
-
bits1j
);
bits1
[
j
]
=
bits1j
;
bits2
[
j
]
=
bits2j
;
}
...
...
@@ -3677,7 +3676,7 @@ void unquant_coarse_energy(int16_t *oldEBands, int32_t intra, int32_t C, int32_t
tell
=
ec_tell
();
if
(
budget
-
tell
>=
15
)
{
int32_t
pi
;
pi
=
2
*
min
(
i
,
20
);
pi
=
2
*
_
min
(
i
,
20
);
qi
=
ec_laplace_decode
(
prob_model
[
pi
]
<<
7
,
prob_model
[
pi
+
1
]
<<
6
);
}
else
if
(
budget
-
tell
>=
2
)
{
qi
=
ec_dec_icdf
(
small_energy_icdf
,
2
);
...
...
@@ -3688,9 +3687,9 @@ void unquant_coarse_energy(int16_t *oldEBands, int32_t intra, int32_t C, int32_t
qi
=
-
1
;
q
=
(
int32_t
)
SHL32
(
EXTEND32
(
qi
),
10
);
oldEBands
[
i
+
c
*
m_CELTMode
.
nbEBands
]
=
max
(
-
QCONST16
(
9.
f
,
10
),
oldEBands
[
i
+
c
*
m_CELTMode
.
nbEBands
]);
oldEBands
[
i
+
c
*
m_CELTMode
.
nbEBands
]
=
_
max
(
-
QCONST16
(
9.
f
,
10
),
oldEBands
[
i
+
c
*
m_CELTMode
.
nbEBands
]);
tmp
=
PSHR
(
MULT16_16
(
coef
,
oldEBands
[
i
+
c
*
m_CELTMode
.
nbEBands
]),
8
)
+
prev
[
c
]
+
SHL32
(
q
,
7
);
tmp
=
max
(
-
QCONST32
(
28.
f
,
10
+
7
),
tmp
);
tmp
=
_
max
(
-
QCONST32
(
28.
f
,
10
+
7
),
tmp
);
oldEBands
[
i
+
c
*
m_CELTMode
.
nbEBands
]
=
PSHR
(
tmp
,
7
);
prev
[
c
]
=
prev
[
c
]
+
SHL32
(
q
,
7
)
-
MULT16_16
(
beta
,
PSHR
(
q
,
8
));
}
while
(
++
c
<
C
);
...
...
src/opus_decoder/celt.h
View file @
6bedb144
...
...
@@ -36,6 +36,9 @@
#pragma GCC optimize ("Os")
#include "Arduino.h"
#include <stdint.h>
#include <cstddef>
#include <assert.h>
#define OPUS_RESET_STATE 4028
#define OPUS_GET_SAMPLE_RATE_REQUEST 4029
...
...
@@ -183,8 +186,8 @@ struct CELTMode {
extern
const
CELTMode
m_CELTMode
;
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define
_
min(a,b) ((a)<(b)?(a):(b))
#define
_
max(a,b) ((a)>(b)?(a):(b))
inline
int32_t
S_MUL
(
int32_t
a
,
int16_t
b
){
return
(
int64_t
)
b
*
a
>>
15
;}
#define C_MUL(m,a,b) do{ (m).r = SUB32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
...
...
@@ -206,7 +209,8 @@ inline int32_t S_MUL(int32_t a, int16_t b){return (int64_t)b * a >> 15;}
#define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a))))
#define EC_CLZ0 ((int32_t)sizeof(uint32_t)*CHAR_BIT)
#define _CHAR_BIT 8
#define EC_CLZ0 ((int32_t)sizeof(uint32_t)*_CHAR_BIT)
#define EC_CLZ(_x) (__builtin_clz(_x))
#define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x))
...
...
@@ -342,8 +346,8 @@ inline int32_t celt_sudiv(int32_t n, int32_t d) {
inline
int16_t
sig2word16
(
int32_t
x
){
x
=
PSHR
(
x
,
12
);
x
=
max
(
x
,
-
32768
);
x
=
min
(
x
,
32767
);
x
=
_
max
(
x
,
-
32768
);
x
=
_
min
(
x
,
32767
);
return
(
int16_t
)(
x
);
}
...
...
@@ -378,10 +382,10 @@ inline int32_t celt_maxabs16(const int16_t *x, int32_t len) {
int16_t
maxval
=
0
;
int16_t
minval
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
maxval
=
max
(
maxval
,
x
[
i
]);
minval
=
min
(
minval
,
x
[
i
]);
maxval
=
_
max
(
maxval
,
x
[
i
]);
minval
=
_
min
(
minval
,
x
[
i
]);
}
return
max
(
EXTEND32
(
maxval
),
-
EXTEND32
(
minval
));
return
_
max
(
EXTEND32
(
maxval
),
-
EXTEND32
(
minval
));
}
inline
int32_t
celt_maxabs32
(
const
int32_t
*
x
,
int32_t
len
)
{
...
...
@@ -389,10 +393,10 @@ inline int32_t celt_maxabs32(const int32_t *x, int32_t len) {
int32_t
maxval
=
0
;
int32_t
minval
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
maxval
=
max
(
maxval
,
x
[
i
]);
minval
=
min
(
minval
,
x
[
i
]);
maxval
=
_
max
(
maxval
,
x
[
i
]);
minval
=
_
min
(
minval
,
x
[
i
]);
}
return
max
(
maxval
,
-
minval
);
return
_
max
(
maxval
,
-
minval
);
}
/** Integer log in base2. Undefined for zero and negative numbers */
...
...
src/opus_decoder/opus_decoder.cpp
View file @
6bedb144
...
...
@@ -3,26 +3,38 @@
* based on Xiph.Org Foundation celt decoder
*
* Created on: 26.01.2023
* Updated on: 0
2
.02.2024
* Updated on: 0
5
.02.2024
*/
//----------------------------------------------------------------------------------------------------------------------
// O G G / O P U S I M P L.
//----------------------------------------------------------------------------------------------------------------------
#include "opus_decoder.h"
#include "celt.h"
#include "Arduino.h"
#include <vector>
// global vars
bool
s_f_opusSubsequentPage
=
false
;
bool
s_f_opusParseOgg
=
false
;
bool
s_f_newSteamTitle
=
false
;
// streamTitle
bool
s_f_opusFramePacket
=
false
;
bool
s_f_opusStereoFlag
=
false
;
bool
s_f_continuedPage
=
false
;
bool
s_f_firstPage
=
false
;
bool
s_f_lastPage
=
false
;
bool
s_f_nextChunk
=
false
;
uint8_t
s_opusChannels
=
0
;
uint8_t
s_opusCountCode
=
0
;
uint8_t
s_opusPageNr
=
0
;
uint16_t
s_opusOggHeaderSize
=
0
;
uint32_t
s_opusSamplerate
=
0
;
uint32_t
s_opusSegmentLength
=
0
;
uint32_t
s_opusBlockPicLen
=
0
;
uint32_t
s_opusCurrentFilePos
=
0
;
int32_t
s_opusBlockPicLen
=
0
;
int32_t
s_blockPicLenUntilFrameEnd
=
0
;
int32_t
s_opusRemainBlockPicLen
=
0
;
uint32_t
s_opusBlockPicPos
=
0
;
uint32_t
s_opusBlockLen
=
0
;
char
*
s_opusChbuf
=
NULL
;
int32_t
s_opusValidSamples
=
0
;
...
...
@@ -32,6 +44,8 @@ int16_t s_opusSegmentTableRdPtr = -1;
int8_t
s_opusError
=
0
;
float
s_opusCompressionRatio
=
0
;
std
::
vector
<
uint32_t
>
s_opusBlockPicItem
;
bool
OPUSDecoder_AllocateBuffers
(){
const
uint32_t
CELT_SET_END_BAND_REQUEST
=
10012
;
const
uint32_t
CELT_SET_SIGNALLING_REQUEST
=
10016
;
...
...
@@ -57,21 +71,26 @@ void OPUSDecoder_ClearBuffers(){
if
(
s_opusSegmentTable
)
memset
(
s_opusSegmentTable
,
0
,
256
*
sizeof
(
int16_t
));
}
void
OPUSsetDefaults
(){
s_f_opusSubsequentPage
=
false
;
s_f_opusParseOgg
=
false
;
s_f_newSteamTitle
=
false
;
// streamTitle
s_f_opusFramePacket
=
false
;
s_f_opusStereoFlag
=
false
;
s_opusChannels
=
0
;
s_opusSamplerate
=
0
;
s_opusSegmentLength
=
0
;
s_opusValidSamples
=
0
;
s_opusSegmentTableSize
=
0
;
s_opusOggHeaderSize
=
0
;
s_opusSegmentTableRdPtr
=
-
1
;
s_opusCountCode
=
0
;
s_opusBlockPicPos
=
0
;
s_opusCurrentFilePos
=
0
;
s_opusBlockPicLen
=
0
;
s_opusRemainBlockPicLen
=
0
;
s_blockPicLenUntilFrameEnd
=
0
;
s_opusBlockLen
=
0
;
s_opusPageNr
=
0
;
s_opusError
=
0
;
s_opusBlockPicItem
.
clear
();
s_opusBlockPicItem
.
shrink_to_fit
();
}
//----------------------------------------------------------------------------------------------------------------------
...
...
@@ -90,26 +109,112 @@ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
int
len
=
0
;
if
(
s_f_opusParseOgg
){
s_f_opusParseOgg
=
false
;
fs
=
0
;
M
=
0
;
paddingBytes
=
0
;
s_opusCountCode
=
0
;
ret
=
OPUSparseOGG
(
inbuf
,
bytesLeft
);
if
(
ret
==
ERR_OPUS_NONE
)
return
OPUS_PARSE_OGG_DONE
;
// ok
else
return
ret
;
// error
if
(
ret
!=
ERR_OPUS_NONE
)
return
ret
;
// error
inbuf
+=
s_opusOggHeaderSize
;
}
if
(
s_opusPageNr
==
0
){
// OpusHead
s_f_opusParseOgg
=
true
;
// goto next page
ret
=
parseOpusHead
(
inbuf
,
s_opusSegmentTable
[
0
]);
*
bytesLeft
-=
s_opusSegmentTable
[
0
];
s_opusCurrentFilePos
+=
s_opusSegmentTable
[
0
];
if
(
ret
==
1
){
s_opusPageNr
++
;}
if
(
ret
==
0
){
log_e
(
"OpusHead not found"
);
}
return
OPUS_PARSE_OGG_DONE
;
}
if
(
s_opusPageNr
==
1
){
// OpusComment
if
(
s_opusBlockLen
>
0
)
{
goto
processChunk
;}
ret
=
parseOpusComment
(
inbuf
,
s_opusSegmentTable
[
0
]);
if
(
ret
==
0
)
log_e
(
"OpusCommemtPage not found"
);
s_opusBlockLen
=
s_opusSegmentTable
[
0
];
processChunk:
// we can't return more than 2* 4096 bytes at a time (max OPUS frame size)
if
(
s_opusBlockLen
<=
8192
)
{
*
bytesLeft
-=
s_opusBlockLen
;
s_opusCurrentFilePos
+=
s_opusBlockLen
;
s_opusBlockLen
=
0
;
s_opusPageNr
++
;
s_f_nextChunk
=
true
;
s_f_opusParseOgg
=
true
;
}
else
{
s_opusBlockLen
-=
8192
;
*
bytesLeft
-=
8192
;
s_opusCurrentFilePos
+=
8192
;
}
return
OPUS_PARSE_OGG_DONE
;
}
if
(
s_opusPageNr
==
2
){
// OpusComment Subsequent Pages
static
int32_t
opusSegmentLength
=
0
;
if
(
s_f_nextChunk
){
s_f_nextChunk
=
false
;
opusSegmentLength
=
s_opusSegmentLength
;
}
// log_i("page(2) opusSegmentLength %i, s_opusRemainBlockPicLen %i", opusSegmentLength, s_opusRemainBlockPicLen);
if
(
s_opusRemainBlockPicLen
<=
0
&&
opusSegmentLength
<=
0
){
s_opusPageNr
++
;
// fall through
s_f_opusParseOgg
=
true
;
if
(
s_opusBlockPicItem
.
size
()
>
0
){
// get blockpic data
log_i
(
"---------------------------------------------------------------------------"
);
log_i
(
"metadata blockpic found at pos %i, size %i bytes"
,
s_opusBlockPicPos
,
s_opusBlockPicLen
);
for
(
int
i
=
0
;
i
<
s_opusBlockPicItem
.
size
();
i
+=
2
){
log_i
(
"segment %02i, pos %07i, len %05i"
,
i
/
2
,
s_opusBlockPicItem
[
i
],
s_opusBlockPicItem
[
i
+
1
]);
}
log_i
(
"---------------------------------------------------------------------------"
);
}
return
OPUS_PARSE_OGG_DONE
;
}
if
(
opusSegmentLength
==
0
){
s_f_opusParseOgg
=
true
;
s_f_nextChunk
=
true
;
return
OPUS_PARSE_OGG_DONE
;
}
int
m
=
min
(
s_opusRemainBlockPicLen
,
opusSegmentLength
);
if
(
m
>
8192
){
s_opusRemainBlockPicLen
-=
8192
;
opusSegmentLength
-=
8192
;
*
bytesLeft
-=
8192
;
s_opusCurrentFilePos
+=
8192
;
return
OPUS_PARSE_OGG_DONE
;
}
if
(
m
==
s_opusRemainBlockPicLen
){
*
bytesLeft
-=
s_opusRemainBlockPicLen
;
s_opusCurrentFilePos
+=
s_opusRemainBlockPicLen
;
opusSegmentLength
-=
s_opusRemainBlockPicLen
;
s_opusRemainBlockPicLen
=
0
;
*
bytesLeft
-=
opusSegmentLength
;
// paddind bytes
s_opusCurrentFilePos
+=
opusSegmentLength
;
opusSegmentLength
=
0
;
return
OPUS_PARSE_OGG_DONE
;
}
if
(
m
==
opusSegmentLength
){
*
bytesLeft
-=
opusSegmentLength
;
s_opusCurrentFilePos
+=
opusSegmentLength
;
s_opusRemainBlockPicLen
-=
opusSegmentLength
;
opusSegmentLength
=
0
;
return
OPUS_PARSE_OGG_DONE
;
}
log_e
(
"never reach this!"
);
}
if
(
s_opusCountCode
>
0
)
goto
FramePacking
;
// more than one frame in the packet
if
(
s_f_opusFramePacket
){
if
(
s_opusSegmentTableSize
>
0
){
s_opusSegmentTableRdPtr
++
;
s_opusSegmentTableSize
--
;
len
=
s_opusSegmentTable
[
s_opusSegmentTableRdPtr
];
}
configNr
=
parseOpusTOC
(
inbuf
[
0
]);
samplesPerFrame
=
opus_packet_get_samples_per_frame
(
inbuf
,
s_opusSamplerate
);
switch
(
configNr
){
case
16
...
19
:
endband
=
13
;
// OPUS_BANDWIDTH_NARROWBAND
break
;
...
...
@@ -123,7 +228,6 @@ int OPUSDecode(uint8_t *inbuf, int *bytesLeft, short *outbuf){
break
;
}
celt_decoder_ctl
(
CELT_SET_END_BAND_REQUEST
,
endband
);
}
FramePacking:
// https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2.html 3.2. Frame Packing
...
...
@@ -131,6 +235,7 @@ FramePacking: // https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2
switch
(
s_opusCountCode
){
case
0
:
// Code 0: One Frame in the Packet
*
bytesLeft
-=
len
;
s_opusCurrentFilePos
+=
len
;
len
--
;
inbuf
++
;
ec_dec_init
((
uint8_t
*
)
inbuf
,
len
);
...
...
@@ -153,6 +258,7 @@ FramePacking: // https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2
M
=
inbuf
[
1
]
&
0x3F
;
// max framecount
// log_i("v %i, p %i, M %i", v, p, M);
*
bytesLeft
-=
2
;
s_opusCurrentFilePos
+=
2
;
len
-=
2
;
inbuf
+=
2
;
...
...
@@ -169,12 +275,14 @@ FramePacking: // https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2
paddingLength
+=
i
;
*
bytesLeft
-=
paddingLength
;
s_opusCurrentFilePos
+=
paddingLength
;
len
-=
paddingLength
;
inbuf
+=
paddingLength
;
}
fs
=
(
len
-
paddingBytes
)
/
M
;
}
*
bytesLeft
-=
fs
;
s_opusCurrentFilePos
+=
fs
;
ec_dec_init
((
uint8_t
*
)
inbuf
,
fs
);
ret
=
celt_decode_with_ec
(
inbuf
,
fs
,
(
int16_t
*
)
outbuf
,
samplesPerFrame
);
if
(
ret
<
0
)
goto
exit
;
// celt error
...
...
@@ -192,9 +300,8 @@ FramePacking: // https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2
}
exit:
if
(
s_opusSegmentTableSize
==
0
){
if
(
s_opusSegmentTableSize
==
0
){
s_opusSegmentTableRdPtr
=
-
1
;
// back to the parking position
s_f_opusFramePacket
=
false
;
s_f_opusParseOgg
=
true
;
}
return
ret
;
...
...
@@ -288,43 +395,55 @@ int parseOpusComment(uint8_t *inbuf, int nBytes){ // reference https://exif
// reference https://www.rfc-editor.org/rfc/rfc7845#section-5
int
idx
=
OPUS_specialIndexOf
(
inbuf
,
"OpusTags"
,
10
);
if
(
idx
!=
0
)
return
0
;
// is not OpusTags
char
*
artist
=
NULL
;
char
*
title
=
NULL
;
uint16_t
pos
=
8
;
nBytes
-=
8
;
uint32_t
vendorLength
=
*
(
inbuf
+
11
)
<<
24
;
// lengt of vendor string, e.g. Lavf58.65.101
vendorLength
+=
*
(
inbuf
+
10
)
<<
16
;
vendorLength
+=
*
(
inbuf
+
9
)
<<
8
;
vendorLength
+=
*
(
inbuf
+
8
);
pos
+=
vendorLength
+
4
;
nBytes
-=
(
vendorLength
+
4
);
uint32_t
commentListLength
=
*
(
inbuf
+
3
+
pos
)
<<
24
;
// nr. of comment entries
commentListLength
+=
*
(
inbuf
+
2
+
pos
)
<<
16
;
commentListLength
+=
*
(
inbuf
+
1
+
pos
)
<<
8
;
commentListLength
+=
*
(
inbuf
+
0
+
pos
);
pos
+=
4
;
nBytes
-=
4
;
for
(
int
i
=
0
;
i
<
commentListLength
;
i
++
){
uint32_t
commentStringLen
=
*
(
inbuf
+
3
+
pos
)
<<
24
;
commentStringLen
+=
*
(
inbuf
+
2
+
pos
)
<<
16
;
commentStringLen
+=
*
(
inbuf
+
1
+
pos
)
<<
8
;
commentStringLen
+=
*
(
inbuf
+
0
+
pos
);
pos
+=
4
;
nBytes
-=
4
;
idx
=
OPUS_specialIndexOf
(
inbuf
+
pos
,
"artist="
,
10
);
if
(
idx
==
-
1
)
idx
=
OPUS_specialIndexOf
(
inbuf
+
pos
,
"ARTIST="
,
10
);
if
(
idx
==
0
){
artist
=
strndup
((
const
char
*
)(
inbuf
+
pos
+
7
),
commentStringLen
-
7
);
}
idx
=
OPUS_specialIndexOf
(
inbuf
+
pos
,
"title="
,
10
);
if
(
idx
==
-
1
)
idx
=
OPUS_specialIndexOf
(
inbuf
+
pos
,
"TITLE="
,
10
);
if
(
idx
==
0
){
title
=
strndup
((
const
char
*
)(
inbuf
+
pos
+
6
),
commentStringLen
-
6
);
}
idx
=
OPUS_specialIndexOf
(
inbuf
+
pos
,
"metadata_block_picture="
,
25
);
if
(
idx
==
-
1
)
idx
=
OPUS_specialIndexOf
(
inbuf
+
pos
,
"METADATA_BLOCK_PICTURE="
,
25
);
if
(
idx
==
0
){
s_opusBlockPicLen
=
commentStringLen
-
23
;
s_opusBlockPicPos
+=
pos
+
23
;
uint16_t
blockPicLenUntilFrameEnd
=
commentStringLen
-
23
;
log_i
(
"metadata block picture found at pos %i, length %i, first blockLength %i"
,
s_opusBlockPicPos
,
s_opusBlockPicLen
,
blockPicLenUntilFrameEnd
);
s_opusBlockPicLen
-=
blockPicLenUntilFrameEnd
;
s_opusBlockPicPos
+=
s_opusCurrentFilePos
+
pos
+
23
;
s_blockPicLenUntilFrameEnd
=
nBytes
-
23
;
// log_i("metadata block picture found at pos %i, length %i", s_opusBlockPicPos, s_opusBlockPicLen);
uint32_t
pLen
=
_min
(
s_blockPicLenUntilFrameEnd
,
s_opusBlockPicLen
);
if
(
pLen
){
s_opusBlockPicItem
.
push_back
(
s_opusBlockPicPos
);
s_opusBlockPicItem
.
push_back
(
pLen
);
}
s_opusRemainBlockPicLen
=
s_opusBlockPicLen
-
s_blockPicLenUntilFrameEnd
;
}
pos
+=
commentStringLen
;
nBytes
-=
commentStringLen
;
}
if
(
artist
&&
title
){
strcpy
(
s_opusChbuf
,
artist
);
...
...
@@ -379,8 +498,6 @@ int parseOpusHead(uint8_t *inbuf, int nBytes){ // reference https://wiki.xiph.o
//----------------------------------------------------------------------------------------------------------------------
int
OPUSparseOGG
(
uint8_t
*
inbuf
,
int
*
bytesLeft
){
// reference https://www.xiph.org/ogg/doc/rfc3533.txt
s_f_opusParseOgg
=
false
;
int
ret
=
0
;
int
idx
=
OPUS_specialIndexOf
(
inbuf
,
"OggS"
,
6
);
if
(
idx
!=
0
)
return
ERR_OPUS_DECODER_ASYNC
;
...
...
@@ -419,6 +536,7 @@ int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph
int
n
=
*
(
inbuf
+
27
+
i
);
while
(
*
(
inbuf
+
27
+
i
)
==
255
){
i
++
;
if
(
i
==
pageSegments
)
break
;
n
+=
*
(
inbuf
+
27
+
i
);
}
segmentTableWrPtr
++
;
...
...
@@ -428,31 +546,24 @@ int OPUSparseOGG(uint8_t *inbuf, int *bytesLeft){ // reference https://www.xiph
s_opusSegmentTableSize
=
segmentTableWrPtr
+
1
;
s_opusCompressionRatio
=
(
float
)(
960
*
2
*
pageSegments
)
/
s_opusSegmentLength
;
// const 960 validBytes out
bool
continuedPage
=
headerType
&
0x01
;
// set: page contains data of a packet continued from the previous page
bool
firstPage
=
headerType
&
0x02
;
// set: this is the first page of a logical bitstream (bos)
bool
lastPage
=
headerType
&
0x04
;
// set: this is the last page of a logical bitstream (eos)
s_f_
continuedPage
=
headerType
&
0x01
;
// set: page contains data of a packet continued from the previous page
s_f_
firstPage
=
headerType
&
0x02
;
// set: this is the first page of a logical bitstream (bos)
s_f_
lastPage
=
headerType
&
0x04
;
// set: this is the last page of a logical bitstream (eos)
// log_i("page %x", headerType
);
// log_i("firstPage %i, continuedPage %i, lastPage %i",s_f_firstPage, s_f_continuedPage, s_f_lastPage
);
uint16_t
headerSize
=
pageSegments
+
27
;
(
void
)
continuedPage
;
(
void
)
lastPage
;
*
bytesLeft
-=
headerSize
;
s_opusBlockPicPos
+=
headerSize
;
if
(
firstPage
||
s_f_opusSubsequentPage
){
// OpusHead or OggComment may follows
ret
=
parseOpusHead
(
inbuf
+
headerSize
,
s_opusSegmentTable
[
0
]);
if
(
ret
==
1
){
*
bytesLeft
-=
s_opusSegmentTable
[
0
];
s_opusBlockPicPos
+=
s_opusSegmentTable
[
0
];}
if
(
ret
<
0
){
*
bytesLeft
-=
s_opusSegmentTable
[
0
];
s_opusBlockPicPos
+=
s_opusSegmentTable
[
0
];
return
ret
;}
ret
=
parseOpusComment
(
inbuf
+
headerSize
,
s_opusSegmentTable
[
0
]);
if
(
ret
==
1
)
*
bytesLeft
-=
s_opusSegmentTable
[
0
];
if
(
ret
<
0
){
*
bytesLeft
-=
s_opusSegmentTable
[
0
];
return
ret
;}
s_f_opusParseOgg
=
true
;
// goto next page
s_opusCurrentFilePos
+=
headerSize
;
s_opusOggHeaderSize
=
headerSize
;
int32_t
pLen
=
_min
((
int32_t
)
s_opusSegmentLength
,
s_opusRemainBlockPicLen
);
// log_i("s_opusSegmentLength %i, s_opusRemainBlockPicLen %i", s_opusSegmentLength, s_opusRemainBlockPicLen);
if
(
s_opusBlockPicLen
&&
pLen
>
0
){
s_opusBlockPicItem
.
push_back
(
s_opusCurrentFilePos
);
s_opusBlockPicItem
.
push_back
(
pLen
);
}
s_f_opusFramePacket
=
true
;
if
(
firstPage
)
s_f_opusSubsequentPage
=
true
;
else
s_f_opusSubsequentPage
=
false
;
return
ERR_OPUS_NONE
;
// no error
return
ERR_OPUS_NONE
;
}
//----------------------------------------------------------------------------------------------------------------------
...
...
src/opus_decoder/opus_decoder.h
View file @
6bedb144
...
...
@@ -3,7 +3,10 @@
//#pragma GCC optimize ("O3")
//#pragma GCC diagnostic ignored "-Wnarrowing"
#include "Arduino.h"
#include <stdint.h>
#include <memory.h>
enum
:
int8_t
{
OPUS_PARSE_OGG_DONE
=
100
,
ERR_OPUS_NONE
=
0
,
...
...
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