Skip to content

Commit ccf20a7

Browse files
committed
OPUSgetMode() added
1 parent 063000b commit ccf20a7

File tree

4 files changed

+94
-67
lines changed

4 files changed

+94
-67
lines changed

src/Audio.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
audio.cpp
44
55
Created on: Oct 28.2018 */char audioI2SVers[] ="\
6-
Version 3.3.1a ";
7-
/* Updated on: Jun 12.2025
6+
Version 3.3.2 ";
7+
/* Updated on: Jun 14.2025
88
99
Author: Wolle (schreibfaul1)
1010
Audio library for ESP32, ESP32-S3 or ESP32-P4
@@ -321,6 +321,7 @@ void Audio::setDefaults() {
321321
m_M4A_objectType = 0;
322322
m_M4A_sampleRate = 0;
323323
m_sumBytesDecoded = 0;
324+
m_opus_mode = 0;
324325
m_vuLeft = m_vuRight = 0; // #835
325326
std::fill(std::begin(m_inputHistory), std::end(m_inputHistory), 0);
326327
if(m_f_reset_m3u8Codec){m_m3u8Codec = CODEC_AAC;} // reset to default
@@ -4814,7 +4815,16 @@ int Audio::sendBytes(uint8_t* data, size_t len) {
48144815
// log_i("---------------------------------------------------------------------------");
48154816
if(audio_oggimage) audio_oggimage(audiofile, vec);
48164817
}
4818+
4819+
if(m_opus_mode != OPUSgetMode()){
4820+
m_opus_mode = OPUSgetMode();
4821+
if(m_opus_mode == MODE_CELT_ONLY) log_info("Opus Mode: CELT_ONLY");
4822+
if(m_opus_mode == MODE_HYBRID) log_info("Opus Mode: HYBRID");
4823+
if(m_opus_mode == MODE_SILK_ONLY) log_info("Opus Mode: SILK_ONLY");
4824+
if(m_opus_mode == MODE_NONE) log_info("Opus Mode: NONE");
4825+
}
48174826
break;
4827+
48184828
case CODEC_VORBIS: if(m_decodeError == VORBIS_PARSE_OGG_DONE) return bytesDecoded; // nothing to play
48194829
m_validSamples = VORBISGetOutputSamps();
48204830
st = VORBISgetStreamTitle();

src/Audio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,7 @@ class Audio : private AudioBuffer{
726726
uint16_t m_vol = 21; // volume
727727
uint16_t m_vol_steps = 21; // default
728728
int16_t m_inputHistory[6] = {0}; // used in resampleTo48kStereo()
729+
uint16_t m_opus_mode = 0; // celt_only, silk_only or hybrid
729730
double m_limit_left = 0; // limiter 0 ... 1, left channel
730731
double m_limit_right = 0; // limiter 0 ... 1, right channel
731732
uint8_t m_timeoutCounter = 0; // timeout counter

src/opus_decoder/opus_decoder.cpp

Lines changed: 58 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extern silk_ptr_obj<silk_DecControlStruct_t> s_silk_DecControlStruct;
3030

3131
enum {OPUS_BANDWIDTH_NARROWBAND = 1101, OPUS_BANDWIDTH_MEDIUMBAND = 1102, OPUS_BANDWIDTH_WIDEBAND = 1103,
3232
OPUS_BANDWIDTH_SUPERWIDEBAND = 1104, OPUS_BANDWIDTH_FULLBAND = 1105};
33-
enum {MODE_NONE = 0, MODE_SILK_ONLY = 1000, MODE_HYBRID = 1001, MODE_CELT_ONLY = 1002};
33+
3434

3535
bool s_f_opusParseOgg = false;
3636
bool s_f_newSteamTitle = false; // streamTitle
@@ -70,6 +70,10 @@ int8_t s_opusError = 0;
7070
int16_t s_prev_mode = 0;
7171
float s_opusCompressionRatio = 0;
7272

73+
ofp2 s_ofp2; // used in opus_FramePacking_Code2
74+
ofp3 s_ofp3; // used in opus_FramePacking_Code3
75+
odp3 s_odp3; // used in opusDecodePage3
76+
7377
std::vector <uint32_t>s_opusBlockPicItem;
7478

7579
bool OPUSDecoder_AllocateBuffers(){
@@ -125,6 +129,9 @@ void OPUSDecoder_ClearBuffers(){
125129
s_opusCountCode = 0;
126130
}
127131
void OPUSsetDefaults(){
132+
memset(&s_ofp2, 0, sizeof(s_ofp2));
133+
memset(&s_ofp3, 0, sizeof(s_ofp3));
134+
memset(&s_odp3, 0, sizeof(s_odp3));
128135
s_f_opusParseOgg = false;
129136
s_f_newSteamTitle = false; // streamTitle
130137
s_f_opusNewMetadataBlockPicture = false;
@@ -154,6 +161,7 @@ void OPUSsetDefaults(){
154161
s_opusError = 0;
155162
s_endband = 0;
156163
s_prev_mode = MODE_NONE;
164+
s_ofp3.firstCall = true;
157165
s_opusBlockPicItem.clear(); s_opusBlockPicItem.shrink_to_fit();
158166
}
159167

@@ -256,20 +264,16 @@ int32_t opusDecodePage3(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLeng
256264
if(s_opusAudioDataStart == 0){
257265
s_opusAudioDataStart = s_opusCurrentFilePos;
258266
}
259-
260-
261267
s_endband = 21;
262-
static int8_t configNr = 0;
263-
static uint16_t samplesPerFrame = 0;
264268

265269
int32_t ret = 0;
266270

267271
if(s_frameCount > 0) goto FramePacking; // more than one frame in the packet
268272

269-
configNr = parseOpusTOC(inbuf[0]);
270-
if(configNr < 0) {log_e("something went wrong"); return configNr;} // SILK or Hybrid mode
273+
s_odp3.configNr = parseOpusTOC(inbuf[0]);
274+
if(s_odp3.configNr < 0) {log_e("something went wrong"); return s_odp3.configNr;} // SILK or Hybrid mode
271275

272-
switch(configNr){
276+
switch(s_odp3.configNr){
273277
case 0 ... 3: s_endband = 0; // OPUS_BANDWIDTH_SILK_NARROWBAND
274278
s_mode = MODE_SILK_ONLY;
275279
s_bandWidth = OPUS_BANDWIDTH_NARROWBAND;
@@ -309,7 +313,7 @@ int32_t opusDecodePage3(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLeng
309313
s_mode = MODE_CELT_ONLY;
310314
s_bandWidth = OPUS_BANDWIDTH_FULLBAND;
311315
break;
312-
default: log_e("unknown bandwidth, configNr is: %d", configNr);
316+
default: log_e("unknown bandwidth, configNr is: %d", s_odp3.configNr);
313317
s_endband = 21; // assume OPUS_BANDWIDTH_FULLBAND
314318
break;
315319
}
@@ -322,23 +326,23 @@ int32_t opusDecodePage3(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLeng
322326
// silk_InitDecoder();
323327
}
324328

325-
samplesPerFrame = opus_packet_get_samples_per_frame(inbuf, /*s_opusSamplerate*/ 48000);
329+
s_odp3.samplesPerFrame = opus_packet_get_samples_per_frame(inbuf, /*s_opusSamplerate*/ 48000);
326330

