33 * based on Xiph.Org Foundation celt decoder
44 *
55 * Created on: 26.01.2023
6- * Updated on: 14 .12.2024
6+ * Updated on: 18 .12.2024
77 */
88// ----------------------------------------------------------------------------------------------------------------------
99// O G G / O P U S I M P L.
@@ -331,49 +331,11 @@ int32_t opusDecodePage3(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLeng
331331// ----------------------------------------------------------------------------------------------------------------------------------------------------
332332int32_t opus_decode_frame (uint8_t *inbuf, int16_t *outbuf, int32_t packetLen, uint16_t samplesPerFrame) {
333333
334-
335-
336334 int32_t ret = 0 ;
337- int32_t silk_frame_size;
338-
339-
340- // celt_decoder_ctl(CELT_SET_START_BAND_REQUEST, endband);
341- if (s_mode == MODE_CELT_ONLY){
342- celt_decoder_ctl (CELT_SET_END_BAND_REQUEST, s_endband);
343- }
344-
345- if (s_mode == MODE_SILK_ONLY) {
346- uint16_t payloadSize_ms = max (10 , 1000 * samplesPerFrame / 48000 );
347- if (s_bandWidth == OPUS_BANDWIDTH_NARROWBAND) { s_internalSampleRate = 8000 ; }
348- else if (s_bandWidth == OPUS_BANDWIDTH_MEDIUMBAND) { s_internalSampleRate = 12000 ; }
349- else if (s_bandWidth == OPUS_BANDWIDTH_WIDEBAND) { s_internalSampleRate = 16000 ; }
350- else { s_internalSampleRate = 16000 ; }
351-
352- // log_w("samplesPerFrame %i", samplesPerFrame);
353- // int spf = opus_packet_get_samples_per_frame(inbuf, samplesPerFrame); // todo
354- // log_w("spf %i", packetLen);
355- ec_dec_init ((uint8_t *)inbuf, packetLen);
356- silk_InitDecoder ();
357- // log_w("payloadSize_ms %i, s_internalSampleRate %i", payloadSize_ms, s_internalSampleRate);
358- silk_setRawParams (1 , 2 , payloadSize_ms, s_internalSampleRate, 48000 );
359- int silk_ret = silk_Decode (0 , 1 , (int16_t *)outbuf, &silk_frame_size);
360-
361- if (silk_ret)log_w (" silk_ret %i" , silk_ret);
362-
363- // log_w("silk_frame_size %i", silk_frame_size);
364- if (samplesPerFrame != silk_frame_size)log_w (" samplesPerFrame %i silk_frame_size %i" ,samplesPerFrame ,silk_frame_size);
365- return silk_frame_size;
366-
367- }
368-
369- if (s_mode == MODE_HYBRID){
370- log_w (" Hybrid" );
371- }
335+ // int32_t silk_frame_size;
372336
373337 if (s_bandWidth) {
374- // log_e("");
375338 int endband = 21 ;
376-
377339 switch (s_bandWidth) {
378340 case OPUS_BANDWIDTH_NARROWBAND: endband = 13 ; break ;
379341 case OPUS_BANDWIDTH_MEDIUMBAND:
@@ -385,15 +347,41 @@ int32_t opus_decode_frame(uint8_t *inbuf, int16_t *outbuf, int32_t packetLen, ui
385347 celt_decoder_ctl (endband);
386348 }
387349
388-
389-
390-
391- if (s_mode == MODE_CELT_ONLY){
350+ if (s_mode == MODE_CELT_ONLY){
351+ celt_decoder_ctl (CELT_SET_END_BAND_REQUEST, s_endband);
392352 ec_dec_init ((uint8_t *)inbuf, packetLen);
393353 ret = celt_decode_with_ec ((int16_t *)outbuf, samplesPerFrame);
394354 }
395355
396- // log_w("ret %i", ret);
356+ if (s_mode == MODE_HYBRID){
357+ log_w (" Hybrid mode not yet supported" );
358+ ret = samplesPerFrame;
359+ }
360+
361+ if (s_mode == MODE_SILK_ONLY){
362+ log_w (" Silk mode not yet supported" );
363+ ret = samplesPerFrame;
364+ }
365+
366+ // if(s_mode == MODE_SILK_ONLY) {
367+ // uint16_t payloadSize_ms = max(10, 1000 * samplesPerFrame / 48000);
368+ // if(s_bandWidth == OPUS_BANDWIDTH_NARROWBAND) { s_internalSampleRate = 8000; }
369+ // else if(s_bandWidth == OPUS_BANDWIDTH_MEDIUMBAND) { s_internalSampleRate = 12000; }
370+ // else if(s_bandWidth == OPUS_BANDWIDTH_WIDEBAND) { s_internalSampleRate = 16000; }
371+ // else { s_internalSampleRate = 16000; }
372+ // //log_w("samplesPerFrame %i", samplesPerFrame);
373+ // // int spf = opus_packet_get_samples_per_frame(inbuf, samplesPerFrame); // todo
374+ // //log_w("spf %i", packetLen);
375+ // ec_dec_init((uint8_t *)inbuf, packetLen);
376+ // silk_InitDecoder();
377+ // //log_w("payloadSize_ms %i, s_internalSampleRate %i", payloadSize_ms, s_internalSampleRate);
378+ // silk_setRawParams(1, 2, payloadSize_ms, s_internalSampleRate, 48000);
379+ // int silk_ret = silk_Decode(0, 1, (int16_t*)outbuf, &silk_frame_size);
380+ // if(silk_ret)log_w("silk_ret %i", silk_ret);
381+ // //log_w("silk_frame_size %i", silk_frame_size);
382+ // if(samplesPerFrame != silk_frame_size)log_w("samplesPerFrame %i silk_frame_size %i",samplesPerFrame ,silk_frame_size);
383+ // return silk_frame_size;
384+ // }
397385 return ret;
398386}
399387// ----------------------------------------------------------------------------------------------------------------------------------------------------
@@ -450,8 +438,6 @@ int8_t opus_FramePacking_Code1(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outb
450438 | |
451439 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
452440*/
453-
454-
455441 int32_t ret = 0 ;
456442 static uint16_t c1fs = 0 ;
457443 if (*frameCount == 0 ){
@@ -460,12 +446,12 @@ int8_t opus_FramePacking_Code1(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outb
460446 *bytesLeft -= 1 ;
461447 s_opusCurrentFilePos += 1 ;
462448 c1fs = packetLen / 2 ;
463- // log_w("OPUS countCode 1 len %i, c1fs %i", len, c1fs);
449+ // log_w("OPUS countCode 1 len %i, c1fs %i", len, c1fs);
464450 *frameCount = 2 ;
465451 }
466452 if (*frameCount > 0 ){
467453 ret = opus_decode_frame (inbuf, outbuf, c1fs, samplesPerFrame);
468- log_w (" code 1, ret %i" , ret);
454+ // log_w("code 1, ret %i", ret);
469455 if (ret < 0 ){
470456 *frameCount = 0 ;
471457 return ret; // decode err
@@ -507,8 +493,6 @@ int8_t opus_FramePacking_Code2(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outb
507493 | |
508494 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
509495*/
510-
511- // log_w("OPUS countCode 2 packetLen %i", packetLen);
512496 int32_t ret = 0 ;
513497 static uint16_t firstFrameLength = 0 ;
514498 static uint16_t secondFrameLength = 0 ;
@@ -535,7 +519,7 @@ int8_t opus_FramePacking_Code2(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outb
535519 }
536520 if (*frameCount == 2 ){
537521 ret = opus_decode_frame (inbuf, outbuf, firstFrameLength, samplesPerFrame);
538- log_w (" code 2, ret %i" , ret);
522+ // log_w("code 2, ret %i", ret);
539523 if (ret < 0 ){
540524 *frameCount = 0 ;
541525 return ret; // decode err
@@ -546,7 +530,7 @@ log_w("code 2, ret %i", ret);
546530 }
547531 if (*frameCount == 1 ){
548532 ret = opus_decode_frame (inbuf, outbuf, secondFrameLength, samplesPerFrame);
549- log_w (" code 2, ret %i" , ret);
533+ // log_w("code 2, ret %i", ret);
550534 if (ret < 0 ){
551535 *frameCount = 0 ;
552536 return ret; // decode err
@@ -659,50 +643,77 @@ int8_t opus_FramePacking_Code3(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outb
659643 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
660644
661645*/
662- static uint16_t paddingBytes = 0 ;
663- static uint16_t fs = 0 ;
664- static uint8_t M = 0 ;
665- static bool v = false ;
666- static bool p = false ;
667- int32_t ret = 0 ;
668- uint8_t paddingLength = 0 ;
669- if (*frameCount == 0 ){
670- v = ((inbuf[ 1 ] & 0x80 ) == 0x80 ); // VBR indicator
671- p = ((inbuf[ 1 ] & 0x40 ) == 0x40 ); // padding bit
672- M = inbuf[ 1 ] & 0x3F ; // max framecount
673- if (v != 0 ) { log_e ( " OPUS countCode 3 with VBR not supported yet " ); vTaskDelay ( 1000 );} // todo
674- *bytesLeft -= 2 ;
675- packetLen -= 2 ;
676- inbuf += 2 ;
677- if (p) paddingLength = inbuf[ 0 ] ;
678- if (paddingLength == 255 ) {paddingLength += inbuf[ 3 ]; }
679- paddingLength ++ ;
680- *bytesLeft -= paddingLength;
681- packetLen -= paddingLength;
682- inbuf += paddingLength;
646+ static bool firstCall = true ;
647+ static bool v = false ; // VBR indicator
648+ static bool p = false ; // padding exists
649+ static int16_t fs = 0 ; // frame size
650+ static uint8_t M = 0 ; // nr of frames
651+ static int32_t spf = 0 ; // static samples per frame
652+ static int32_t paddingLength = 0 ;
653+ uint32_t idx = 0 ; // includes TOC byte
654+ int32_t ret = 0 ;
655+ int32_t remainingBytes = 0 ;
656+ uint16_t vfs[ 48 ] = { 0 }; // variable frame size
657+
658+ if (firstCall) {
659+ firstCall = false ;
660+ s_opusCurrentFilePos += packetLen ;
661+ paddingLength = 0 ;
662+ idx = 1 ; // skip TOC byte
663+ spf = samplesPerFrame ;
664+ if (inbuf[idx] & 0b10000000 ) v = true ; // VBR indicator
665+ if (inbuf[idx] & 0b01000000 ) p = true ; // padding bit
666+ M = inbuf[idx] & 0b00111111 ; // framecount
683667 *frameCount = M;
684- if (M == 0 ) return -1 ; // div0
685- log_i (" packetLen %i, M %i FS %i" , packetLen, M, packetLen / M);
686-
687- fs = (packetLen - paddingBytes) / *frameCount;
668+ idx++;
669+ if (p) {
670+ while (inbuf[idx] == 255 ) { paddingLength += 255 , idx++; }
671+ paddingLength += inbuf[idx];
672+ idx++;
673+ }
674+ if (v && M) { // variable frame size
675+ uint8_t m = 0 ;
676+ while (m < M) {
677+ vfs[m] = inbuf[idx];
678+ if (vfs[m] == 255 ) {vfs[m] = 255 ; idx++;}
679+ idx++;
680+ m++;
681+ // log_e("vfs[m] %i", vfs[m]);
682+ }
683+ }
684+ remainingBytes = packetLen - paddingLength - idx;
685+ if (remainingBytes < 0 ) {
686+ // log_e("fs %i", fs);
687+ *bytesLeft -= packetLen;
688+ *frameCount = 0 ;
689+ firstCall = true ;
690+ return ERR_OPUS_NONE;
691+ }
692+ if (!v){
693+ fs = remainingBytes / M;
694+ }
695+ if (fs > remainingBytes) {
696+ *bytesLeft -= packetLen;
697+ *frameCount = 0 ;
698+ firstCall = true ;
699+ return ERR_OPUS_NONE;
700+ }
701+ // log_w("remainingBytes %i, packetLen %i, paddingLength %i, idx %i, fs %i, frameCount %i", remainingBytes, packetLen, paddingLength, idx, fs, *frameCount);
702+ *bytesLeft -= idx;
688703 }
689- *bytesLeft -= fs;
690- s_opusCurrentFilePos += fs;
691- ret = opus_decode_frame (inbuf, outbuf, fs, samplesPerFrame);
692- // log_w("code 3, ret %i", ret);
693- if (ret < 0 ){
694- return ret; // decode error
704+ if (*frameCount > 0 ){
705+ if (v){ret = opus_decode_frame (inbuf + idx, outbuf, vfs[M - (*frameCount)], spf);}
706+ else { ret = opus_decode_frame (inbuf + idx, outbuf, fs, spf);}
707+ // log_w("code 3, ret %i", ret);
708+ *frameCount -= 1 ;
709+ *bytesLeft -= fs;
710+ s_opusValidSamples = ret;
711+ if (*frameCount > 0 ) return OPUS_CONTINUE;
695712 }
696- s_opusValidSamples = ret;
697- *frameCount -= 1 ;
698- if (*frameCount > 0 ) return OPUS_CONTINUE;
699- s_opusCountCode = 0 ;
700- *bytesLeft -= paddingBytes;
701- s_opusCurrentFilePos += paddingBytes;
702- paddingBytes = 0 ;
703- fs = 0 ;
704- v = false ;
705- p = false ;
713+ *bytesLeft -= paddingLength;
714+ *frameCount = 0 ;
715+ s_opusValidSamples = samplesPerFrame;
716+ firstCall = true ;
706717 return ERR_OPUS_NONE;
707718}
708719
@@ -804,8 +815,8 @@ int8_t parseOpusTOC(uint8_t TOC_Byte){ // https://www.rfc-editor.org/rfc/rfc671
804815 s_opusCountCode = c;
805816 s_f_opusStereoFlag = s;
806817
807- if (configNr < 12 ) return ERR_OPUS_SILK_MODE_UNSUPPORTED;
808- if (configNr < 16 ) return ERR_OPUS_HYBRID_MODE_UNSUPPORTED;
818+ // if(configNr < 12) return ERR_OPUS_SILK_MODE_UNSUPPORTED;
819+ // if(configNr < 16) return ERR_OPUS_HYBRID_MODE_UNSUPPORTED;
809820 // if(configNr < 20) return ERR_OPUS_NARROW_BAND_UNSUPPORTED;
810821 // if(configNr < 24) return ERR_OPUS_WIDE_BAND_UNSUPPORTED;
811822 // if(configNr < 28) return ERR_OPUS_SUPER_WIDE_BAND_UNSUPPORTED;
0 commit comments