Skip to content

Commit 063000b

Browse files
committed
new OpusDecodeFrame
1 parent dc9e0ce commit 063000b

File tree

3 files changed

+100
-41
lines changed

3 files changed

+100
-41
lines changed

src/opus_decoder/opus_decoder.cpp

Lines changed: 91 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ uint16_t *s_opusSegmentTable;
6767
uint8_t s_opusSegmentTableSize = 0;
6868
int16_t s_opusSegmentTableRdPtr = -1;
6969
int8_t s_opusError = 0;
70-
int8_t s_prev_mode = 0;
70+
int16_t s_prev_mode = 0;
7171
float s_opusCompressionRatio = 0;
7272

7373
std::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
//----------------------------------------------------------------------------------------------------------------------------------------------------
349350
int32_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
//----------------------------------------------------------------------------------------------------------------------------------------------------
405455
int8_t opus_FramePacking_Code0(uint8_t *inbuf, int32_t *bytesLeft, int16_t *outbuf, int32_t packetLen, uint16_t samplesPerFrame){

src/opus_decoder/silk.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,14 @@ bool SILKDecoder_AllocateBuffers(){
435435
return true;
436436
}
437437
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
438+
void SILKDecoder_ClearBuffers(){
439+
memset(s_resampler_state.get(), 0, sizeof(silk_resampler_state_struct_t) * DECODER_NUM_CHANNELS);
440+
memset(s_channel_state.get(), 0, sizeof(silk_decoder_state_t) * DECODER_NUM_CHANNELS);
441+
memset(s_silk_decoder.get(), 0, sizeof(silk_decoder_t));
442+
memset(s_silk_decoder_control.get(), 0, sizeof(silk_decoder_control_t));
443+
memset(s_silk_DecControlStruct.get(), 0, sizeof(silk_DecControlStruct_t));
444+
}
445+
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
438446
void SILKDecoder_FreeBuffers(){
439447
s_resampler_state.reset();
440448
s_channel_state.reset();

src/opus_decoder/silk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,7 @@ using silk_ptr_obj = std::unique_ptr<T, Silk_PsramDeleter>;
10411041
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
10421042

10431043
bool SILKDecoder_AllocateBuffers();
1044+
void SILKDecoder_ClearBuffers();
10441045
void SILKDecoder_FreeBuffers();
10451046
void silk_ana_filt_bank_1(const int16_t *in, int32_t *S, int16_t *outL, int16_t *outH, const int32_t N);
10461047
void silk_biquad_alt_stride1(const int16_t *in, const int32_t *B_Q28, const int32_t *A_Q28, int32_t *S,

0 commit comments

Comments
 (0)