1*a58d3d2aSXin Li /* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited
2*a58d3d2aSXin Li Written by Jean-Marc Valin and Koen Vos */
3*a58d3d2aSXin Li /*
4*a58d3d2aSXin Li Redistribution and use in source and binary forms, with or without
5*a58d3d2aSXin Li modification, are permitted provided that the following conditions
6*a58d3d2aSXin Li are met:
7*a58d3d2aSXin Li
8*a58d3d2aSXin Li - Redistributions of source code must retain the above copyright
9*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer.
10*a58d3d2aSXin Li
11*a58d3d2aSXin Li - Redistributions in binary form must reproduce the above copyright
12*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer in the
13*a58d3d2aSXin Li documentation and/or other materials provided with the distribution.
14*a58d3d2aSXin Li
15*a58d3d2aSXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16*a58d3d2aSXin Li ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17*a58d3d2aSXin Li LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18*a58d3d2aSXin Li A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19*a58d3d2aSXin Li OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20*a58d3d2aSXin Li EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21*a58d3d2aSXin Li PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22*a58d3d2aSXin Li PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23*a58d3d2aSXin Li LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24*a58d3d2aSXin Li NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25*a58d3d2aSXin Li SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*a58d3d2aSXin Li */
27*a58d3d2aSXin Li
28*a58d3d2aSXin Li #ifdef HAVE_CONFIG_H
29*a58d3d2aSXin Li # include "config.h"
30*a58d3d2aSXin Li #endif
31*a58d3d2aSXin Li
32*a58d3d2aSXin Li #ifndef OPUS_BUILD
33*a58d3d2aSXin Li # error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you need other defines as well, as in a config.h. See the included build files for details."
34*a58d3d2aSXin Li #endif
35*a58d3d2aSXin Li
36*a58d3d2aSXin Li #if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) && !defined(OPUS_WILL_BE_SLOW)
37*a58d3d2aSXin Li # pragma message "You appear to be compiling without optimization, if so opus will be very slow."
38*a58d3d2aSXin Li #endif
39*a58d3d2aSXin Li
40*a58d3d2aSXin Li #include <stdarg.h>
41*a58d3d2aSXin Li #include "celt.h"
42*a58d3d2aSXin Li #include "opus.h"
43*a58d3d2aSXin Li #include "entdec.h"
44*a58d3d2aSXin Li #include "modes.h"
45*a58d3d2aSXin Li #include "API.h"
46*a58d3d2aSXin Li #include "stack_alloc.h"
47*a58d3d2aSXin Li #include "float_cast.h"
48*a58d3d2aSXin Li #include "opus_private.h"
49*a58d3d2aSXin Li #include "os_support.h"
50*a58d3d2aSXin Li #include "structs.h"
51*a58d3d2aSXin Li #include "define.h"
52*a58d3d2aSXin Li #include "mathops.h"
53*a58d3d2aSXin Li #include "cpu_support.h"
54*a58d3d2aSXin Li
55*a58d3d2aSXin Li #ifdef ENABLE_DEEP_PLC
56*a58d3d2aSXin Li #include "dred_rdovae_dec_data.h"
57*a58d3d2aSXin Li #include "dred_rdovae_dec.h"
58*a58d3d2aSXin Li #endif
59*a58d3d2aSXin Li
60*a58d3d2aSXin Li #ifdef ENABLE_OSCE
61*a58d3d2aSXin Li #include "osce.h"
62*a58d3d2aSXin Li #endif
63*a58d3d2aSXin Li
64*a58d3d2aSXin Li struct OpusDecoder {
65*a58d3d2aSXin Li int celt_dec_offset;
66*a58d3d2aSXin Li int silk_dec_offset;
67*a58d3d2aSXin Li int channels;
68*a58d3d2aSXin Li opus_int32 Fs; /** Sampling rate (at the API level) */
69*a58d3d2aSXin Li silk_DecControlStruct DecControl;
70*a58d3d2aSXin Li int decode_gain;
71*a58d3d2aSXin Li int complexity;
72*a58d3d2aSXin Li int arch;
73*a58d3d2aSXin Li #ifdef ENABLE_DEEP_PLC
74*a58d3d2aSXin Li LPCNetPLCState lpcnet;
75*a58d3d2aSXin Li #endif
76*a58d3d2aSXin Li
77*a58d3d2aSXin Li /* Everything beyond this point gets cleared on a reset */
78*a58d3d2aSXin Li #define OPUS_DECODER_RESET_START stream_channels
79*a58d3d2aSXin Li int stream_channels;
80*a58d3d2aSXin Li
81*a58d3d2aSXin Li int bandwidth;
82*a58d3d2aSXin Li int mode;
83*a58d3d2aSXin Li int prev_mode;
84*a58d3d2aSXin Li int frame_size;
85*a58d3d2aSXin Li int prev_redundancy;
86*a58d3d2aSXin Li int last_packet_duration;
87*a58d3d2aSXin Li #ifndef FIXED_POINT
88*a58d3d2aSXin Li opus_val16 softclip_mem[2];
89*a58d3d2aSXin Li #endif
90*a58d3d2aSXin Li
91*a58d3d2aSXin Li opus_uint32 rangeFinal;
92*a58d3d2aSXin Li };
93*a58d3d2aSXin Li
94*a58d3d2aSXin Li #if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
validate_opus_decoder(OpusDecoder * st)95*a58d3d2aSXin Li static void validate_opus_decoder(OpusDecoder *st)
96*a58d3d2aSXin Li {
97*a58d3d2aSXin Li celt_assert(st->channels == 1 || st->channels == 2);
98*a58d3d2aSXin Li celt_assert(st->Fs == 48000 || st->Fs == 24000 || st->Fs == 16000 || st->Fs == 12000 || st->Fs == 8000);
99*a58d3d2aSXin Li celt_assert(st->DecControl.API_sampleRate == st->Fs);
100*a58d3d2aSXin Li celt_assert(st->DecControl.internalSampleRate == 0 || st->DecControl.internalSampleRate == 16000 || st->DecControl.internalSampleRate == 12000 || st->DecControl.internalSampleRate == 8000);
101*a58d3d2aSXin Li celt_assert(st->DecControl.nChannelsAPI == st->channels);
102*a58d3d2aSXin Li celt_assert(st->DecControl.nChannelsInternal == 0 || st->DecControl.nChannelsInternal == 1 || st->DecControl.nChannelsInternal == 2);
103*a58d3d2aSXin Li celt_assert(st->DecControl.payloadSize_ms == 0 || st->DecControl.payloadSize_ms == 10 || st->DecControl.payloadSize_ms == 20 || st->DecControl.payloadSize_ms == 40 || st->DecControl.payloadSize_ms == 60);
104*a58d3d2aSXin Li #ifdef OPUS_ARCHMASK
105*a58d3d2aSXin Li celt_assert(st->arch >= 0);
106*a58d3d2aSXin Li celt_assert(st->arch <= OPUS_ARCHMASK);
107*a58d3d2aSXin Li #endif
108*a58d3d2aSXin Li celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
109*a58d3d2aSXin Li }
110*a58d3d2aSXin Li #define VALIDATE_OPUS_DECODER(st) validate_opus_decoder(st)
111*a58d3d2aSXin Li #else
112*a58d3d2aSXin Li #define VALIDATE_OPUS_DECODER(st)
113*a58d3d2aSXin Li #endif
114*a58d3d2aSXin Li
opus_decoder_get_size(int channels)115*a58d3d2aSXin Li int opus_decoder_get_size(int channels)
116*a58d3d2aSXin Li {
117*a58d3d2aSXin Li int silkDecSizeBytes, celtDecSizeBytes;
118*a58d3d2aSXin Li int ret;
119*a58d3d2aSXin Li if (channels<1 || channels > 2)
120*a58d3d2aSXin Li return 0;
121*a58d3d2aSXin Li ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
122*a58d3d2aSXin Li if(ret)
123*a58d3d2aSXin Li return 0;
124*a58d3d2aSXin Li silkDecSizeBytes = align(silkDecSizeBytes);
125*a58d3d2aSXin Li celtDecSizeBytes = celt_decoder_get_size(channels);
126*a58d3d2aSXin Li return align(sizeof(OpusDecoder))+silkDecSizeBytes+celtDecSizeBytes;
127*a58d3d2aSXin Li }
128*a58d3d2aSXin Li
opus_decoder_init(OpusDecoder * st,opus_int32 Fs,int channels)129*a58d3d2aSXin Li int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
130*a58d3d2aSXin Li {
131*a58d3d2aSXin Li void *silk_dec;
132*a58d3d2aSXin Li CELTDecoder *celt_dec;
133*a58d3d2aSXin Li int ret, silkDecSizeBytes;
134*a58d3d2aSXin Li
135*a58d3d2aSXin Li if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
136*a58d3d2aSXin Li || (channels!=1&&channels!=2))
137*a58d3d2aSXin Li return OPUS_BAD_ARG;
138*a58d3d2aSXin Li
139*a58d3d2aSXin Li OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
140*a58d3d2aSXin Li /* Initialize SILK decoder */
141*a58d3d2aSXin Li ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
142*a58d3d2aSXin Li if (ret)
143*a58d3d2aSXin Li return OPUS_INTERNAL_ERROR;
144*a58d3d2aSXin Li
145*a58d3d2aSXin Li silkDecSizeBytes = align(silkDecSizeBytes);
146*a58d3d2aSXin Li st->silk_dec_offset = align(sizeof(OpusDecoder));
147*a58d3d2aSXin Li st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes;
148*a58d3d2aSXin Li silk_dec = (char*)st+st->silk_dec_offset;
149*a58d3d2aSXin Li celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
150*a58d3d2aSXin Li st->stream_channels = st->channels = channels;
151*a58d3d2aSXin Li st->complexity = 0;
152*a58d3d2aSXin Li
153*a58d3d2aSXin Li st->Fs = Fs;
154*a58d3d2aSXin Li st->DecControl.API_sampleRate = st->Fs;
155*a58d3d2aSXin Li st->DecControl.nChannelsAPI = st->channels;
156*a58d3d2aSXin Li
157*a58d3d2aSXin Li /* Reset decoder */
158*a58d3d2aSXin Li ret = silk_InitDecoder( silk_dec );
159*a58d3d2aSXin Li if(ret)return OPUS_INTERNAL_ERROR;
160*a58d3d2aSXin Li
161*a58d3d2aSXin Li /* Initialize CELT decoder */
162*a58d3d2aSXin Li ret = celt_decoder_init(celt_dec, Fs, channels);
163*a58d3d2aSXin Li if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR;
164*a58d3d2aSXin Li
165*a58d3d2aSXin Li celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));
166*a58d3d2aSXin Li
167*a58d3d2aSXin Li st->prev_mode = 0;
168*a58d3d2aSXin Li st->frame_size = Fs/400;
169*a58d3d2aSXin Li #ifdef ENABLE_DEEP_PLC
170*a58d3d2aSXin Li lpcnet_plc_init( &st->lpcnet);
171*a58d3d2aSXin Li #endif
172*a58d3d2aSXin Li st->arch = opus_select_arch();
173*a58d3d2aSXin Li return OPUS_OK;
174*a58d3d2aSXin Li }
175*a58d3d2aSXin Li
opus_decoder_create(opus_int32 Fs,int channels,int * error)176*a58d3d2aSXin Li OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
177*a58d3d2aSXin Li {
178*a58d3d2aSXin Li int ret;
179*a58d3d2aSXin Li OpusDecoder *st;
180*a58d3d2aSXin Li if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
181*a58d3d2aSXin Li || (channels!=1&&channels!=2))
182*a58d3d2aSXin Li {
183*a58d3d2aSXin Li if (error)
184*a58d3d2aSXin Li *error = OPUS_BAD_ARG;
185*a58d3d2aSXin Li return NULL;
186*a58d3d2aSXin Li }
187*a58d3d2aSXin Li st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
188*a58d3d2aSXin Li if (st == NULL)
189*a58d3d2aSXin Li {
190*a58d3d2aSXin Li if (error)
191*a58d3d2aSXin Li *error = OPUS_ALLOC_FAIL;
192*a58d3d2aSXin Li return NULL;
193*a58d3d2aSXin Li }
194*a58d3d2aSXin Li ret = opus_decoder_init(st, Fs, channels);
195*a58d3d2aSXin Li if (error)
196*a58d3d2aSXin Li *error = ret;
197*a58d3d2aSXin Li if (ret != OPUS_OK)
198*a58d3d2aSXin Li {
199*a58d3d2aSXin Li opus_free(st);
200*a58d3d2aSXin Li st = NULL;
201*a58d3d2aSXin Li }
202*a58d3d2aSXin Li return st;
203*a58d3d2aSXin Li }
204*a58d3d2aSXin Li
smooth_fade(const opus_val16 * in1,const opus_val16 * in2,opus_val16 * out,int overlap,int channels,const opus_val16 * window,opus_int32 Fs)205*a58d3d2aSXin Li static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2,
206*a58d3d2aSXin Li opus_val16 *out, int overlap, int channels,
207*a58d3d2aSXin Li const opus_val16 *window, opus_int32 Fs)
208*a58d3d2aSXin Li {
209*a58d3d2aSXin Li int i, c;
210*a58d3d2aSXin Li int inc = 48000/Fs;
211*a58d3d2aSXin Li for (c=0;c<channels;c++)
212*a58d3d2aSXin Li {
213*a58d3d2aSXin Li for (i=0;i<overlap;i++)
214*a58d3d2aSXin Li {
215*a58d3d2aSXin Li opus_val16 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
216*a58d3d2aSXin Li out[i*channels+c] = SHR32(MAC16_16(MULT16_16(w,in2[i*channels+c]),
217*a58d3d2aSXin Li Q15ONE-w, in1[i*channels+c]), 15);
218*a58d3d2aSXin Li }
219*a58d3d2aSXin Li }
220*a58d3d2aSXin Li }
221*a58d3d2aSXin Li
opus_packet_get_mode(const unsigned char * data)222*a58d3d2aSXin Li static int opus_packet_get_mode(const unsigned char *data)
223*a58d3d2aSXin Li {
224*a58d3d2aSXin Li int mode;
225*a58d3d2aSXin Li if (data[0]&0x80)
226*a58d3d2aSXin Li {
227*a58d3d2aSXin Li mode = MODE_CELT_ONLY;
228*a58d3d2aSXin Li } else if ((data[0]&0x60) == 0x60)
229*a58d3d2aSXin Li {
230*a58d3d2aSXin Li mode = MODE_HYBRID;
231*a58d3d2aSXin Li } else {
232*a58d3d2aSXin Li mode = MODE_SILK_ONLY;
233*a58d3d2aSXin Li }
234*a58d3d2aSXin Li return mode;
235*a58d3d2aSXin Li }
236*a58d3d2aSXin Li
opus_decode_frame(OpusDecoder * st,const unsigned char * data,opus_int32 len,opus_val16 * pcm,int frame_size,int decode_fec)237*a58d3d2aSXin Li static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
238*a58d3d2aSXin Li opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
239*a58d3d2aSXin Li {
240*a58d3d2aSXin Li void *silk_dec;
241*a58d3d2aSXin Li CELTDecoder *celt_dec;
242*a58d3d2aSXin Li int i, silk_ret=0, celt_ret=0;
243*a58d3d2aSXin Li ec_dec dec;
244*a58d3d2aSXin Li opus_int32 silk_frame_size;
245*a58d3d2aSXin Li int pcm_silk_size;
246*a58d3d2aSXin Li VARDECL(opus_int16, pcm_silk);
247*a58d3d2aSXin Li int pcm_transition_silk_size;
248*a58d3d2aSXin Li VARDECL(opus_val16, pcm_transition_silk);
249*a58d3d2aSXin Li int pcm_transition_celt_size;
250*a58d3d2aSXin Li VARDECL(opus_val16, pcm_transition_celt);
251*a58d3d2aSXin Li opus_val16 *pcm_transition=NULL;
252*a58d3d2aSXin Li int redundant_audio_size;
253*a58d3d2aSXin Li VARDECL(opus_val16, redundant_audio);
254*a58d3d2aSXin Li
255*a58d3d2aSXin Li int audiosize;
256*a58d3d2aSXin Li int mode;
257*a58d3d2aSXin Li int bandwidth;
258*a58d3d2aSXin Li int transition=0;
259*a58d3d2aSXin Li int start_band;
260*a58d3d2aSXin Li int redundancy=0;
261*a58d3d2aSXin Li int redundancy_bytes = 0;
262*a58d3d2aSXin Li int celt_to_silk=0;
263*a58d3d2aSXin Li int c;
264*a58d3d2aSXin Li int F2_5, F5, F10, F20;
265*a58d3d2aSXin Li const opus_val16 *window;
266*a58d3d2aSXin Li opus_uint32 redundant_rng = 0;
267*a58d3d2aSXin Li int celt_accum;
268*a58d3d2aSXin Li ALLOC_STACK;
269*a58d3d2aSXin Li
270*a58d3d2aSXin Li silk_dec = (char*)st+st->silk_dec_offset;
271*a58d3d2aSXin Li celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
272*a58d3d2aSXin Li F20 = st->Fs/50;
273*a58d3d2aSXin Li F10 = F20>>1;
274*a58d3d2aSXin Li F5 = F10>>1;
275*a58d3d2aSXin Li F2_5 = F5>>1;
276*a58d3d2aSXin Li if (frame_size < F2_5)
277*a58d3d2aSXin Li {
278*a58d3d2aSXin Li RESTORE_STACK;
279*a58d3d2aSXin Li return OPUS_BUFFER_TOO_SMALL;
280*a58d3d2aSXin Li }
281*a58d3d2aSXin Li /* Limit frame_size to avoid excessive stack allocations. */
282*a58d3d2aSXin Li frame_size = IMIN(frame_size, st->Fs/25*3);
283*a58d3d2aSXin Li /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */
284*a58d3d2aSXin Li if (len<=1)
285*a58d3d2aSXin Li {
286*a58d3d2aSXin Li data = NULL;
287*a58d3d2aSXin Li /* In that case, don't conceal more than what the ToC says */
288*a58d3d2aSXin Li frame_size = IMIN(frame_size, st->frame_size);
289*a58d3d2aSXin Li }
290*a58d3d2aSXin Li if (data != NULL)
291*a58d3d2aSXin Li {
292*a58d3d2aSXin Li audiosize = st->frame_size;
293*a58d3d2aSXin Li mode = st->mode;
294*a58d3d2aSXin Li bandwidth = st->bandwidth;
295*a58d3d2aSXin Li ec_dec_init(&dec,(unsigned char*)data,len);
296*a58d3d2aSXin Li } else {
297*a58d3d2aSXin Li audiosize = frame_size;
298*a58d3d2aSXin Li /* Run PLC using last used mode (CELT if we ended with CELT redundancy) */
299*a58d3d2aSXin Li mode = st->prev_redundancy ? MODE_CELT_ONLY : st->prev_mode;
300*a58d3d2aSXin Li bandwidth = 0;
301*a58d3d2aSXin Li
302*a58d3d2aSXin Li if (mode == 0)
303*a58d3d2aSXin Li {
304*a58d3d2aSXin Li /* If we haven't got any packet yet, all we can do is return zeros */
305*a58d3d2aSXin Li for (i=0;i<audiosize*st->channels;i++)
306*a58d3d2aSXin Li pcm[i] = 0;
307*a58d3d2aSXin Li RESTORE_STACK;
308*a58d3d2aSXin Li return audiosize;
309*a58d3d2aSXin Li }
310*a58d3d2aSXin Li
311*a58d3d2aSXin Li /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT),
312*a58d3d2aSXin Li 10, or 20 (e.g. 12.5 or 30 ms). */
313*a58d3d2aSXin Li if (audiosize > F20)
314*a58d3d2aSXin Li {
315*a58d3d2aSXin Li do {
316*a58d3d2aSXin Li int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0);
317*a58d3d2aSXin Li if (ret<0)
318*a58d3d2aSXin Li {
319*a58d3d2aSXin Li RESTORE_STACK;
320*a58d3d2aSXin Li return ret;
321*a58d3d2aSXin Li }
322*a58d3d2aSXin Li pcm += ret*st->channels;
323*a58d3d2aSXin Li audiosize -= ret;
324*a58d3d2aSXin Li } while (audiosize > 0);
325*a58d3d2aSXin Li RESTORE_STACK;
326*a58d3d2aSXin Li return frame_size;
327*a58d3d2aSXin Li } else if (audiosize < F20)
328*a58d3d2aSXin Li {
329*a58d3d2aSXin Li if (audiosize > F10)
330*a58d3d2aSXin Li audiosize = F10;
331*a58d3d2aSXin Li else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10)
332*a58d3d2aSXin Li audiosize = F5;
333*a58d3d2aSXin Li }
334*a58d3d2aSXin Li }
335*a58d3d2aSXin Li
336*a58d3d2aSXin Li /* In fixed-point, we can tell CELT to do the accumulation on top of the
337*a58d3d2aSXin Li SILK PCM buffer. This saves some stack space. */
338*a58d3d2aSXin Li #ifdef FIXED_POINT
339*a58d3d2aSXin Li celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10);
340*a58d3d2aSXin Li #else
341*a58d3d2aSXin Li celt_accum = 0;
342*a58d3d2aSXin Li #endif
343*a58d3d2aSXin Li
344*a58d3d2aSXin Li pcm_transition_silk_size = ALLOC_NONE;
345*a58d3d2aSXin Li pcm_transition_celt_size = ALLOC_NONE;
346*a58d3d2aSXin Li if (data!=NULL && st->prev_mode > 0 && (
347*a58d3d2aSXin Li (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy)
348*a58d3d2aSXin Li || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
349*a58d3d2aSXin Li )
350*a58d3d2aSXin Li {
351*a58d3d2aSXin Li transition = 1;
352*a58d3d2aSXin Li /* Decide where to allocate the stack memory for pcm_transition */
353*a58d3d2aSXin Li if (mode == MODE_CELT_ONLY)
354*a58d3d2aSXin Li pcm_transition_celt_size = F5*st->channels;
355*a58d3d2aSXin Li else
356*a58d3d2aSXin Li pcm_transition_silk_size = F5*st->channels;
357*a58d3d2aSXin Li }
358*a58d3d2aSXin Li ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16);
359*a58d3d2aSXin Li if (transition && mode == MODE_CELT_ONLY)
360*a58d3d2aSXin Li {
361*a58d3d2aSXin Li pcm_transition = pcm_transition_celt;
362*a58d3d2aSXin Li opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
363*a58d3d2aSXin Li }
364*a58d3d2aSXin Li if (audiosize > frame_size)
365*a58d3d2aSXin Li {
366*a58d3d2aSXin Li /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/
367*a58d3d2aSXin Li RESTORE_STACK;
368*a58d3d2aSXin Li return OPUS_BAD_ARG;
369*a58d3d2aSXin Li } else {
370*a58d3d2aSXin Li frame_size = audiosize;
371*a58d3d2aSXin Li }
372*a58d3d2aSXin Li
373*a58d3d2aSXin Li /* Don't allocate any memory when in CELT-only mode */
374*a58d3d2aSXin Li pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE;
375*a58d3d2aSXin Li ALLOC(pcm_silk, pcm_silk_size, opus_int16);
376*a58d3d2aSXin Li
377*a58d3d2aSXin Li /* SILK processing */
378*a58d3d2aSXin Li if (mode != MODE_CELT_ONLY)
379*a58d3d2aSXin Li {
380*a58d3d2aSXin Li int lost_flag, decoded_samples;
381*a58d3d2aSXin Li opus_int16 *pcm_ptr;
382*a58d3d2aSXin Li #ifdef FIXED_POINT
383*a58d3d2aSXin Li if (celt_accum)
384*a58d3d2aSXin Li pcm_ptr = pcm;
385*a58d3d2aSXin Li else
386*a58d3d2aSXin Li #endif
387*a58d3d2aSXin Li pcm_ptr = pcm_silk;
388*a58d3d2aSXin Li
389*a58d3d2aSXin Li if (st->prev_mode==MODE_CELT_ONLY)
390*a58d3d2aSXin Li silk_ResetDecoder( silk_dec );
391*a58d3d2aSXin Li
392*a58d3d2aSXin Li /* The SILK PLC cannot produce frames of less than 10 ms */
393*a58d3d2aSXin Li st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs);
394*a58d3d2aSXin Li
395*a58d3d2aSXin Li if (data != NULL)
396*a58d3d2aSXin Li {
397*a58d3d2aSXin Li st->DecControl.nChannelsInternal = st->stream_channels;
398*a58d3d2aSXin Li if( mode == MODE_SILK_ONLY ) {
399*a58d3d2aSXin Li if( bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
400*a58d3d2aSXin Li st->DecControl.internalSampleRate = 8000;
401*a58d3d2aSXin Li } else if( bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
402*a58d3d2aSXin Li st->DecControl.internalSampleRate = 12000;
403*a58d3d2aSXin Li } else if( bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
404*a58d3d2aSXin Li st->DecControl.internalSampleRate = 16000;
405*a58d3d2aSXin Li } else {
406*a58d3d2aSXin Li st->DecControl.internalSampleRate = 16000;
407*a58d3d2aSXin Li celt_assert( 0 );
408*a58d3d2aSXin Li }
409*a58d3d2aSXin Li } else {
410*a58d3d2aSXin Li /* Hybrid mode */
411*a58d3d2aSXin Li st->DecControl.internalSampleRate = 16000;
412*a58d3d2aSXin Li }
413*a58d3d2aSXin Li }
414*a58d3d2aSXin Li st->DecControl.enable_deep_plc = st->complexity >= 5;
415*a58d3d2aSXin Li #ifdef ENABLE_OSCE
416*a58d3d2aSXin Li st->DecControl.osce_method = OSCE_METHOD_NONE;
417*a58d3d2aSXin Li #ifndef DISABLE_LACE
418*a58d3d2aSXin Li if (st->complexity >= 6) {st->DecControl.osce_method = OSCE_METHOD_LACE;}
419*a58d3d2aSXin Li #endif
420*a58d3d2aSXin Li #ifndef DISABLE_NOLACE
421*a58d3d2aSXin Li if (st->complexity >= 7) {st->DecControl.osce_method = OSCE_METHOD_NOLACE;}
422*a58d3d2aSXin Li #endif
423*a58d3d2aSXin Li #endif
424*a58d3d2aSXin Li
425*a58d3d2aSXin Li lost_flag = data == NULL ? 1 : 2 * !!decode_fec;
426*a58d3d2aSXin Li decoded_samples = 0;
427*a58d3d2aSXin Li do {
428*a58d3d2aSXin Li /* Call SILK decoder */
429*a58d3d2aSXin Li int first_frame = decoded_samples == 0;
430*a58d3d2aSXin Li silk_ret = silk_Decode( silk_dec, &st->DecControl,
431*a58d3d2aSXin Li lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size,
432*a58d3d2aSXin Li #ifdef ENABLE_DEEP_PLC
433*a58d3d2aSXin Li &st->lpcnet,
434*a58d3d2aSXin Li #endif
435*a58d3d2aSXin Li st->arch );
436*a58d3d2aSXin Li if( silk_ret ) {
437*a58d3d2aSXin Li if (lost_flag) {
438*a58d3d2aSXin Li /* PLC failure should not be fatal */
439*a58d3d2aSXin Li silk_frame_size = frame_size;
440*a58d3d2aSXin Li for (i=0;i<frame_size*st->channels;i++)
441*a58d3d2aSXin Li pcm_ptr[i] = 0;
442*a58d3d2aSXin Li } else {
443*a58d3d2aSXin Li RESTORE_STACK;
444*a58d3d2aSXin Li return OPUS_INTERNAL_ERROR;
445*a58d3d2aSXin Li }
446*a58d3d2aSXin Li }
447*a58d3d2aSXin Li pcm_ptr += silk_frame_size * st->channels;
448*a58d3d2aSXin Li decoded_samples += silk_frame_size;
449*a58d3d2aSXin Li } while( decoded_samples < frame_size );
450*a58d3d2aSXin Li }
451*a58d3d2aSXin Li
452*a58d3d2aSXin Li start_band = 0;
453*a58d3d2aSXin Li if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL
454*a58d3d2aSXin Li && ec_tell(&dec)+17+20*(mode == MODE_HYBRID) <= 8*len)
455*a58d3d2aSXin Li {
456*a58d3d2aSXin Li /* Check if we have a redundant 0-8 kHz band */
457*a58d3d2aSXin Li if (mode == MODE_HYBRID)
458*a58d3d2aSXin Li redundancy = ec_dec_bit_logp(&dec, 12);
459*a58d3d2aSXin Li else
460*a58d3d2aSXin Li redundancy = 1;
461*a58d3d2aSXin Li if (redundancy)
462*a58d3d2aSXin Li {
463*a58d3d2aSXin Li celt_to_silk = ec_dec_bit_logp(&dec, 1);
464*a58d3d2aSXin Li /* redundancy_bytes will be at least two, in the non-hybrid
465*a58d3d2aSXin Li case due to the ec_tell() check above */
466*a58d3d2aSXin Li redundancy_bytes = mode==MODE_HYBRID ?
467*a58d3d2aSXin Li (opus_int32)ec_dec_uint(&dec, 256)+2 :
468*a58d3d2aSXin Li len-((ec_tell(&dec)+7)>>3);
469*a58d3d2aSXin Li len -= redundancy_bytes;
470*a58d3d2aSXin Li /* This is a sanity check. It should never happen for a valid
471*a58d3d2aSXin Li packet, so the exact behaviour is not normative. */
472*a58d3d2aSXin Li if (len*8 < ec_tell(&dec))
473*a58d3d2aSXin Li {
474*a58d3d2aSXin Li len = 0;
475*a58d3d2aSXin Li redundancy_bytes = 0;
476*a58d3d2aSXin Li redundancy = 0;
477*a58d3d2aSXin Li }
478*a58d3d2aSXin Li /* Shrink decoder because of raw bits */
479*a58d3d2aSXin Li dec.storage -= redundancy_bytes;
480*a58d3d2aSXin Li }
481*a58d3d2aSXin Li }
482*a58d3d2aSXin Li if (mode != MODE_CELT_ONLY)
483*a58d3d2aSXin Li start_band = 17;
484*a58d3d2aSXin Li
485*a58d3d2aSXin Li if (redundancy)
486*a58d3d2aSXin Li {
487*a58d3d2aSXin Li transition = 0;
488*a58d3d2aSXin Li pcm_transition_silk_size=ALLOC_NONE;
489*a58d3d2aSXin Li }
490*a58d3d2aSXin Li
491*a58d3d2aSXin Li ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);
492*a58d3d2aSXin Li
493*a58d3d2aSXin Li if (transition && mode != MODE_CELT_ONLY)
494*a58d3d2aSXin Li {
495*a58d3d2aSXin Li pcm_transition = pcm_transition_silk;
496*a58d3d2aSXin Li opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
497*a58d3d2aSXin Li }
498*a58d3d2aSXin Li
499*a58d3d2aSXin Li
500*a58d3d2aSXin Li if (bandwidth)
501*a58d3d2aSXin Li {
502*a58d3d2aSXin Li int endband=21;
503*a58d3d2aSXin Li
504*a58d3d2aSXin Li switch(bandwidth)
505*a58d3d2aSXin Li {
506*a58d3d2aSXin Li case OPUS_BANDWIDTH_NARROWBAND:
507*a58d3d2aSXin Li endband = 13;
508*a58d3d2aSXin Li break;
509*a58d3d2aSXin Li case OPUS_BANDWIDTH_MEDIUMBAND:
510*a58d3d2aSXin Li case OPUS_BANDWIDTH_WIDEBAND:
511*a58d3d2aSXin Li endband = 17;
512*a58d3d2aSXin Li break;
513*a58d3d2aSXin Li case OPUS_BANDWIDTH_SUPERWIDEBAND:
514*a58d3d2aSXin Li endband = 19;
515*a58d3d2aSXin Li break;
516*a58d3d2aSXin Li case OPUS_BANDWIDTH_FULLBAND:
517*a58d3d2aSXin Li endband = 21;
518*a58d3d2aSXin Li break;
519*a58d3d2aSXin Li default:
520*a58d3d2aSXin Li celt_assert(0);
521*a58d3d2aSXin Li break;
522*a58d3d2aSXin Li }
523*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)));
524*a58d3d2aSXin Li }
525*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)));
526*a58d3d2aSXin Li
527*a58d3d2aSXin Li /* Only allocation memory for redundancy if/when needed */
528*a58d3d2aSXin Li redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
529*a58d3d2aSXin Li ALLOC(redundant_audio, redundant_audio_size, opus_val16);
530*a58d3d2aSXin Li
531*a58d3d2aSXin Li /* 5 ms redundant frame for CELT->SILK*/
532*a58d3d2aSXin Li if (redundancy && celt_to_silk)
533*a58d3d2aSXin Li {
534*a58d3d2aSXin Li /* If the previous frame did not use CELT (the first redundancy frame in
535*a58d3d2aSXin Li a transition from SILK may have been lost) then the CELT decoder is
536*a58d3d2aSXin Li stale at this point and the redundancy audio is not useful, however
537*a58d3d2aSXin Li the final range is still needed (for testing), so the redundancy is
538*a58d3d2aSXin Li always decoded but the decoded audio may not be used */
539*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
540*a58d3d2aSXin Li celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
541*a58d3d2aSXin Li redundant_audio, F5, NULL, 0);
542*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)));
543*a58d3d2aSXin Li }
544*a58d3d2aSXin Li
545*a58d3d2aSXin Li /* MUST be after PLC */
546*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)));
547*a58d3d2aSXin Li
548*a58d3d2aSXin Li if (mode != MODE_SILK_ONLY)
549*a58d3d2aSXin Li {
550*a58d3d2aSXin Li int celt_frame_size = IMIN(F20, frame_size);
551*a58d3d2aSXin Li /* Make sure to discard any previous CELT state */
552*a58d3d2aSXin Li if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
553*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE));
554*a58d3d2aSXin Li /* Decode CELT */
555*a58d3d2aSXin Li celt_ret = celt_decode_with_ec_dred(celt_dec, decode_fec ? NULL : data,
556*a58d3d2aSXin Li len, pcm, celt_frame_size, &dec, celt_accum
557*a58d3d2aSXin Li #ifdef ENABLE_DEEP_PLC
558*a58d3d2aSXin Li , &st->lpcnet
559*a58d3d2aSXin Li #endif
560*a58d3d2aSXin Li );
561*a58d3d2aSXin Li } else {
562*a58d3d2aSXin Li unsigned char silence[2] = {0xFF, 0xFF};
563*a58d3d2aSXin Li if (!celt_accum)
564*a58d3d2aSXin Li {
565*a58d3d2aSXin Li for (i=0;i<frame_size*st->channels;i++)
566*a58d3d2aSXin Li pcm[i] = 0;
567*a58d3d2aSXin Li }
568*a58d3d2aSXin Li /* For hybrid -> SILK transitions, we let the CELT MDCT
569*a58d3d2aSXin Li do a fade-out by decoding a silence frame */
570*a58d3d2aSXin Li if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )
571*a58d3d2aSXin Li {
572*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
573*a58d3d2aSXin Li celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);
574*a58d3d2aSXin Li }
575*a58d3d2aSXin Li }
576*a58d3d2aSXin Li
577*a58d3d2aSXin Li if (mode != MODE_CELT_ONLY && !celt_accum)
578*a58d3d2aSXin Li {
579*a58d3d2aSXin Li #ifdef FIXED_POINT
580*a58d3d2aSXin Li for (i=0;i<frame_size*st->channels;i++)
581*a58d3d2aSXin Li pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i]));
582*a58d3d2aSXin Li #else
583*a58d3d2aSXin Li for (i=0;i<frame_size*st->channels;i++)
584*a58d3d2aSXin Li pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);
585*a58d3d2aSXin Li #endif
586*a58d3d2aSXin Li }
587*a58d3d2aSXin Li
588*a58d3d2aSXin Li {
589*a58d3d2aSXin Li const CELTMode *celt_mode;
590*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)));
591*a58d3d2aSXin Li window = celt_mode->window;
592*a58d3d2aSXin Li }
593*a58d3d2aSXin Li
594*a58d3d2aSXin Li /* 5 ms redundant frame for SILK->CELT */
595*a58d3d2aSXin Li if (redundancy && !celt_to_silk)
596*a58d3d2aSXin Li {
597*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE));
598*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
599*a58d3d2aSXin Li
600*a58d3d2aSXin Li celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);
601*a58d3d2aSXin Li MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)));
602*a58d3d2aSXin Li smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
603*a58d3d2aSXin Li pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
604*a58d3d2aSXin Li }
605*a58d3d2aSXin Li /* 5ms redundant frame for CELT->SILK; ignore if the previous frame did not
606*a58d3d2aSXin Li use CELT (the first redundancy frame in a transition from SILK may have
607*a58d3d2aSXin Li been lost) */
608*a58d3d2aSXin Li if (redundancy && celt_to_silk && (st->prev_mode != MODE_SILK_ONLY || st->prev_redundancy))
609*a58d3d2aSXin Li {
610*a58d3d2aSXin Li for (c=0;c<st->channels;c++)
611*a58d3d2aSXin Li {
612*a58d3d2aSXin Li for (i=0;i<F2_5;i++)
613*a58d3d2aSXin Li pcm[st->channels*i+c] = redundant_audio[st->channels*i+c];
614*a58d3d2aSXin Li }
615*a58d3d2aSXin Li smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5,
616*a58d3d2aSXin Li pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs);
617*a58d3d2aSXin Li }
618*a58d3d2aSXin Li if (transition)
619*a58d3d2aSXin Li {
620*a58d3d2aSXin Li if (audiosize >= F5)
621*a58d3d2aSXin Li {
622*a58d3d2aSXin Li for (i=0;i<st->channels*F2_5;i++)
623*a58d3d2aSXin Li pcm[i] = pcm_transition[i];
624*a58d3d2aSXin Li smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5,
625*a58d3d2aSXin Li pcm+st->channels*F2_5, F2_5,
626*a58d3d2aSXin Li st->channels, window, st->Fs);
627*a58d3d2aSXin Li } else {
628*a58d3d2aSXin Li /* Not enough time to do a clean transition, but we do it anyway
629*a58d3d2aSXin Li This will not preserve amplitude perfectly and may introduce
630*a58d3d2aSXin Li a bit of temporal aliasing, but it shouldn't be too bad and
631*a58d3d2aSXin Li that's pretty much the best we can do. In any case, generating this
632*a58d3d2aSXin Li transition it pretty silly in the first place */
633*a58d3d2aSXin Li smooth_fade(pcm_transition, pcm,
634*a58d3d2aSXin Li pcm, F2_5,
635*a58d3d2aSXin Li st->channels, window, st->Fs);
636*a58d3d2aSXin Li }
637*a58d3d2aSXin Li }
638*a58d3d2aSXin Li
639*a58d3d2aSXin Li if(st->decode_gain)
640*a58d3d2aSXin Li {
641*a58d3d2aSXin Li opus_val32 gain;
642*a58d3d2aSXin Li gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain));
643*a58d3d2aSXin Li for (i=0;i<frame_size*st->channels;i++)
644*a58d3d2aSXin Li {
645*a58d3d2aSXin Li opus_val32 x;
646*a58d3d2aSXin Li x = MULT16_32_P16(pcm[i],gain);
647*a58d3d2aSXin Li pcm[i] = SATURATE(x, 32767);
648*a58d3d2aSXin Li }
649*a58d3d2aSXin Li }
650*a58d3d2aSXin Li
651*a58d3d2aSXin Li if (len <= 1)
652*a58d3d2aSXin Li st->rangeFinal = 0;
653*a58d3d2aSXin Li else
654*a58d3d2aSXin Li st->rangeFinal = dec.rng ^ redundant_rng;
655*a58d3d2aSXin Li
656*a58d3d2aSXin Li st->prev_mode = mode;
657*a58d3d2aSXin Li st->prev_redundancy = redundancy && !celt_to_silk;
658*a58d3d2aSXin Li
659*a58d3d2aSXin Li if (celt_ret>=0)
660*a58d3d2aSXin Li {
661*a58d3d2aSXin Li if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels))
662*a58d3d2aSXin Li OPUS_PRINT_INT(audiosize);
663*a58d3d2aSXin Li }
664*a58d3d2aSXin Li
665*a58d3d2aSXin Li RESTORE_STACK;
666*a58d3d2aSXin Li return celt_ret < 0 ? celt_ret : audiosize;
667*a58d3d2aSXin Li
668*a58d3d2aSXin Li }
669*a58d3d2aSXin Li
opus_decode_native(OpusDecoder * st,const unsigned char * data,opus_int32 len,opus_val16 * pcm,int frame_size,int decode_fec,int self_delimited,opus_int32 * packet_offset,int soft_clip,const OpusDRED * dred,opus_int32 dred_offset)670*a58d3d2aSXin Li int opus_decode_native(OpusDecoder *st, const unsigned char *data,
671*a58d3d2aSXin Li opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
672*a58d3d2aSXin Li int self_delimited, opus_int32 *packet_offset, int soft_clip, const OpusDRED *dred, opus_int32 dred_offset)
673*a58d3d2aSXin Li {
674*a58d3d2aSXin Li int i, nb_samples;
675*a58d3d2aSXin Li int count, offset;
676*a58d3d2aSXin Li unsigned char toc;
677*a58d3d2aSXin Li int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
678*a58d3d2aSXin Li /* 48 x 2.5 ms = 120 ms */
679*a58d3d2aSXin Li opus_int16 size[48];
680*a58d3d2aSXin Li VALIDATE_OPUS_DECODER(st);
681*a58d3d2aSXin Li if (decode_fec<0 || decode_fec>1)
682*a58d3d2aSXin Li return OPUS_BAD_ARG;
683*a58d3d2aSXin Li /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
684*a58d3d2aSXin Li if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
685*a58d3d2aSXin Li return OPUS_BAD_ARG;
686*a58d3d2aSXin Li #ifdef ENABLE_DRED
687*a58d3d2aSXin Li if (dred != NULL && dred->process_stage == 2) {
688*a58d3d2aSXin Li int F10;
689*a58d3d2aSXin Li int features_per_frame;
690*a58d3d2aSXin Li int needed_feature_frames;
691*a58d3d2aSXin Li int init_frames;
692*a58d3d2aSXin Li lpcnet_plc_fec_clear(&st->lpcnet);
693*a58d3d2aSXin Li F10 = st->Fs/100;
694*a58d3d2aSXin Li /* if blend==0, the last PLC call was "update" and we need to feed two extra 10-ms frames. */
695*a58d3d2aSXin Li init_frames = (st->lpcnet.blend == 0) ? 2 : 0;
696*a58d3d2aSXin Li features_per_frame = IMAX(1, frame_size/F10);
697*a58d3d2aSXin Li needed_feature_frames = init_frames + features_per_frame;
698*a58d3d2aSXin Li lpcnet_plc_fec_clear(&st->lpcnet);
699*a58d3d2aSXin Li for (i=0;i<needed_feature_frames;i++) {
700*a58d3d2aSXin Li int feature_offset;
701*a58d3d2aSXin Li /* We floor instead of rounding because 5-ms overlap compensates for the missing 0.5 rounding offset. */
702*a58d3d2aSXin Li feature_offset = init_frames - i - 2 + (int)floor(((float)dred_offset + dred->dred_offset*F10/4)/F10);
703*a58d3d2aSXin Li if (feature_offset <= 4*dred->nb_latents-1 && feature_offset >= 0) {
704*a58d3d2aSXin Li lpcnet_plc_fec_add(&st->lpcnet, dred->fec_features+feature_offset*DRED_NUM_FEATURES);
705*a58d3d2aSXin Li } else {
706*a58d3d2aSXin Li if (feature_offset >= 0) lpcnet_plc_fec_add(&st->lpcnet, NULL);
707*a58d3d2aSXin Li }
708*a58d3d2aSXin Li
709*a58d3d2aSXin Li }
710*a58d3d2aSXin Li }
711*a58d3d2aSXin Li #else
712*a58d3d2aSXin Li (void)dred;
713*a58d3d2aSXin Li (void)dred_offset;
714*a58d3d2aSXin Li #endif
715*a58d3d2aSXin Li if (len==0 || data==NULL)
716*a58d3d2aSXin Li {
717*a58d3d2aSXin Li int pcm_count=0;
718*a58d3d2aSXin Li do {
719*a58d3d2aSXin Li int ret;
720*a58d3d2aSXin Li ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0);
721*a58d3d2aSXin Li if (ret<0)
722*a58d3d2aSXin Li return ret;
723*a58d3d2aSXin Li pcm_count += ret;
724*a58d3d2aSXin Li } while (pcm_count < frame_size);
725*a58d3d2aSXin Li celt_assert(pcm_count == frame_size);
726*a58d3d2aSXin Li if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels))
727*a58d3d2aSXin Li OPUS_PRINT_INT(pcm_count);
728*a58d3d2aSXin Li st->last_packet_duration = pcm_count;
729*a58d3d2aSXin Li return pcm_count;
730*a58d3d2aSXin Li } else if (len<0)
731*a58d3d2aSXin Li return OPUS_BAD_ARG;
732*a58d3d2aSXin Li
733*a58d3d2aSXin Li packet_mode = opus_packet_get_mode(data);
734*a58d3d2aSXin Li packet_bandwidth = opus_packet_get_bandwidth(data);
735*a58d3d2aSXin Li packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
736*a58d3d2aSXin Li packet_stream_channels = opus_packet_get_nb_channels(data);
737*a58d3d2aSXin Li
738*a58d3d2aSXin Li count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
739*a58d3d2aSXin Li size, &offset, packet_offset, NULL, NULL);
740*a58d3d2aSXin Li if (count<0)
741*a58d3d2aSXin Li return count;
742*a58d3d2aSXin Li
743*a58d3d2aSXin Li data += offset;
744*a58d3d2aSXin Li
745*a58d3d2aSXin Li if (decode_fec)
746*a58d3d2aSXin Li {
747*a58d3d2aSXin Li int duration_copy;
748*a58d3d2aSXin Li int ret;
749*a58d3d2aSXin Li /* If no FEC can be present, run the PLC (recursive call) */
750*a58d3d2aSXin Li if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY)
751*a58d3d2aSXin Li return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip, NULL, 0);
752*a58d3d2aSXin Li /* Otherwise, run the PLC on everything except the size for which we might have FEC */
753*a58d3d2aSXin Li duration_copy = st->last_packet_duration;
754*a58d3d2aSXin Li if (frame_size-packet_frame_size!=0)
755*a58d3d2aSXin Li {
756*a58d3d2aSXin Li ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip, NULL, 0);
757*a58d3d2aSXin Li if (ret<0)
758*a58d3d2aSXin Li {
759*a58d3d2aSXin Li st->last_packet_duration = duration_copy;
760*a58d3d2aSXin Li return ret;
761*a58d3d2aSXin Li }
762*a58d3d2aSXin Li celt_assert(ret==frame_size-packet_frame_size);
763*a58d3d2aSXin Li }
764*a58d3d2aSXin Li /* Complete with FEC */
765*a58d3d2aSXin Li st->mode = packet_mode;
766*a58d3d2aSXin Li st->bandwidth = packet_bandwidth;
767*a58d3d2aSXin Li st->frame_size = packet_frame_size;
768*a58d3d2aSXin Li st->stream_channels = packet_stream_channels;
769*a58d3d2aSXin Li ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size),
770*a58d3d2aSXin Li packet_frame_size, 1);
771*a58d3d2aSXin Li if (ret<0)
772*a58d3d2aSXin Li return ret;
773*a58d3d2aSXin Li else {
774*a58d3d2aSXin Li if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels))
775*a58d3d2aSXin Li OPUS_PRINT_INT(frame_size);
776*a58d3d2aSXin Li st->last_packet_duration = frame_size;
777*a58d3d2aSXin Li return frame_size;
778*a58d3d2aSXin Li }
779*a58d3d2aSXin Li }
780*a58d3d2aSXin Li
781*a58d3d2aSXin Li if (count*packet_frame_size > frame_size)
782*a58d3d2aSXin Li return OPUS_BUFFER_TOO_SMALL;
783*a58d3d2aSXin Li
784*a58d3d2aSXin Li /* Update the state as the last step to avoid updating it on an invalid packet */
785*a58d3d2aSXin Li st->mode = packet_mode;
786*a58d3d2aSXin Li st->bandwidth = packet_bandwidth;
787*a58d3d2aSXin Li st->frame_size = packet_frame_size;
788*a58d3d2aSXin Li st->stream_channels = packet_stream_channels;
789*a58d3d2aSXin Li
790*a58d3d2aSXin Li nb_samples=0;
791*a58d3d2aSXin Li for (i=0;i<count;i++)
792*a58d3d2aSXin Li {
793*a58d3d2aSXin Li int ret;
794*a58d3d2aSXin Li ret = opus_decode_frame(st, data, size[i], pcm+nb_samples*st->channels, frame_size-nb_samples, 0);
795*a58d3d2aSXin Li if (ret<0)
796*a58d3d2aSXin Li return ret;
797*a58d3d2aSXin Li celt_assert(ret==packet_frame_size);
798*a58d3d2aSXin Li data += size[i];
799*a58d3d2aSXin Li nb_samples += ret;
800*a58d3d2aSXin Li }
801*a58d3d2aSXin Li st->last_packet_duration = nb_samples;
802*a58d3d2aSXin Li if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels))
803*a58d3d2aSXin Li OPUS_PRINT_INT(nb_samples);
804*a58d3d2aSXin Li #ifndef FIXED_POINT
805*a58d3d2aSXin Li if (soft_clip)
806*a58d3d2aSXin Li opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem);
807*a58d3d2aSXin Li else
808*a58d3d2aSXin Li st->softclip_mem[0]=st->softclip_mem[1]=0;
809*a58d3d2aSXin Li #endif
810*a58d3d2aSXin Li return nb_samples;
811*a58d3d2aSXin Li }
812*a58d3d2aSXin Li
813*a58d3d2aSXin Li #ifdef FIXED_POINT
814*a58d3d2aSXin Li
opus_decode(OpusDecoder * st,const unsigned char * data,opus_int32 len,opus_val16 * pcm,int frame_size,int decode_fec)815*a58d3d2aSXin Li int opus_decode(OpusDecoder *st, const unsigned char *data,
816*a58d3d2aSXin Li opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
817*a58d3d2aSXin Li {
818*a58d3d2aSXin Li if(frame_size<=0)
819*a58d3d2aSXin Li return OPUS_BAD_ARG;
820*a58d3d2aSXin Li return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
821*a58d3d2aSXin Li }
822*a58d3d2aSXin Li
823*a58d3d2aSXin Li #ifndef DISABLE_FLOAT_API
opus_decode_float(OpusDecoder * st,const unsigned char * data,opus_int32 len,float * pcm,int frame_size,int decode_fec)824*a58d3d2aSXin Li int opus_decode_float(OpusDecoder *st, const unsigned char *data,
825*a58d3d2aSXin Li opus_int32 len, float *pcm, int frame_size, int decode_fec)
826*a58d3d2aSXin Li {
827*a58d3d2aSXin Li VARDECL(opus_int16, out);
828*a58d3d2aSXin Li int ret, i;
829*a58d3d2aSXin Li int nb_samples;
830*a58d3d2aSXin Li ALLOC_STACK;
831*a58d3d2aSXin Li
832*a58d3d2aSXin Li if(frame_size<=0)
833*a58d3d2aSXin Li {
834*a58d3d2aSXin Li RESTORE_STACK;
835*a58d3d2aSXin Li return OPUS_BAD_ARG;
836*a58d3d2aSXin Li }
837*a58d3d2aSXin Li if (data != NULL && len > 0 && !decode_fec)
838*a58d3d2aSXin Li {
839*a58d3d2aSXin Li nb_samples = opus_decoder_get_nb_samples(st, data, len);
840*a58d3d2aSXin Li if (nb_samples>0)
841*a58d3d2aSXin Li frame_size = IMIN(frame_size, nb_samples);
842*a58d3d2aSXin Li else
843*a58d3d2aSXin Li return OPUS_INVALID_PACKET;
844*a58d3d2aSXin Li }
845*a58d3d2aSXin Li celt_assert(st->channels == 1 || st->channels == 2);
846*a58d3d2aSXin Li ALLOC(out, frame_size*st->channels, opus_int16);
847*a58d3d2aSXin Li
848*a58d3d2aSXin Li ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
849*a58d3d2aSXin Li if (ret > 0)
850*a58d3d2aSXin Li {
851*a58d3d2aSXin Li for (i=0;i<ret*st->channels;i++)
852*a58d3d2aSXin Li pcm[i] = (1.f/32768.f)*(out[i]);
853*a58d3d2aSXin Li }
854*a58d3d2aSXin Li RESTORE_STACK;
855*a58d3d2aSXin Li return ret;
856*a58d3d2aSXin Li }
857*a58d3d2aSXin Li #endif
858*a58d3d2aSXin Li
859*a58d3d2aSXin Li
860*a58d3d2aSXin Li #else
opus_decode(OpusDecoder * st,const unsigned char * data,opus_int32 len,opus_int16 * pcm,int frame_size,int decode_fec)861*a58d3d2aSXin Li int opus_decode(OpusDecoder *st, const unsigned char *data,
862*a58d3d2aSXin Li opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
863*a58d3d2aSXin Li {
864*a58d3d2aSXin Li VARDECL(float, out);
865*a58d3d2aSXin Li int ret, i;
866*a58d3d2aSXin Li int nb_samples;
867*a58d3d2aSXin Li ALLOC_STACK;
868*a58d3d2aSXin Li
869*a58d3d2aSXin Li if(frame_size<=0)
870*a58d3d2aSXin Li {
871*a58d3d2aSXin Li RESTORE_STACK;
872*a58d3d2aSXin Li return OPUS_BAD_ARG;
873*a58d3d2aSXin Li }
874*a58d3d2aSXin Li
875*a58d3d2aSXin Li if (data != NULL && len > 0 && !decode_fec)
876*a58d3d2aSXin Li {
877*a58d3d2aSXin Li nb_samples = opus_decoder_get_nb_samples(st, data, len);
878*a58d3d2aSXin Li if (nb_samples>0)
879*a58d3d2aSXin Li frame_size = IMIN(frame_size, nb_samples);
880*a58d3d2aSXin Li else
881*a58d3d2aSXin Li return OPUS_INVALID_PACKET;
882*a58d3d2aSXin Li }
883*a58d3d2aSXin Li celt_assert(st->channels == 1 || st->channels == 2);
884*a58d3d2aSXin Li ALLOC(out, frame_size*st->channels, float);
885*a58d3d2aSXin Li
886*a58d3d2aSXin Li ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1, NULL, 0);
887*a58d3d2aSXin Li if (ret > 0)
888*a58d3d2aSXin Li {
889*a58d3d2aSXin Li for (i=0;i<ret*st->channels;i++)
890*a58d3d2aSXin Li pcm[i] = FLOAT2INT16(out[i]);
891*a58d3d2aSXin Li }
892*a58d3d2aSXin Li RESTORE_STACK;
893*a58d3d2aSXin Li return ret;
894*a58d3d2aSXin Li }
895*a58d3d2aSXin Li
opus_decode_float(OpusDecoder * st,const unsigned char * data,opus_int32 len,opus_val16 * pcm,int frame_size,int decode_fec)896*a58d3d2aSXin Li int opus_decode_float(OpusDecoder *st, const unsigned char *data,
897*a58d3d2aSXin Li opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
898*a58d3d2aSXin Li {
899*a58d3d2aSXin Li if(frame_size<=0)
900*a58d3d2aSXin Li return OPUS_BAD_ARG;
901*a58d3d2aSXin Li return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0, NULL, 0);
902*a58d3d2aSXin Li }
903*a58d3d2aSXin Li
904*a58d3d2aSXin Li #endif
905*a58d3d2aSXin Li
opus_decoder_ctl(OpusDecoder * st,int request,...)906*a58d3d2aSXin Li int opus_decoder_ctl(OpusDecoder *st, int request, ...)
907*a58d3d2aSXin Li {
908*a58d3d2aSXin Li int ret = OPUS_OK;
909*a58d3d2aSXin Li va_list ap;
910*a58d3d2aSXin Li void *silk_dec;
911*a58d3d2aSXin Li CELTDecoder *celt_dec;
912*a58d3d2aSXin Li
913*a58d3d2aSXin Li silk_dec = (char*)st+st->silk_dec_offset;
914*a58d3d2aSXin Li celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
915*a58d3d2aSXin Li
916*a58d3d2aSXin Li
917*a58d3d2aSXin Li va_start(ap, request);
918*a58d3d2aSXin Li
919*a58d3d2aSXin Li switch (request)
920*a58d3d2aSXin Li {
921*a58d3d2aSXin Li case OPUS_GET_BANDWIDTH_REQUEST:
922*a58d3d2aSXin Li {
923*a58d3d2aSXin Li opus_int32 *value = va_arg(ap, opus_int32*);
924*a58d3d2aSXin Li if (!value)
925*a58d3d2aSXin Li {
926*a58d3d2aSXin Li goto bad_arg;
927*a58d3d2aSXin Li }
928*a58d3d2aSXin Li *value = st->bandwidth;
929*a58d3d2aSXin Li }
930*a58d3d2aSXin Li break;
931*a58d3d2aSXin Li case OPUS_SET_COMPLEXITY_REQUEST:
932*a58d3d2aSXin Li {
933*a58d3d2aSXin Li opus_int32 value = va_arg(ap, opus_int32);
934*a58d3d2aSXin Li if(value<0 || value>10)
935*a58d3d2aSXin Li {
936*a58d3d2aSXin Li goto bad_arg;
937*a58d3d2aSXin Li }
938*a58d3d2aSXin Li st->complexity = value;
939*a58d3d2aSXin Li celt_decoder_ctl(celt_dec, OPUS_SET_COMPLEXITY(value));
940*a58d3d2aSXin Li }
941*a58d3d2aSXin Li break;
942*a58d3d2aSXin Li case OPUS_GET_COMPLEXITY_REQUEST:
943*a58d3d2aSXin Li {
944*a58d3d2aSXin Li opus_int32 *value = va_arg(ap, opus_int32*);
945*a58d3d2aSXin Li if (!value)
946*a58d3d2aSXin Li {
947*a58d3d2aSXin Li goto bad_arg;
948*a58d3d2aSXin Li }
949*a58d3d2aSXin Li *value = st->complexity;
950*a58d3d2aSXin Li }
951*a58d3d2aSXin Li break;
952*a58d3d2aSXin Li case OPUS_GET_FINAL_RANGE_REQUEST:
953*a58d3d2aSXin Li {
954*a58d3d2aSXin Li opus_uint32 *value = va_arg(ap, opus_uint32*);
955*a58d3d2aSXin Li if (!value)
956*a58d3d2aSXin Li {
957*a58d3d2aSXin Li goto bad_arg;
958*a58d3d2aSXin Li }
959*a58d3d2aSXin Li *value = st->rangeFinal;
960*a58d3d2aSXin Li }
961*a58d3d2aSXin Li break;
962*a58d3d2aSXin Li case OPUS_RESET_STATE:
963*a58d3d2aSXin Li {
964*a58d3d2aSXin Li OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
965*a58d3d2aSXin Li sizeof(OpusDecoder)-
966*a58d3d2aSXin Li ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));
967*a58d3d2aSXin Li
968*a58d3d2aSXin Li celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
969*a58d3d2aSXin Li silk_ResetDecoder( silk_dec );
970*a58d3d2aSXin Li st->stream_channels = st->channels;
971*a58d3d2aSXin Li st->frame_size = st->Fs/400;
972*a58d3d2aSXin Li #ifdef ENABLE_DEEP_PLC
973*a58d3d2aSXin Li lpcnet_plc_reset( &st->lpcnet );
974*a58d3d2aSXin Li #endif
975*a58d3d2aSXin Li }
976*a58d3d2aSXin Li break;
977*a58d3d2aSXin Li case OPUS_GET_SAMPLE_RATE_REQUEST:
978*a58d3d2aSXin Li {
979*a58d3d2aSXin Li opus_int32 *value = va_arg(ap, opus_int32*);
980*a58d3d2aSXin Li if (!value)
981*a58d3d2aSXin Li {
982*a58d3d2aSXin Li goto bad_arg;
983*a58d3d2aSXin Li }
984*a58d3d2aSXin Li *value = st->Fs;
985*a58d3d2aSXin Li }
986*a58d3d2aSXin Li break;
987*a58d3d2aSXin Li case OPUS_GET_PITCH_REQUEST:
988*a58d3d2aSXin Li {
989*a58d3d2aSXin Li opus_int32 *value = va_arg(ap, opus_int32*);
990*a58d3d2aSXin Li if (!value)
991*a58d3d2aSXin Li {
992*a58d3d2aSXin Li goto bad_arg;
993*a58d3d2aSXin Li }
994*a58d3d2aSXin Li if (st->prev_mode == MODE_CELT_ONLY)
995*a58d3d2aSXin Li ret = celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
996*a58d3d2aSXin Li else
997*a58d3d2aSXin Li *value = st->DecControl.prevPitchLag;
998*a58d3d2aSXin Li }
999*a58d3d2aSXin Li break;
1000*a58d3d2aSXin Li case OPUS_GET_GAIN_REQUEST:
1001*a58d3d2aSXin Li {
1002*a58d3d2aSXin Li opus_int32 *value = va_arg(ap, opus_int32*);
1003*a58d3d2aSXin Li if (!value)
1004*a58d3d2aSXin Li {
1005*a58d3d2aSXin Li goto bad_arg;
1006*a58d3d2aSXin Li }
1007*a58d3d2aSXin Li *value = st->decode_gain;
1008*a58d3d2aSXin Li }
1009*a58d3d2aSXin Li break;
1010*a58d3d2aSXin Li case OPUS_SET_GAIN_REQUEST:
1011*a58d3d2aSXin Li {
1012*a58d3d2aSXin Li opus_int32 value = va_arg(ap, opus_int32);
1013*a58d3d2aSXin Li if (value<-32768 || value>32767)
1014*a58d3d2aSXin Li {
1015*a58d3d2aSXin Li goto bad_arg;
1016*a58d3d2aSXin Li }
1017*a58d3d2aSXin Li st->decode_gain = value;
1018*a58d3d2aSXin Li }
1019*a58d3d2aSXin Li break;
1020*a58d3d2aSXin Li case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
1021*a58d3d2aSXin Li {
1022*a58d3d2aSXin Li opus_int32 *value = va_arg(ap, opus_int32*);
1023*a58d3d2aSXin Li if (!value)
1024*a58d3d2aSXin Li {
1025*a58d3d2aSXin Li goto bad_arg;
1026*a58d3d2aSXin Li }
1027*a58d3d2aSXin Li *value = st->last_packet_duration;
1028*a58d3d2aSXin Li }
1029*a58d3d2aSXin Li break;
1030*a58d3d2aSXin Li case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
1031*a58d3d2aSXin Li {
1032*a58d3d2aSXin Li opus_int32 value = va_arg(ap, opus_int32);
1033*a58d3d2aSXin Li if(value<0 || value>1)
1034*a58d3d2aSXin Li {
1035*a58d3d2aSXin Li goto bad_arg;
1036*a58d3d2aSXin Li }
1037*a58d3d2aSXin Li ret = celt_decoder_ctl(celt_dec, OPUS_SET_PHASE_INVERSION_DISABLED(value));
1038*a58d3d2aSXin Li }
1039*a58d3d2aSXin Li break;
1040*a58d3d2aSXin Li case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
1041*a58d3d2aSXin Li {
1042*a58d3d2aSXin Li opus_int32 *value = va_arg(ap, opus_int32*);
1043*a58d3d2aSXin Li if (!value)
1044*a58d3d2aSXin Li {
1045*a58d3d2aSXin Li goto bad_arg;
1046*a58d3d2aSXin Li }
1047*a58d3d2aSXin Li ret = celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value));
1048*a58d3d2aSXin Li }
1049*a58d3d2aSXin Li break;
1050*a58d3d2aSXin Li #ifdef USE_WEIGHTS_FILE
1051*a58d3d2aSXin Li case OPUS_SET_DNN_BLOB_REQUEST:
1052*a58d3d2aSXin Li {
1053*a58d3d2aSXin Li const unsigned char *data = va_arg(ap, const unsigned char *);
1054*a58d3d2aSXin Li opus_int32 len = va_arg(ap, opus_int32);
1055*a58d3d2aSXin Li if(len<0 || data == NULL)
1056*a58d3d2aSXin Li {
1057*a58d3d2aSXin Li goto bad_arg;
1058*a58d3d2aSXin Li }
1059*a58d3d2aSXin Li ret = lpcnet_plc_load_model(&st->lpcnet, data, len);
1060*a58d3d2aSXin Li ret = silk_LoadOSCEModels(silk_dec, data, len) || ret;
1061*a58d3d2aSXin Li }
1062*a58d3d2aSXin Li break;
1063*a58d3d2aSXin Li #endif
1064*a58d3d2aSXin Li default:
1065*a58d3d2aSXin Li /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
1066*a58d3d2aSXin Li ret = OPUS_UNIMPLEMENTED;
1067*a58d3d2aSXin Li break;
1068*a58d3d2aSXin Li }
1069*a58d3d2aSXin Li
1070*a58d3d2aSXin Li va_end(ap);
1071*a58d3d2aSXin Li return ret;
1072*a58d3d2aSXin Li bad_arg:
1073*a58d3d2aSXin Li va_end(ap);
1074*a58d3d2aSXin Li return OPUS_BAD_ARG;
1075*a58d3d2aSXin Li }
1076*a58d3d2aSXin Li
opus_decoder_destroy(OpusDecoder * st)1077*a58d3d2aSXin Li void opus_decoder_destroy(OpusDecoder *st)
1078*a58d3d2aSXin Li {
1079*a58d3d2aSXin Li opus_free(st);
1080*a58d3d2aSXin Li }
1081*a58d3d2aSXin Li
1082*a58d3d2aSXin Li
opus_packet_get_bandwidth(const unsigned char * data)1083*a58d3d2aSXin Li int opus_packet_get_bandwidth(const unsigned char *data)
1084*a58d3d2aSXin Li {
1085*a58d3d2aSXin Li int bandwidth;
1086*a58d3d2aSXin Li if (data[0]&0x80)
1087*a58d3d2aSXin Li {
1088*a58d3d2aSXin Li bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3);
1089*a58d3d2aSXin Li if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
1090*a58d3d2aSXin Li bandwidth = OPUS_BANDWIDTH_NARROWBAND;
1091*a58d3d2aSXin Li } else if ((data[0]&0x60) == 0x60)
1092*a58d3d2aSXin Li {
1093*a58d3d2aSXin Li bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND :
1094*a58d3d2aSXin Li OPUS_BANDWIDTH_SUPERWIDEBAND;
1095*a58d3d2aSXin Li } else {
1096*a58d3d2aSXin Li bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3);
1097*a58d3d2aSXin Li }
1098*a58d3d2aSXin Li return bandwidth;
1099*a58d3d2aSXin Li }
1100*a58d3d2aSXin Li
opus_packet_get_nb_channels(const unsigned char * data)1101*a58d3d2aSXin Li int opus_packet_get_nb_channels(const unsigned char *data)
1102*a58d3d2aSXin Li {
1103*a58d3d2aSXin Li return (data[0]&0x4) ? 2 : 1;
1104*a58d3d2aSXin Li }
1105*a58d3d2aSXin Li
opus_packet_get_nb_frames(const unsigned char packet[],opus_int32 len)1106*a58d3d2aSXin Li int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)
1107*a58d3d2aSXin Li {
1108*a58d3d2aSXin Li int count;
1109*a58d3d2aSXin Li if (len<1)
1110*a58d3d2aSXin Li return OPUS_BAD_ARG;
1111*a58d3d2aSXin Li count = packet[0]&0x3;
1112*a58d3d2aSXin Li if (count==0)
1113*a58d3d2aSXin Li return 1;
1114*a58d3d2aSXin Li else if (count!=3)
1115*a58d3d2aSXin Li return 2;
1116*a58d3d2aSXin Li else if (len<2)
1117*a58d3d2aSXin Li return OPUS_INVALID_PACKET;
1118*a58d3d2aSXin Li else
1119*a58d3d2aSXin Li return packet[1]&0x3F;
1120*a58d3d2aSXin Li }
1121*a58d3d2aSXin Li
opus_packet_get_nb_samples(const unsigned char packet[],opus_int32 len,opus_int32 Fs)1122*a58d3d2aSXin Li int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len,
1123*a58d3d2aSXin Li opus_int32 Fs)
1124*a58d3d2aSXin Li {
1125*a58d3d2aSXin Li int samples;
1126*a58d3d2aSXin Li int count = opus_packet_get_nb_frames(packet, len);
1127*a58d3d2aSXin Li
1128*a58d3d2aSXin Li if (count<0)
1129*a58d3d2aSXin Li return count;
1130*a58d3d2aSXin Li
1131*a58d3d2aSXin Li samples = count*opus_packet_get_samples_per_frame(packet, Fs);
1132*a58d3d2aSXin Li /* Can't have more than 120 ms */
1133*a58d3d2aSXin Li if (samples*25 > Fs*3)
1134*a58d3d2aSXin Li return OPUS_INVALID_PACKET;
1135*a58d3d2aSXin Li else
1136*a58d3d2aSXin Li return samples;
1137*a58d3d2aSXin Li }
1138*a58d3d2aSXin Li
opus_packet_has_lbrr(const unsigned char packet[],opus_int32 len)1139*a58d3d2aSXin Li int opus_packet_has_lbrr(const unsigned char packet[], opus_int32 len)
1140*a58d3d2aSXin Li {
1141*a58d3d2aSXin Li int ret;
1142*a58d3d2aSXin Li const unsigned char *frames[48];
1143*a58d3d2aSXin Li opus_int16 size[48];
1144*a58d3d2aSXin Li int packet_mode, packet_frame_size, packet_stream_channels;
1145*a58d3d2aSXin Li int nb_frames=1;
1146*a58d3d2aSXin Li int lbrr;
1147*a58d3d2aSXin Li
1148*a58d3d2aSXin Li packet_mode = opus_packet_get_mode(packet);
1149*a58d3d2aSXin Li if (packet_mode == MODE_CELT_ONLY)
1150*a58d3d2aSXin Li return 0;
1151*a58d3d2aSXin Li packet_frame_size = opus_packet_get_samples_per_frame(packet, 48000);
1152*a58d3d2aSXin Li if (packet_frame_size > 960)
1153*a58d3d2aSXin Li nb_frames = packet_frame_size/960;
1154*a58d3d2aSXin Li packet_stream_channels = opus_packet_get_nb_channels(packet);
1155*a58d3d2aSXin Li ret = opus_packet_parse(packet, len, NULL, frames, size, NULL);
1156*a58d3d2aSXin Li if (ret <= 0)
1157*a58d3d2aSXin Li return ret;
1158*a58d3d2aSXin Li lbrr = (frames[0][0] >> (7-nb_frames)) & 0x1;
1159*a58d3d2aSXin Li if (packet_stream_channels == 2)
1160*a58d3d2aSXin Li lbrr = lbrr || ((frames[0][0] >> (6-2*nb_frames)) & 0x1);
1161*a58d3d2aSXin Li return lbrr;
1162*a58d3d2aSXin Li }
1163*a58d3d2aSXin Li
opus_decoder_get_nb_samples(const OpusDecoder * dec,const unsigned char packet[],opus_int32 len)1164*a58d3d2aSXin Li int opus_decoder_get_nb_samples(const OpusDecoder *dec,
1165*a58d3d2aSXin Li const unsigned char packet[], opus_int32 len)
1166*a58d3d2aSXin Li {
1167*a58d3d2aSXin Li return opus_packet_get_nb_samples(packet, len, dec->Fs);
1168*a58d3d2aSXin Li }
1169*a58d3d2aSXin Li
1170*a58d3d2aSXin Li struct OpusDREDDecoder {
1171*a58d3d2aSXin Li #ifdef ENABLE_DRED
1172*a58d3d2aSXin Li RDOVAEDec model;
1173*a58d3d2aSXin Li #endif
1174*a58d3d2aSXin Li int loaded;
1175*a58d3d2aSXin Li int arch;
1176*a58d3d2aSXin Li opus_uint32 magic;
1177*a58d3d2aSXin Li };
1178*a58d3d2aSXin Li
1179*a58d3d2aSXin Li #if defined(ENABLE_DRED) && (defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS))
validate_dred_decoder(OpusDREDDecoder * st)1180*a58d3d2aSXin Li static void validate_dred_decoder(OpusDREDDecoder *st)
1181*a58d3d2aSXin Li {
1182*a58d3d2aSXin Li celt_assert(st->magic == 0xD8EDDEC0);
1183*a58d3d2aSXin Li #ifdef OPUS_ARCHMASK
1184*a58d3d2aSXin Li celt_assert(st->arch >= 0);
1185*a58d3d2aSXin Li celt_assert(st->arch <= OPUS_ARCHMASK);
1186*a58d3d2aSXin Li #endif
1187*a58d3d2aSXin Li }
1188*a58d3d2aSXin Li #define VALIDATE_DRED_DECODER(st) validate_dred_decoder(st)
1189*a58d3d2aSXin Li #else
1190*a58d3d2aSXin Li #define VALIDATE_DRED_DECODER(st)
1191*a58d3d2aSXin Li #endif
1192*a58d3d2aSXin Li
1193*a58d3d2aSXin Li
opus_dred_decoder_get_size(void)1194*a58d3d2aSXin Li int opus_dred_decoder_get_size(void)
1195*a58d3d2aSXin Li {
1196*a58d3d2aSXin Li return sizeof(OpusDREDDecoder);
1197*a58d3d2aSXin Li }
1198*a58d3d2aSXin Li
1199*a58d3d2aSXin Li #ifdef ENABLE_DRED
dred_decoder_load_model(OpusDREDDecoder * dec,const unsigned char * data,int len)1200*a58d3d2aSXin Li int dred_decoder_load_model(OpusDREDDecoder *dec, const unsigned char *data, int len)
1201*a58d3d2aSXin Li {
1202*a58d3d2aSXin Li WeightArray *list;
1203*a58d3d2aSXin Li int ret;
1204*a58d3d2aSXin Li parse_weights(&list, data, len);
1205*a58d3d2aSXin Li ret = init_rdovaedec(&dec->model, list);
1206*a58d3d2aSXin Li opus_free(list);
1207*a58d3d2aSXin Li if (ret == 0) dec->loaded = 1;
1208*a58d3d2aSXin Li return (ret == 0) ? OPUS_OK : OPUS_BAD_ARG;
1209*a58d3d2aSXin Li }
1210*a58d3d2aSXin Li #endif
1211*a58d3d2aSXin Li
opus_dred_decoder_init(OpusDREDDecoder * dec)1212*a58d3d2aSXin Li int opus_dred_decoder_init(OpusDREDDecoder *dec)
1213*a58d3d2aSXin Li {
1214*a58d3d2aSXin Li int ret = 0;
1215*a58d3d2aSXin Li dec->loaded = 0;
1216*a58d3d2aSXin Li #if defined(ENABLE_DRED) && !defined(USE_WEIGHTS_FILE)
1217*a58d3d2aSXin Li ret = init_rdovaedec(&dec->model, rdovaedec_arrays);
1218*a58d3d2aSXin Li if (ret == 0) dec->loaded = 1;
1219*a58d3d2aSXin Li #endif
1220*a58d3d2aSXin Li dec->arch = opus_select_arch();
1221*a58d3d2aSXin Li /* To make sure nobody forgets to init, use a magic number. */
1222*a58d3d2aSXin Li dec->magic = 0xD8EDDEC0;
1223*a58d3d2aSXin Li return (ret == 0) ? OPUS_OK : OPUS_UNIMPLEMENTED;
1224*a58d3d2aSXin Li }
1225*a58d3d2aSXin Li
opus_dred_decoder_create(int * error)1226*a58d3d2aSXin Li OpusDREDDecoder *opus_dred_decoder_create(int *error)
1227*a58d3d2aSXin Li {
1228*a58d3d2aSXin Li int ret;
1229*a58d3d2aSXin Li OpusDREDDecoder *dec;
1230*a58d3d2aSXin Li dec = (OpusDREDDecoder *)opus_alloc(opus_dred_decoder_get_size());
1231*a58d3d2aSXin Li if (dec == NULL)
1232*a58d3d2aSXin Li {
1233*a58d3d2aSXin Li if (error)
1234*a58d3d2aSXin Li *error = OPUS_ALLOC_FAIL;
1235*a58d3d2aSXin Li return NULL;
1236*a58d3d2aSXin Li }
1237*a58d3d2aSXin Li ret = opus_dred_decoder_init(dec);
1238*a58d3d2aSXin Li if (error)
1239*a58d3d2aSXin Li *error = ret;
1240*a58d3d2aSXin Li if (ret != OPUS_OK)
1241*a58d3d2aSXin Li {
1242*a58d3d2aSXin Li opus_free(dec);
1243*a58d3d2aSXin Li dec = NULL;
1244*a58d3d2aSXin Li }
1245*a58d3d2aSXin Li return dec;
1246*a58d3d2aSXin Li }
1247*a58d3d2aSXin Li
opus_dred_decoder_destroy(OpusDREDDecoder * dec)1248*a58d3d2aSXin Li void opus_dred_decoder_destroy(OpusDREDDecoder *dec)
1249*a58d3d2aSXin Li {
1250*a58d3d2aSXin Li if (dec) dec->magic = 0xDE57801D;
1251*a58d3d2aSXin Li opus_free(dec);
1252*a58d3d2aSXin Li }
1253*a58d3d2aSXin Li
opus_dred_decoder_ctl(OpusDREDDecoder * dred_dec,int request,...)1254*a58d3d2aSXin Li int opus_dred_decoder_ctl(OpusDREDDecoder *dred_dec, int request, ...)
1255*a58d3d2aSXin Li {
1256*a58d3d2aSXin Li #ifdef ENABLE_DRED
1257*a58d3d2aSXin Li int ret = OPUS_OK;
1258*a58d3d2aSXin Li va_list ap;
1259*a58d3d2aSXin Li
1260*a58d3d2aSXin Li va_start(ap, request);
1261*a58d3d2aSXin Li (void)dred_dec;
1262*a58d3d2aSXin Li switch (request)
1263*a58d3d2aSXin Li {
1264*a58d3d2aSXin Li # ifdef USE_WEIGHTS_FILE
1265*a58d3d2aSXin Li case OPUS_SET_DNN_BLOB_REQUEST:
1266*a58d3d2aSXin Li {
1267*a58d3d2aSXin Li const unsigned char *data = va_arg(ap, const unsigned char *);
1268*a58d3d2aSXin Li opus_int32 len = va_arg(ap, opus_int32);
1269*a58d3d2aSXin Li if(len<0 || data == NULL)
1270*a58d3d2aSXin Li {
1271*a58d3d2aSXin Li goto bad_arg;
1272*a58d3d2aSXin Li }
1273*a58d3d2aSXin Li return dred_decoder_load_model(dred_dec, data, len);
1274*a58d3d2aSXin Li }
1275*a58d3d2aSXin Li break;
1276*a58d3d2aSXin Li # endif
1277*a58d3d2aSXin Li default:
1278*a58d3d2aSXin Li /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
1279*a58d3d2aSXin Li ret = OPUS_UNIMPLEMENTED;
1280*a58d3d2aSXin Li break;
1281*a58d3d2aSXin Li }
1282*a58d3d2aSXin Li va_end(ap);
1283*a58d3d2aSXin Li return ret;
1284*a58d3d2aSXin Li # ifdef USE_WEIGHTS_FILE
1285*a58d3d2aSXin Li bad_arg:
1286*a58d3d2aSXin Li va_end(ap);
1287*a58d3d2aSXin Li return OPUS_BAD_ARG;
1288*a58d3d2aSXin Li # endif
1289*a58d3d2aSXin Li #else
1290*a58d3d2aSXin Li (void)dred_dec;
1291*a58d3d2aSXin Li (void)request;
1292*a58d3d2aSXin Li return OPUS_UNIMPLEMENTED;
1293*a58d3d2aSXin Li #endif
1294*a58d3d2aSXin Li }
1295*a58d3d2aSXin Li
1296*a58d3d2aSXin Li #ifdef ENABLE_DRED
dred_find_payload(const unsigned char * data,opus_int32 len,const unsigned char ** payload,int * dred_frame_offset)1297*a58d3d2aSXin Li static int dred_find_payload(const unsigned char *data, opus_int32 len, const unsigned char **payload, int *dred_frame_offset)
1298*a58d3d2aSXin Li {
1299*a58d3d2aSXin Li const unsigned char *data0;
1300*a58d3d2aSXin Li int len0;
1301*a58d3d2aSXin Li int frame = 0;
1302*a58d3d2aSXin Li int ret;
1303*a58d3d2aSXin Li const unsigned char *frames[48];
1304*a58d3d2aSXin Li opus_int16 size[48];
1305*a58d3d2aSXin Li int frame_size;
1306*a58d3d2aSXin Li
1307*a58d3d2aSXin Li *payload = NULL;
1308*a58d3d2aSXin Li /* Get the padding section of the packet. */
1309*a58d3d2aSXin Li ret = opus_packet_parse_impl(data, len, 0, NULL, frames, size, NULL, NULL, &data0, &len0);
1310*a58d3d2aSXin Li if (ret < 0)
1311*a58d3d2aSXin Li return ret;
1312*a58d3d2aSXin Li frame_size = opus_packet_get_samples_per_frame(data, 48000);
1313*a58d3d2aSXin Li data = data0;
1314*a58d3d2aSXin Li len = len0;
1315*a58d3d2aSXin Li /* Scan extensions in order until we find the earliest frame with DRED data. */
1316*a58d3d2aSXin Li while (len > 0)
1317*a58d3d2aSXin Li {
1318*a58d3d2aSXin Li opus_int32 header_size;
1319*a58d3d2aSXin Li int id, L;
1320*a58d3d2aSXin Li len0 = len;
1321*a58d3d2aSXin Li data0 = data;
1322*a58d3d2aSXin Li id = *data0 >> 1;
1323*a58d3d2aSXin Li L = *data0 & 0x1;
1324*a58d3d2aSXin Li len = skip_extension(&data, len, &header_size);
1325*a58d3d2aSXin Li if (len < 0)
1326*a58d3d2aSXin Li break;
1327*a58d3d2aSXin Li if (id == 1)
1328*a58d3d2aSXin Li {
1329*a58d3d2aSXin Li if (L==0)
1330*a58d3d2aSXin Li {
1331*a58d3d2aSXin Li frame++;
1332*a58d3d2aSXin Li } else {
1333*a58d3d2aSXin Li frame += data0[1];
1334*a58d3d2aSXin Li }
1335*a58d3d2aSXin Li } else if (id == DRED_EXTENSION_ID)
1336*a58d3d2aSXin Li {
1337*a58d3d2aSXin Li const unsigned char *curr_payload;
1338*a58d3d2aSXin Li opus_int32 curr_payload_len;
1339*a58d3d2aSXin Li curr_payload = data0+header_size;
1340*a58d3d2aSXin Li curr_payload_len = (data-data0)-header_size;
1341*a58d3d2aSXin Li /* DRED position in the packet, in units of 2.5 ms like for the signaled DRED offset. */
1342*a58d3d2aSXin Li *dred_frame_offset = frame*frame_size/120;
1343*a58d3d2aSXin Li #ifdef DRED_EXPERIMENTAL_VERSION
1344*a58d3d2aSXin Li /* Check that temporary extension type and version match.
1345*a58d3d2aSXin Li This check will be removed once extension is finalized. */
1346*a58d3d2aSXin Li if (curr_payload_len > DRED_EXPERIMENTAL_BYTES && curr_payload[0] == 'D' && curr_payload[1] == DRED_EXPERIMENTAL_VERSION) {
1347*a58d3d2aSXin Li *payload = curr_payload+2;
1348*a58d3d2aSXin Li return curr_payload_len-2;
1349*a58d3d2aSXin Li }
1350*a58d3d2aSXin Li #else
1351*a58d3d2aSXin Li if (curr_payload_len > 0) {
1352*a58d3d2aSXin Li *payload = curr_payload;
1353*a58d3d2aSXin Li return curr_payload_len;
1354*a58d3d2aSXin Li }
1355*a58d3d2aSXin Li #endif
1356*a58d3d2aSXin Li }
1357*a58d3d2aSXin Li }
1358*a58d3d2aSXin Li return 0;
1359*a58d3d2aSXin Li }
1360*a58d3d2aSXin Li #endif
1361*a58d3d2aSXin Li
opus_dred_get_size(void)1362*a58d3d2aSXin Li int opus_dred_get_size(void)
1363*a58d3d2aSXin Li {
1364*a58d3d2aSXin Li #ifdef ENABLE_DRED
1365*a58d3d2aSXin Li return sizeof(OpusDRED);
1366*a58d3d2aSXin Li #else
1367*a58d3d2aSXin Li return 0;
1368*a58d3d2aSXin Li #endif
1369*a58d3d2aSXin Li }
1370*a58d3d2aSXin Li
opus_dred_alloc(int * error)1371*a58d3d2aSXin Li OpusDRED *opus_dred_alloc(int *error)
1372*a58d3d2aSXin Li {
1373*a58d3d2aSXin Li #ifdef ENABLE_DRED
1374*a58d3d2aSXin Li OpusDRED *dec;
1375*a58d3d2aSXin Li dec = (OpusDRED *)opus_alloc(opus_dred_get_size());
1376*a58d3d2aSXin Li if (dec == NULL)
1377*a58d3d2aSXin Li {
1378*a58d3d2aSXin Li if (error)
1379*a58d3d2aSXin Li *error = OPUS_ALLOC_FAIL;
1380*a58d3d2aSXin Li return NULL;
1381*a58d3d2aSXin Li }
1382*a58d3d2aSXin Li return dec;
1383*a58d3d2aSXin Li #else
1384*a58d3d2aSXin Li if (error)
1385*a58d3d2aSXin Li *error = OPUS_UNIMPLEMENTED;
1386*a58d3d2aSXin Li return NULL;
1387*a58d3d2aSXin Li #endif
1388*a58d3d2aSXin Li }
1389*a58d3d2aSXin Li
opus_dred_free(OpusDRED * dec)1390*a58d3d2aSXin Li void opus_dred_free(OpusDRED *dec)
1391*a58d3d2aSXin Li {
1392*a58d3d2aSXin Li #ifdef ENABLE_DRED
1393*a58d3d2aSXin Li opus_free(dec);
1394*a58d3d2aSXin Li #else
1395*a58d3d2aSXin Li (void)dec;
1396*a58d3d2aSXin Li #endif
1397*a58d3d2aSXin Li }
1398*a58d3d2aSXin Li
opus_dred_parse(OpusDREDDecoder * dred_dec,OpusDRED * dred,const unsigned char * data,opus_int32 len,opus_int32 max_dred_samples,opus_int32 sampling_rate,int * dred_end,int defer_processing)1399*a58d3d2aSXin Li int opus_dred_parse(OpusDREDDecoder *dred_dec, OpusDRED *dred, const unsigned char *data, opus_int32 len, opus_int32 max_dred_samples, opus_int32 sampling_rate, int *dred_end, int defer_processing)
1400*a58d3d2aSXin Li {
1401*a58d3d2aSXin Li #ifdef ENABLE_DRED
1402*a58d3d2aSXin Li const unsigned char *payload;
1403*a58d3d2aSXin Li opus_int32 payload_len;
1404*a58d3d2aSXin Li int dred_frame_offset=0;
1405*a58d3d2aSXin Li VALIDATE_DRED_DECODER(dred_dec);
1406*a58d3d2aSXin Li if (!dred_dec->loaded) return OPUS_UNIMPLEMENTED;
1407*a58d3d2aSXin Li dred->process_stage = -1;
1408*a58d3d2aSXin Li payload_len = dred_find_payload(data, len, &payload, &dred_frame_offset);
1409*a58d3d2aSXin Li if (payload_len < 0)
1410*a58d3d2aSXin Li return payload_len;
1411*a58d3d2aSXin Li if (payload != NULL)
1412*a58d3d2aSXin Li {
1413*a58d3d2aSXin Li int offset;
1414*a58d3d2aSXin Li int min_feature_frames;
1415*a58d3d2aSXin Li offset = 100*max_dred_samples/sampling_rate;
1416*a58d3d2aSXin Li min_feature_frames = IMIN(2 + offset, 2*DRED_NUM_REDUNDANCY_FRAMES);
1417*a58d3d2aSXin Li dred_ec_decode(dred, payload, payload_len, min_feature_frames, dred_frame_offset);
1418*a58d3d2aSXin Li if (!defer_processing)
1419*a58d3d2aSXin Li opus_dred_process(dred_dec, dred, dred);
1420*a58d3d2aSXin Li if (dred_end) *dred_end = IMAX(0, -dred->dred_offset*sampling_rate/400);
1421*a58d3d2aSXin Li return IMAX(0, dred->nb_latents*sampling_rate/25 - dred->dred_offset* sampling_rate/400);
1422*a58d3d2aSXin Li }
1423*a58d3d2aSXin Li if (dred_end) *dred_end = 0;
1424*a58d3d2aSXin Li return 0;
1425*a58d3d2aSXin Li #else
1426*a58d3d2aSXin Li (void)dred_dec;
1427*a58d3d2aSXin Li (void)dred;
1428*a58d3d2aSXin Li (void)data;
1429*a58d3d2aSXin Li (void)len;
1430*a58d3d2aSXin Li (void)max_dred_samples;
1431*a58d3d2aSXin Li (void)sampling_rate;
1432*a58d3d2aSXin Li (void)defer_processing;
1433*a58d3d2aSXin Li (void)dred_end;
1434*a58d3d2aSXin Li return OPUS_UNIMPLEMENTED;
1435*a58d3d2aSXin Li #endif
1436*a58d3d2aSXin Li }
1437*a58d3d2aSXin Li
opus_dred_process(OpusDREDDecoder * dred_dec,const OpusDRED * src,OpusDRED * dst)1438*a58d3d2aSXin Li int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src, OpusDRED *dst)
1439*a58d3d2aSXin Li {
1440*a58d3d2aSXin Li #ifdef ENABLE_DRED
1441*a58d3d2aSXin Li if (dred_dec == NULL || src == NULL || dst == NULL || (src->process_stage != 1 && src->process_stage != 2))
1442*a58d3d2aSXin Li return OPUS_BAD_ARG;
1443*a58d3d2aSXin Li VALIDATE_DRED_DECODER(dred_dec);
1444*a58d3d2aSXin Li if (!dred_dec->loaded) return OPUS_UNIMPLEMENTED;
1445*a58d3d2aSXin Li if (src != dst)
1446*a58d3d2aSXin Li OPUS_COPY(dst, src, 1);
1447*a58d3d2aSXin Li if (dst->process_stage == 2)
1448*a58d3d2aSXin Li return OPUS_OK;
1449*a58d3d2aSXin Li DRED_rdovae_decode_all(&dred_dec->model, dst->fec_features, dst->state, dst->latents, dst->nb_latents, dred_dec->arch);
1450*a58d3d2aSXin Li dst->process_stage = 2;
1451*a58d3d2aSXin Li return OPUS_OK;
1452*a58d3d2aSXin Li #else
1453*a58d3d2aSXin Li (void)dred_dec;
1454*a58d3d2aSXin Li (void)src;
1455*a58d3d2aSXin Li (void)dst;
1456*a58d3d2aSXin Li return OPUS_UNIMPLEMENTED;
1457*a58d3d2aSXin Li #endif
1458*a58d3d2aSXin Li }
1459*a58d3d2aSXin Li
opus_decoder_dred_decode(OpusDecoder * st,const OpusDRED * dred,opus_int32 dred_offset,opus_int16 * pcm,opus_int32 frame_size)1460*a58d3d2aSXin Li int opus_decoder_dred_decode(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int16 *pcm, opus_int32 frame_size)
1461*a58d3d2aSXin Li {
1462*a58d3d2aSXin Li #ifdef ENABLE_DRED
1463*a58d3d2aSXin Li VARDECL(float, out);
1464*a58d3d2aSXin Li int ret, i;
1465*a58d3d2aSXin Li ALLOC_STACK;
1466*a58d3d2aSXin Li
1467*a58d3d2aSXin Li if(frame_size<=0)
1468*a58d3d2aSXin Li {
1469*a58d3d2aSXin Li RESTORE_STACK;
1470*a58d3d2aSXin Li return OPUS_BAD_ARG;
1471*a58d3d2aSXin Li }
1472*a58d3d2aSXin Li
1473*a58d3d2aSXin Li celt_assert(st->channels == 1 || st->channels == 2);
1474*a58d3d2aSXin Li ALLOC(out, frame_size*st->channels, float);
1475*a58d3d2aSXin Li
1476*a58d3d2aSXin Li ret = opus_decode_native(st, NULL, 0, out, frame_size, 0, 0, NULL, 1, dred, dred_offset);
1477*a58d3d2aSXin Li if (ret > 0)
1478*a58d3d2aSXin Li {
1479*a58d3d2aSXin Li for (i=0;i<ret*st->channels;i++)
1480*a58d3d2aSXin Li pcm[i] = FLOAT2INT16(out[i]);
1481*a58d3d2aSXin Li }
1482*a58d3d2aSXin Li RESTORE_STACK;
1483*a58d3d2aSXin Li return ret;
1484*a58d3d2aSXin Li #else
1485*a58d3d2aSXin Li (void)st;
1486*a58d3d2aSXin Li (void)dred;
1487*a58d3d2aSXin Li (void)dred_offset;
1488*a58d3d2aSXin Li (void)pcm;
1489*a58d3d2aSXin Li (void)frame_size;
1490*a58d3d2aSXin Li return OPUS_UNIMPLEMENTED;
1491*a58d3d2aSXin Li #endif
1492*a58d3d2aSXin Li }
1493*a58d3d2aSXin Li
opus_decoder_dred_decode_float(OpusDecoder * st,const OpusDRED * dred,opus_int32 dred_offset,float * pcm,opus_int32 frame_size)1494*a58d3d2aSXin Li int opus_decoder_dred_decode_float(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, float *pcm, opus_int32 frame_size)
1495*a58d3d2aSXin Li {
1496*a58d3d2aSXin Li #ifdef ENABLE_DRED
1497*a58d3d2aSXin Li if(frame_size<=0)
1498*a58d3d2aSXin Li return OPUS_BAD_ARG;
1499*a58d3d2aSXin Li return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, 0, dred, dred_offset);
1500*a58d3d2aSXin Li #else
1501*a58d3d2aSXin Li (void)st;
1502*a58d3d2aSXin Li (void)dred;
1503*a58d3d2aSXin Li (void)dred_offset;
1504*a58d3d2aSXin Li (void)pcm;
1505*a58d3d2aSXin Li (void)frame_size;
1506*a58d3d2aSXin Li return OPUS_UNIMPLEMENTED;
1507*a58d3d2aSXin Li #endif
1508*a58d3d2aSXin Li }
1509