33 * based on Xiph.Org Foundation celt decoder
44 *
55 * Created on: 26.01.2023
6- * Updated on: 07.04 .2023
6+ * Updated on: 23.12 .2023
77 */
88// ----------------------------------------------------------------------------------------------------------------------
99// O G G / O P U S I M P L.
@@ -16,7 +16,9 @@ bool s_f_opusSubsequentPage = false;
1616bool s_f_opusParseOgg = false ;
1717bool s_f_newSteamTitle = false ; // streamTitle
1818bool s_f_opusFramePacket = false ;
19+ bool s_f_opusStereoFlag = false ;
1920uint8_t s_opusChannels = 0 ;
21+ uint8_t s_opusCountCode = 0 ;
2022uint16_t s_opusSamplerate = 0 ;
2123uint32_t s_opusSegmentLength = 0 ;
2224char *s_opusChbuf = NULL ;
@@ -58,13 +60,15 @@ void OPUSsetDefaults(){
5860 s_f_opusParseOgg = false ;
5961 s_f_newSteamTitle = false ; // streamTitle
6062 s_f_opusFramePacket = false ;
63+ s_f_opusStereoFlag = false ;
6164 s_opusChannels = 0 ;
6265 s_opusSamplerate = 0 ;
6366 s_opusSegmentLength = 0 ;
6467 s_opusValidSamples = 0 ;
6568 s_opusSegmentTableSize = 0 ;
6669 s_opusOldMode = 0xFF ;
6770 s_opusSegmentTableRdPtr = -1 ;
71+ s_opusCountCode = 0 ;
6872
6973 s_opusError = 0 ;
7074}
@@ -73,38 +77,100 @@ void OPUSsetDefaults(){
7377
7478int OPUSDecode (uint8_t *inbuf, int *bytesLeft, short *outbuf){
7579
80+ static uint16_t fs = 0 ;
81+ static uint8_t M = 0 ;
82+ static uint16_t paddingBytes = 0 ;
83+ static uint16_t samplesPerFrame = 0 ;
84+ int ret = ERR_OPUS_NONE;
85+ int len = 0 ;
86+
7687 if (s_f_opusParseOgg){
77- int ret = OPUSparseOGG (inbuf, bytesLeft);
88+ fs = 0 ;
89+ M = 0 ;
90+ paddingBytes = 0 ;
91+ s_opusCountCode = 0 ;
92+ ret = OPUSparseOGG (inbuf, bytesLeft);
7893 if (ret == ERR_OPUS_NONE) return OPUS_PARSE_OGG_DONE; // ok
7994 else return ret; // error
8095 }
8196
97+ if (s_opusCountCode == 3 ) goto FramePacking;
98+
8299 if (s_f_opusFramePacket){
83100 if (s_opusSegmentTableSize > 0 ){
84101 s_opusSegmentTableRdPtr++;
85102 s_opusSegmentTableSize--;
86- int len = s_opusSegmentTable[s_opusSegmentTableRdPtr];
103+ len = s_opusSegmentTable[s_opusSegmentTableRdPtr];
104+ }
105+
106+ ret = parseOpusTOC (inbuf[0 ]);
107+ samplesPerFrame = opus_packet_get_samples_per_frame (inbuf, 48000 );
108+ if (ret < 0 ) goto exit; // error
109+
110+ FramePacking:
111+
112+ // https://www.tech-invite.com/y65/tinv-ietf-rfc-6716-2.html 3.2. Frame Packing
113+ if (s_opusCountCode == 0 ){ // Code 0: One Frame in the Packet
87114 *bytesLeft -= len;
88- int32_t ret = parseOpusTOC (inbuf[0 ]);
89- if (ret < 0 ) return ret;
90- int frame_size = opus_packet_get_samples_per_frame (inbuf, 48000 );
115+ ret = parseOpusTOC (inbuf[0 ]);
116+ if (ret < 0 ) goto exit; // error
91117 len--;
92118 inbuf++;
93-
94119 ec_dec_init ((uint8_t *)inbuf, len);
95- ret = celt_decode_with_ec (inbuf, len, (int16_t *)outbuf, frame_size );
96- if (ret < 0 ) return ret ; // celt error
120+ ret = celt_decode_with_ec (inbuf, len, (int16_t *)outbuf, samplesPerFrame );
121+ if (ret < 0 ) goto exit ; // celt error
97122 s_opusValidSamples = ret;
98-
99- if (s_opusSegmentTableSize== 0 ){
100- s_opusSegmentTableRdPtr = -1 ; // back to the parking position
101- s_f_opusFramePacket = false ;
102- s_f_opusParseOgg = true ;
123+ ret = ERR_OPUS_NONE;
124+ }
125+ if (s_opusCountCode == 1 ){ // Code 1: Two Frames in the Packet, Each with Equal Compressed Size
126+ log_e (" OPUS countCode 1 not supported yet" ); vTaskDelay (1000 ); // todo
127+ }
128+ if (s_opusCountCode == 2 ){ // Code 2: Two Frames in the Packet, with Different Compressed Sizes
129+ log_e (" OPUS countCode 2 not supported yet" ); vTaskDelay (1000 ); // todo
130+ }
131+ if (s_opusCountCode == 3 ){ // Code 3: A Signaled Number of Frames in the Packet
132+
133+ if (M == 0 ){
134+ bool v = ((inbuf[1 ] & 0x80 ) == 0x80 ); // VBR indicator
135+ (void )v;
136+ bool p = ((inbuf[1 ] & 0x40 ) == 0x40 ); // padding bit
137+ M = inbuf[1 ] & 0x3F ; // max framecount
138+ // log_i("v %i, p %i, M %i", v, p, M);
139+ paddingBytes = 0 ;
140+ if (p){
141+ int i = 0 ;
142+ while (inbuf[2 + i] == 255 ){
143+ paddingBytes += inbuf[2 + i];
144+ i++;
145+ }
146+ paddingBytes += inbuf[2 + i];
147+ fs = (len - 3 - i - paddingBytes) / M;
148+ *bytesLeft -= 3 + i;
149+ inbuf += 3 + i;
150+ }
103151 }
152+ *bytesLeft -= fs;
153+ ec_dec_init ((uint8_t *)inbuf, fs);
154+ ret = celt_decode_with_ec (inbuf, fs, (int16_t *)outbuf, samplesPerFrame);
155+ if (ret < 0 ) goto exit; // celt error
156+ s_opusValidSamples = ret;
157+ M--;
158+ // log_i("M %i fs %i spf %i", M, fs, samplesPerFrame);
159+ ret = ERR_OPUS_NONE;
160+ if (M == 0 ) {s_opusCountCode = 0 ; *bytesLeft -= paddingBytes; goto exit;}
161+ return ret;
104162 }
105163 }
106- return ERR_OPUS_NONE;
164+
165+ exit:
166+ if (s_opusSegmentTableSize== 0 ){
167+ s_opusSegmentTableRdPtr = -1 ; // back to the parking position
168+ s_f_opusFramePacket = false ;
169+ s_f_opusParseOgg = true ;
170+ }
171+ return ret;
107172}
173+
108174// ----------------------------------------------------------------------------------------------------------------------
109175
110176int32_t opus_packet_get_samples_per_frame (const uint8_t *data, int32_t Fs) {
@@ -155,8 +221,8 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716
155221
156222 uint8_t mode = 0 ;
157223 uint8_t configNr = 0 ;
158- uint8_t s = 0 ;
159- uint8_t c = 0 ; (void )c;
224+ uint8_t s = 0 ; // stereo flag
225+ uint8_t c = 0 ; (void )c; // count code
160226
161227 configNr = (TOC_Byte & 0b11111000 ) >> 3 ;
162228 s = (TOC_Byte & 0b00000100 ) >> 2 ;
@@ -184,18 +250,13 @@ int parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc6716
184250 c = 2: 2 frames in the packet, with different compressed sizes
185251 c = 3: an arbitrary number of frames in the packet
186252 */
187-
188- // log_i("configNr %i, s %i, c %i", configNr, s, c);
189-
190- if (c == 3 ) { // todo https://www.rfc-editor.org/rfc/rfc6716#page-16 3.2.3. at page 17
191- log_e (" an arbitrary number of frames in the packet is unsupported yet" );
192- vTaskDelay (1000 );
193- }
253+ s_opusCountCode = c;
254+ s_f_opusStereoFlag = s;
194255
195256 if (configNr < 12 ) return ERR_OPUS_SILK_MODE_UNSUPPORTED;
196257 if (configNr < 16 ) return ERR_OPUS_HYBRID_MODE_UNSUPPORTED;
197258
198- return s ;
259+ return configNr ;
199260}
200261// ----------------------------------------------------------------------------------------------------------------------
201262int parseOpusComment (uint8_t *inbuf, int nBytes){ // reference https://exiftool.org/TagNames/Vorbis.html#Comments
0 commit comments