327331
FramePacking: // https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2.html 3.2. Frame Packing
328332
//log_i("s_opusCountCode %i, configNr %i", s_opusCountCode, configNr);
329333

330334
switch(s_opusCountCode){
331335
case 0: // Code 0: One Frame in the Packet
332-
ret = opus_FramePacking_Code0(inbuf, bytesLeft, outbuf, segmentLength, samplesPerFrame);
336+
ret = opus_FramePacking_Code0(inbuf, bytesLeft, outbuf, segmentLength, s_odp3.samplesPerFrame);
333337
break;
334338
case 1: // Code 1: Two Frames in the Packet, Each with Equal Compressed Size
335-
ret = opus_FramePacking_Code1(inbuf, bytesLeft, outbuf, segmentLength, samplesPerFrame, &s_frameCount);
339+
ret = opus_FramePacking_Code1(inbuf, bytesLeft, outbuf, segmentLength, s_odp3.samplesPerFrame, &s_frameCount);
336340
break;
337341
case 2: // Code 2: Two Frames in the Packet, with Different Compressed Sizes
338-
ret = opus_FramePacking_Code2(inbuf, bytesLeft, outbuf, segmentLength, samplesPerFrame, &s_frameCount);
342+
ret = opus_FramePacking_Code2(inbuf, bytesLeft, outbuf, segmentLength, s_odp3.samplesPerFrame, &s_frameCount);
339343
break;
340344
case 3: // Code 3: A Signaled Number of Frames in the Packet
341-
ret = opus_FramePacking_Code3(inbuf, bytesLeft, outbuf, segmentLength, samplesPerFrame, &s_frameCount);
345+
ret = opus_FramePacking_Code3(inbuf, bytesLeft, outbuf, segmentLength, s_odp3.samplesPerFrame, &s_frameCount);
342346
break;
343347
default:
344348
log_e("unknown countCode %i", s_opusCountCode);
@@ -357,11 +361,6 @@ if(!packetLen) {log_e("packetLen = 0"); return 0;}
357361
s_silk_DecControlStruct->nChannelsInternal = s_opusChannels;
358362
s_silk_DecControlStruct->API_sampleRate = 48000;
359363

360-
if(s_mode != s_prev_mode) {
361-
if(s_mode == MODE_CELT_ONLY) log_w("Celt");
362-
if(s_mode == MODE_SILK_ONLY) log_w("Silk");
363-
if(s_mode == MODE_HYBRID) log_w("Hybrid");
364-
}
365364
if(s_prev_mode == MODE_NONE) celt_decoder_ctl((int32_t)OPUS_RESET_STATE);
366365

367366
ec_dec_init(inbuf, packetLen);
@@ -506,26 +505,25 @@ int8_t opus_FramePacking_Code1(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outb
506505
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
507506
*/
508507
int32_t ret = 0;
509-
static uint16_t c1fs = 0;
510508
if(*frameCount == 0){
511509
packetLen--;
512510
inbuf++;
513511
*bytesLeft -= 1;
514512
s_opusCurrentFilePos += 1;
515-
c1fs = packetLen / 2;
513+
s_ofp3.c1fs = packetLen / 2;
516514
// log_w("OPUS countCode 1 len %i, c1fs %i", len, c1fs);
517515
*frameCount = 2;
518516
}
519517
if(*frameCount > 0){
520-
ret = opus_decode_frame(inbuf, outbuf, c1fs, samplesPerFrame);
518+
ret = opus_decode_frame(inbuf, outbuf, s_ofp3.c1fs, samplesPerFrame);
521519
// log_w("code 1, ret %i", ret);
522520
if(ret < 0){
523521
*frameCount = 0;
524522
return ret; // decode err
525523
}
526524
s_opusValidSamples = ret;
527-
*bytesLeft -= c1fs;
528-
s_opusCurrentFilePos += c1fs;
525+
*bytesLeft -= s_ofp3.c1fs;
526+
s_opusCurrentFilePos += s_ofp3.c1fs;
529527
}
530528
*frameCount -= 1;
531529
return ERR_OPUS_NONE;
@@ -561,50 +559,48 @@ int8_t opus_FramePacking_Code2(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outb
561559
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
562560
*/
563561
int32_t ret = 0;
564-
static uint16_t firstFrameLength = 0;
565-
static uint16_t secondFrameLength = 0;
566562

567563
if(*frameCount == 0){
568564
uint8_t b1 = inbuf[1];
569565
uint8_t b2 = inbuf[2];
570566
if(b1 < 252){
571-
firstFrameLength = b1;
567+
s_ofp2.firstFrameLength = b1;
572568
packetLen -= 2;
573569
*bytesLeft -= 2;
574570
s_opusCurrentFilePos += 2;
575571
inbuf += 2;
576572
}
577573
else{
578-
firstFrameLength = b1 + (b2 * 4);
574+
s_ofp2.firstFrameLength = b1 + (b2 * 4);
579575
packetLen -= 3;
580576
*bytesLeft -= 3;
581577
s_opusCurrentFilePos += 3;
582578
inbuf += 3;
583579
}
584-
secondFrameLength = packetLen - firstFrameLength;
580+
s_ofp2.secondFrameLength = packetLen - s_ofp2.firstFrameLength;
585581
*frameCount = 2;
586582
}
587583
if(*frameCount == 2){
588-
ret = opus_decode_frame(inbuf, outbuf, firstFrameLength, samplesPerFrame);
584+
ret = opus_decode_frame(inbuf, outbuf, s_ofp2.firstFrameLength, samplesPerFrame);
589585
// log_w("code 2, ret %i", ret);
590586
if(ret < 0){
591587
*frameCount = 0;
592588
return ret; // decode err
593589
}
594590
s_opusValidSamples = ret;
595-
*bytesLeft -= firstFrameLength;
596-
s_opusCurrentFilePos += firstFrameLength;
591+
*bytesLeft -= s_ofp2.firstFrameLength;
592+
s_opusCurrentFilePos += s_ofp2.firstFrameLength;
597593
}
598594
if(*frameCount == 1){
599-
ret = opus_decode_frame(inbuf, outbuf, secondFrameLength, samplesPerFrame);
595+
ret = opus_decode_frame(inbuf, outbuf, s_ofp2.secondFrameLength, samplesPerFrame);
600596
// log_w("code 2, ret %i", ret);
601597
if(ret < 0){
602598
*frameCount = 0;
603599
return ret; // decode err
604600
}
605601
s_opusValidSamples = ret;
606-
*bytesLeft -= secondFrameLength;
607-
s_opusCurrentFilePos += secondFrameLength;
602+
*bytesLeft -= s_ofp2.secondFrameLength;
603+
s_opusCurrentFilePos += s_ofp2.secondFrameLength;
608604
}
609605
*frameCount -= 1;
610606
return ERR_OPUS_NONE;
@@ -710,76 +706,70 @@ int8_t opus_FramePacking_Code3(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outb
710706
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
711707
712708
*/
713-
static bool firstCall = true;
714-
static bool v = false; // VBR indicator
715-
static bool p = false; // padding exists
716-
static int16_t fs = 0; // frame size
717-
static uint8_t M = 0; // nr of frames
718-
static int32_t spf = 0; // static samples per frame
719-
static int32_t paddingLength = 0;
709+
720710
uint32_t idx = 0; // includes TOC byte
721711
int32_t ret = 0;
722712
int32_t remainingBytes = 0;
723713
uint16_t vfs[48] = {0}; // variable frame size
724714

725-
if (firstCall) {
726-
firstCall = false;
715+
if (s_ofp3.firstCall) {
716+
s_ofp3.firstCall = false;
727717
s_opusCurrentFilePos += packetLen;
728-
paddingLength = 0;
718+
s_ofp3.paddingLength = 0;
729719
idx = 1; // skip TOC byte
730-
spf = samplesPerFrame;
731-
if (inbuf[idx] & 0b10000000) v = true; // VBR indicator
732-
if (inbuf[idx] & 0b01000000) p = true; // padding bit
733-
M = inbuf[idx] & 0b00111111; // framecount
734-
*frameCount = M;
720+
s_ofp3.spf = samplesPerFrame;
721+
if (inbuf[idx] & 0b10000000) s_ofp3.v = true; // VBR indicator
722+
if (inbuf[idx] & 0b01000000) s_ofp3.p = true; // padding bit
723+
s_ofp3.M = inbuf[idx] & 0b00111111; // framecount
724+
*frameCount = s_ofp3.M;
735725
idx++;
736-
if (p) {
737-
while (inbuf[idx] == 255) { paddingLength += 255, idx++; }
738-
paddingLength += inbuf[idx];
726+
if (s_ofp3.p) {
727+
while (inbuf[idx] == 255) { s_ofp3.paddingLength += 255, idx++; }
728+
s_ofp3.paddingLength += inbuf[idx];
739729
idx++;
740730
}
741-
if (v && M) { // variable frame size
731+
if (s_ofp3.v && s_ofp3.M) { // variable frame size
742732
uint8_t m = 0;
743-
while(m < M) {
733+
while(m < s_ofp3.M) {
744734
vfs[m] = inbuf[idx];
745735
if(vfs[m] == 255) {vfs[m] = 255; idx++;}
746736
idx++;
747737
m++;
748738
// log_e("vfs[m] %i", vfs[m]);
749739
}
750740
}
751-
remainingBytes = packetLen - paddingLength - idx;
741+
remainingBytes = packetLen - s_ofp3.paddingLength - idx;
752742
if (remainingBytes < 0) {
753743
// log_e("fs %i", fs);
754744
*bytesLeft -= packetLen;
755745
*frameCount = 0;
756-
firstCall = true;
746+
s_ofp3.firstCall = true;
757747
return ERR_OPUS_NONE;
758748
}
759-
if(!v){
760-
fs = remainingBytes / M;
749+
if(!s_ofp3.v){
750+
s_ofp3.fs = remainingBytes / s_ofp3.M;
761751
}
762-
if (fs > remainingBytes) {
752+
if (s_ofp3.fs > remainingBytes) {
763753
*bytesLeft -= packetLen;
764754
*frameCount = 0;
765-
firstCall = true;
755+
s_ofp3.firstCall = true;
766756
return ERR_OPUS_NONE;
767757
}
768758
// log_w("remainingBytes %i, packetLen %i, paddingLength %i, idx %i, fs %i, frameCount %i", remainingBytes, packetLen, paddingLength, idx, fs, *frameCount);
769759
*bytesLeft -= idx;
770760
}
771761
if(*frameCount > 0){
772-
if(v){ret = opus_decode_frame(inbuf + idx, outbuf, vfs[M - (*frameCount)], spf); *bytesLeft -= vfs[M - (*frameCount)]; /* log_e("code 3, vfs[M - (*frameCount)], spf) %i", vfs[M - (*frameCount)], spf); */ }
773-
else{ ret = opus_decode_frame(inbuf + idx, outbuf, fs, spf); *bytesLeft -= fs; /* log_e("code 3, fs, spf) %i", fs, spf); */ }
762+
if(s_ofp3.v){ret = opus_decode_frame(inbuf + idx, outbuf, vfs[s_ofp3.M - (*frameCount)], s_ofp3.spf); *bytesLeft -= vfs[s_ofp3.M - (*frameCount)]; /* log_e("code 3, vfs[M - (*frameCount)], spf) %i", vfs[M - (*frameCount)], spf); */ }
763+
else{ ret = opus_decode_frame(inbuf + idx, outbuf, s_ofp3.fs, s_ofp3.spf); *bytesLeft -= s_ofp3.fs; /* log_e("code 3, fs, spf) %i", fs, spf); */ }
774764
// log_w("code 3, ret %i", ret);
775765
*frameCount -= 1;
776766
s_opusValidSamples = ret;
777767
if(*frameCount > 0) return OPUS_CONTINUE;
778768
}
779-
*bytesLeft -= paddingLength;
769+
*bytesLeft -= s_ofp3.paddingLength;
780770
*frameCount = 0;
781771
s_opusValidSamples = samplesPerFrame;
782-
firstCall = true;
772+
s_ofp3.firstCall = true;
783773
return ERR_OPUS_NONE;
784774
}
785775

@@ -833,6 +823,9 @@ char* OPUSgetStreamTitle(){
833823
}
834824
return NULL;
835825
}
826+
uint16_t OPUSgetMode(){
827+
return s_mode;
828+
}
836829
vector<uint32_t> OPUSgetMetadataBlockPicture(){
837830
if(s_f_opusNewMetadataBlockPicture){
838831
s_f_opusNewMetadataBlockPicture = false;

src/opus_decoder/opus_decoder.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,28 @@ enum : int8_t {OPUS_END = 120,
3535
ERR_OPUS_CELT_START_BAND = -27,
3636
ERR_CELT_OPUS_INTERNAL_ERROR = -28};
3737

38+
enum {MODE_NONE = 0, MODE_SILK_ONLY = 1000, MODE_HYBRID = 1001, MODE_CELT_ONLY = 1002};
39+
typedef struct _ofp2 {
40+
uint16_t firstFrameLength;
41+
uint16_t secondFrameLength;
42+
} ofp2;
43+
44+
typedef struct _ofp3 { // opus_FramePacking_Code
45+
bool firstCall = true;
46+
bool v = false; // VBR indicator
47+
bool p = false; // padding exists
48+
int16_t fs = 0; // frame size
49+
uint8_t M = 0; // nr of frames
50+
int32_t spf = 0; // samples per frame
51+
int32_t paddingLength = 0;
52+
uint16_t c1fs = 0;
53+
} ofp3;
54+
55+
typedef struct _odp3 {
56+
int8_t configNr;
57+
uint16_t samplesPerFrame;
58+
} odp3;
59+
3860
bool OPUSDecoder_AllocateBuffers();
3961
void OPUSDecoder_FreeBuffers();
4062
void OPUSDecoder_ClearBuffers();
@@ -53,6 +75,7 @@ uint32_t OPUSGetBitRate();
5375
uint16_t OPUSGetOutputSamps();
5476
uint32_t OPUSGetAudioDataStart();
5577
char* OPUSgetStreamTitle();
78+
uint16_t OPUSgetMode();
5679
vector<uint32_t> OPUSgetMetadataBlockPicture();
5780
int32_t OPUSFindSyncWord(unsigned char* buf, int32_t nBytes);
5881
int32_t OPUSparseOGG(uint8_t* inbuf, int32_t* bytesLeft);

0 commit comments

Comments
 (0)