Coverage Report

Created: 2026-04-01 07:42

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