@@ -67,7 +67,7 @@ uint16_t *s_opusSegmentTable;
6767uint8_t s_opusSegmentTableSize = 0 ;
6868int16_t s_opusSegmentTableRdPtr = -1 ;
6969int8_t s_opusError = 0 ;
70- int8_t s_prev_mode = 0 ;
70+ int16_t s_prev_mode = 0 ;
7171float s_opusCompressionRatio = 0 ;
7272
7373std::vector <uint32_t >s_opusBlockPicItem;
@@ -79,6 +79,7 @@ bool OPUSDecoder_AllocateBuffers(){
7979 s_opusSegmentTable = (uint16_t *)__malloc_heap_psram (256 * sizeof (uint16_t ));
8080 if (!s_opusSegmentTable) {log_e (" CELT not init" ); return false ;}
8181 CELTDecoder_ClearBuffer ();
82+ SILKDecoder_ClearBuffers ();
8283 OPUSDecoder_ClearBuffers ();
8384 // allocate CELT buffers after OPUS head (nr of channels is needed)
8485 s_opusError = celt_decoder_init (2 ); if (s_opusError < 0 ) {log_e (" CELT not init" ); return false ;}
@@ -152,7 +153,7 @@ void OPUSsetDefaults(){
152153 s_opusPageNr = 0 ;
153154 s_opusError = 0 ;
154155 s_endband = 0 ;
155- s_prev_mode = MODE_CELT_ONLY ;
156+ s_prev_mode = MODE_NONE ;
156157 s_opusBlockPicItem.clear (); s_opusBlockPicItem.shrink_to_fit ();
157158}
158159
@@ -347,59 +348,108 @@ int32_t opusDecodePage3(uint8_t* inbuf, int32_t* bytesLeft, uint32_t segmentLeng
347348}
348349// ----------------------------------------------------------------------------------------------------------------------------------------------------
349350int32_t opus_decode_frame (uint8_t *inbuf, int16_t *outbuf, int32_t packetLen, uint16_t samplesPerFrame) {
350-
351- int32_t ret = 0 ;
352- uint8_t payloadSize_ms = 0 ;
351+ if (!packetLen) {log_e (" packetLen = 0" ); return 0 ;}
352+ int i, silk_ret = 0 , celt_ret = 0 ;
353353 uint16_t audiosize = 960 ;
354- int32_t silk_frame_size;
354+ uint8_t payloadSize_ms = 20 ;
355+
356+ s_silk_DecControlStruct->nChannelsAPI = s_opusChannels;
357+ s_silk_DecControlStruct->nChannelsInternal = s_opusChannels;
358+ s_silk_DecControlStruct->API_sampleRate = 48000 ;
359+
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+ }
365+ if (s_prev_mode == MODE_NONE) celt_decoder_ctl ((int32_t )OPUS_RESET_STATE);
366+
367+ ec_dec_init (inbuf, packetLen);
368+
369+ /* Don't allocate any memory when in CELT-only mode */
370+ int pcm_silk_size = (s_mode != MODE_CELT_ONLY) ? samplesPerFrame * 4 : ALLOC_NONE;
371+ int16_t *pcm_silk = (int16_t *)ps_malloc (pcm_silk_size * sizeof (int16_t ));
372+ if (!pcm_silk)log_e (" oom" );
355373
356- if (s_mode == MODE_HYBRID || s_mode == MODE_SILK_ONLY){
374+ /* SILK processing */
375+ if (s_mode != MODE_CELT_ONLY) {
357376 int decoded_samples;
358- if (s_prev_mode == MODE_CELT_ONLY) silk_InitDecoder ();
359- payloadSize_ms = max (10 , 1000 * audiosize / 48000 ); /* The SILK PLC cannot produce frames of less than 10 ms */
360- s_silk_DecControlStruct->nChannelsAPI = 2 ;
361- s_silk_DecControlStruct->nChannelsInternal = 2 ;
362- s_silk_DecControlStruct->API_sampleRate = 48000 ;
363-
364- if (s_mode == MODE_SILK_ONLY) {
365- if (s_bandWidth == OPUS_BANDWIDTH_NARROWBAND) {
366- s_internalSampleRate = 8000 ;
367- } else if (s_bandWidth == OPUS_BANDWIDTH_MEDIUMBAND) {
368- s_internalSampleRate = 12000 ;
369- } else if (s_bandWidth == OPUS_BANDWIDTH_WIDEBAND) {
370- s_internalSampleRate = 16000 ;
371- } else {
377+ int16_t *pcm_ptr;
378+ pcm_ptr = pcm_silk;
379+
380+ if (s_prev_mode == MODE_CELT_ONLY || s_prev_mode == MODE_NONE) silk_InitDecoder ();
381+
382+ if (s_mode == MODE_SILK_ONLY) {
383+ if (s_bandWidth == OPUS_BANDWIDTH_NARROWBAND) {s_internalSampleRate = 8000 ;}
384+ else if (s_bandWidth == OPUS_BANDWIDTH_MEDIUMBAND) {s_internalSampleRate = 12000 ;}
385+ else if (s_bandWidth == OPUS_BANDWIDTH_WIDEBAND) {s_internalSampleRate = 16000 ;}
386+ else {s_internalSampleRate = 16000 ;}
387+ } else { /* Hybrid mode */
372388 s_internalSampleRate = 16000 ;
373389 }
374- } else { /* Hybrid mode */
375- s_internalSampleRate = 16000 ;
376- }
377- ec_dec_init ((uint8_t *)inbuf, packetLen);
390+
378391 decoded_samples = 0 ;
379392 silk_setRawParams (s_opusChannels, 2 , payloadSize_ms, s_internalSampleRate, 48000 );
380- do {
381- /* Call SILK decoder */
393+ do { /* Call SILK decoder */
382394 int first_frame = decoded_samples == 0 ;
383- int silk_ret = silk_Decode (0 , first_frame, (int16_t *)outbuf + decoded_samples, &silk_frame_size);
384- if (silk_ret)log_w (" silk_ret %i" , silk_ret);
385- decoded_samples += silk_frame_size;
386- } while (decoded_samples < samplesPerFrame);
395+ int32_t nSamplesOut;
396+ silk_ret = silk_Decode (0 , first_frame, pcm_ptr, &nSamplesOut);
397+ if (silk_ret) {
398+ if (pcm_silk){free (pcm_silk); pcm_silk = nullptr ;}
399+ return OPUS_INTERNAL_ERROR;
400+ }
401+ pcm_ptr += nSamplesOut * s_opusChannels;
402+ decoded_samples += nSamplesOut;
403+ } while (decoded_samples < audiosize);
404+ }
387405
388- ret = decoded_samples;
389- if (s_mode == MODE_SILK_ONLY) return ret;
406+ uint8_t start_band = 0 ;
407+ if (s_mode != MODE_CELT_ONLY && ec_tell () + 17 + 20 * (s_mode == MODE_HYBRID) <= 8 * packetLen) {
408+ /* Check if we have a redundant 0-8 kHz band */
409+ if (s_mode == MODE_HYBRID) ec_dec_bit_logp (12 );
410+ }
411+ if (s_mode != MODE_CELT_ONLY) start_band = 17 ;
412+
413+ if (s_bandWidth) {
414+ int endband = 21 ;
415+
416+ switch (s_bandWidth) {
417+ case OPUS_BANDWIDTH_NARROWBAND: endband = 13 ; break ;
418+ case OPUS_BANDWIDTH_MEDIUMBAND:
419+ case OPUS_BANDWIDTH_WIDEBAND: endband = 17 ; break ;
420+ case OPUS_BANDWIDTH_SUPERWIDEBAND:endband = 19 ; break ;
421+ case OPUS_BANDWIDTH_FULLBAND: endband = 21 ; break ;
422+ default : break ;
423+ }
424+ const uint32_t CELT_SET_CHANNELS_REQUEST = 10008 ;
425+ celt_decoder_ctl ((int32_t )CELT_SET_END_BAND_REQUEST,(endband));
426+ celt_decoder_ctl ((int32_t )CELT_SET_CHANNELS_REQUEST,(s_opusChannels));
390427 }
391428
392- if (s_mode == MODE_CELT_ONLY){
393- celt_decoder_ctl (CELT_SET_END_BAND_REQUEST, s_endband);
394- ec_dec_init ((uint8_t *)inbuf, packetLen);
395- ret = celt_decode_with_ec ((int16_t *)outbuf, samplesPerFrame);
429+ /* MUST be after PLC */
430+ celt_decoder_ctl ((int32_t )CELT_SET_START_BAND_REQUEST, start_band);
431+
432+ if (s_mode != MODE_SILK_ONLY) {
433+ /* Make sure to discard any previous CELT state */
434+ if (s_mode != s_prev_mode && s_prev_mode > 0 ) celt_decoder_ctl ((int32_t )OPUS_RESET_STATE);
435+ celt_ret = celt_decode_with_ec (outbuf, audiosize);
436+ } else {
437+ // unsigned char silence[2] = {0xFF, 0xFF};
438+ for (i = 0 ; i < audiosize * s_opusChannels; i++) outbuf[i] = 0 ;
439+ /* For hybrid -> SILK transitions, we let the CELT MDCT do a fade-out by decoding a silence frame */
440+ if (s_prev_mode == MODE_HYBRID) {
441+ celt_decoder_ctl ((int32_t )CELT_SET_START_BAND_REQUEST, 0 );
442+ celt_decode_with_ec (outbuf, 120 );
443+ }
396444 }
397445
398- if (s_mode == MODE_HYBRID){
399- log_w (" Hybrid mode mot supported yet" );
400- return packetLen;
446+ if (s_mode != MODE_CELT_ONLY) {
447+ for (i = 0 ; i < audiosize * s_opusChannels; i++) outbuf[i] = SAT16 (ADD32 (outbuf[i], pcm_silk[i]));
401448 }
402- return ret;
449+
450+ s_prev_mode = s_mode;
451+ if (pcm_silk){free (pcm_silk); pcm_silk = nullptr ;}
452+ return celt_ret < 0 ? celt_ret : audiosize;
403453}
404454// ----------------------------------------------------------------------------------------------------------------------------------------------------
405455int8_t opus_FramePacking_Code0 (uint8_t *inbuf, int32_t *bytesLeft, int16_t *outbuf, int32_t packetLen, uint16_t samplesPerFrame){
0 commit comments