1 /* Copyright (c) 2007-2008 CSIRO 2 Copyright (c) 2007-2010 Xiph.Org Foundation 3 Copyright (c) 2008 Gregory Maxwell 4 Written by Jean-Marc Valin and Gregory Maxwell */ 5 /* 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions 8 are met: 9 10 - Redistributions of source code must retain the above copyright 11 notice, this list of conditions and the following disclaimer. 12 13 - Redistributions in binary form must reproduce the above copyright 14 notice, this list of conditions and the following disclaimer in the 15 documentation and/or other materials provided with the distribution. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifdef HAVE_CONFIG_H 31 #include "config.h" 32 #endif 33 34 #define CELT_DECODER_C 35 36 #include "cpu_support.h" 37 #include "os_support.h" 38 #include "mdct.h" 39 #include <math.h> 40 #include "celt.h" 41 #include "pitch.h" 42 #include "bands.h" 43 #include "modes.h" 44 #include "entcode.h" 45 #include "quant_bands.h" 46 #include "rate.h" 47 #include "stack_alloc.h" 48 #include "mathops.h" 49 #include "float_cast.h" 50 #include <stdarg.h> 51 #include "celt_lpc.h" 52 #include "vq.h" 53 54 #if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT) 55 #define NORM_ALIASING_HACK 56 #endif 57 /**********************************************************************/ 58 /* */ 59 /* DECODER */ 60 /* */ 61 /**********************************************************************/ 62 #define DECODE_BUFFER_SIZE 2048 63 64 /** Decoder state 65 @brief Decoder state 66 */ 67 struct OpusCustomDecoder { 68 const OpusCustomMode *mode; 69 int overlap; 70 int channels; 71 int stream_channels; 72 73 int downsample; 74 int start, end; 75 int signalling; 76 int arch; 77 78 /* Everything beyond this point gets cleared on a reset */ 79 #define DECODER_RESET_START rng 80 81 opus_uint32 rng; 82 int error; 83 int last_pitch_index; 84 int loss_count; 85 int skip_plc; 86 int postfilter_period; 87 int postfilter_period_old; 88 opus_val16 postfilter_gain; 89 opus_val16 postfilter_gain_old; 90 int postfilter_tapset; 91 int postfilter_tapset_old; 92 93 celt_sig preemph_memD[2]; 94 95 celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */ 96 /* opus_val16 lpc[], Size = channels*LPC_ORDER */ 97 /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */ 98 /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */ 99 /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */ 100 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */ 101 }; 102 103 int celt_decoder_get_size(int channels) 104 { 105 const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); 106 return opus_custom_decoder_get_size(mode, channels); 107 } 108 109 OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels) 110 { 111 int size = sizeof(struct CELTDecoder) 112 + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) 113 + channels*LPC_ORDER*sizeof(opus_val16) 114 + 4*2*mode->nbEBands*sizeof(opus_val16); 115 return size; 116 } 117 118 #ifdef CUSTOM_MODES 119 CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error) 120 { 121 int ret; 122 CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels)); 123 ret = opus_custom_decoder_init(st, mode, channels); 124 if (ret != OPUS_OK) 125 { 126 opus_custom_decoder_destroy(st); 127 st = NULL; 128 } 129 if (error) 130 *error = ret; 131 return st; 132 } 133 #endif /* CUSTOM_MODES */ 134 135 int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels) 136 { 137 int ret; 138 ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); 139 if (ret != OPUS_OK) 140 return ret; 141 st->downsample = resampling_factor(sampling_rate); 142 if (st->downsample==0) 143 return OPUS_BAD_ARG; 144 else 145 return OPUS_OK; 146 } 147 148 OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels) 149 { 150 if (channels < 0 || channels > 2) 151 return OPUS_BAD_ARG; 152 153 if (st==NULL) 154 return OPUS_ALLOC_FAIL; 155 156 OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels)); 157 158 st->mode = mode; 159 st->overlap = mode->overlap; 160 st->stream_channels = st->channels = channels; 161 162 st->downsample = 1; 163 st->start = 0; 164 st->end = st->mode->effEBands; 165 st->signalling = 1; 166 st->arch = opus_select_arch(); 167 168 opus_custom_decoder_ctl(st, OPUS_RESET_STATE); 169 170 return OPUS_OK; 171 } 172 173 #ifdef CUSTOM_MODES 174 void opus_custom_decoder_destroy(CELTDecoder *st) 175 { 176 opus_free(st); 177 } 178 #endif /* CUSTOM_MODES */ 179 180 181 #ifndef RESYNTH 182 static 183 #endif 184 void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, 185 celt_sig *mem, int accum) 186 { 187 int c; 188 int Nd; 189 int apply_downsampling=0; 190 opus_val16 coef0; 191 VARDECL(celt_sig, scratch); 192 SAVE_STACK; 193 #ifndef FIXED_POINT 194 (void)accum; 195 celt_assert(accum==0); 196 #endif 197 ALLOC(scratch, N, celt_sig); 198 coef0 = coef[0]; 199 Nd = N/downsample; 200 c=0; do { 201 int j; 202 celt_sig * OPUS_RESTRICT x; 203 opus_val16 * OPUS_RESTRICT y; 204 celt_sig m = mem[c]; 205 x =in[c]; 206 y = pcm+c; 207 #ifdef CUSTOM_MODES 208 if (coef[1] != 0) 209 { 210 opus_val16 coef1 = coef[1]; 211 opus_val16 coef3 = coef[3]; 212 for (j=0;j<N;j++) 213 { 214 celt_sig tmp = x[j] + m + VERY_SMALL; 215 m = MULT16_32_Q15(coef0, tmp) 216 - MULT16_32_Q15(coef1, x[j]); 217 tmp = SHL32(MULT16_32_Q15(coef3, tmp), 2); 218 scratch[j] = tmp; 219 } 220 apply_downsampling=1; 221 } else 222 #endif 223 if (downsample>1) 224 { 225 /* Shortcut for the standard (non-custom modes) case */ 226 for (j=0;j<N;j++) 227 { 228 celt_sig tmp = x[j] + m + VERY_SMALL; 229 m = MULT16_32_Q15(coef0, tmp); 230 scratch[j] = tmp; 231 } 232 apply_downsampling=1; 233 } else { 234 /* Shortcut for the standard (non-custom modes) case */ 235 #ifdef FIXED_POINT 236 if (accum) 237 { 238 for (j=0;j<N;j++) 239 { 240 celt_sig tmp = x[j] + m + VERY_SMALL; 241 m = MULT16_32_Q15(coef0, tmp); 242 y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(tmp)))); 243 } 244 } else 245 #endif 246 { 247 for (j=0;j<N;j++) 248 { 249 celt_sig tmp = x[j] + m + VERY_SMALL; 250 m = MULT16_32_Q15(coef0, tmp); 251 y[j*C] = SCALEOUT(SIG2WORD16(tmp)); 252 } 253 } 254 } 255 mem[c] = m; 256 257 if (apply_downsampling) 258 { 259 /* Perform down-sampling */ 260 #ifdef FIXED_POINT 261 if (accum) 262 { 263 for (j=0;j<Nd;j++) 264 y[j*C] = SAT16(ADD32(y[j*C], SCALEOUT(SIG2WORD16(scratch[j*downsample])))); 265 } else 266 #endif 267 { 268 for (j=0;j<Nd;j++) 269 y[j*C] = SCALEOUT(SIG2WORD16(scratch[j*downsample])); 270 } 271 } 272 } while (++c<C); 273 RESTORE_STACK; 274 } 275 276 #ifndef RESYNTH 277 static 278 #endif 279 void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], 280 opus_val16 *oldBandE, int start, int effEnd, int C, int CC, 281 int isTransient, int LM, int downsample, 282 int silence, int arch) 283 { 284 int c, i; 285 int M; 286 int b; 287 int B; 288 int N, NB; 289 int shift; 290 int nbEBands; 291 int overlap; 292 VARDECL(celt_sig, freq); 293 SAVE_STACK; 294 295 overlap = mode->overlap; 296 nbEBands = mode->nbEBands; 297 N = mode->shortMdctSize<<LM; 298 ALLOC(freq, N, celt_sig); /**< Interleaved signal MDCTs */ 299 M = 1<<LM; 300 301 if (isTransient) 302 { 303 B = M; 304 NB = mode->shortMdctSize; 305 shift = mode->maxLM; 306 } else { 307 B = 1; 308 NB = mode->shortMdctSize<<LM; 309 shift = mode->maxLM-LM; 310 } 311 312 if (CC==2&&C==1) 313 { 314 /* Copying a mono streams to two channels */ 315 celt_sig *freq2; 316 denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M, 317 downsample, silence); 318 /* Store a temporary copy in the output buffer because the IMDCT destroys its input. */ 319 freq2 = out_syn[1]+overlap/2; 320 OPUS_COPY(freq2, freq, N); 321 for (b=0;b<B;b++) 322 clt_mdct_backward(&mode->mdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch); 323 for (b=0;b<B;b++) 324 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B, arch); 325 } else if (CC==1&&C==2) 326 { 327 /* Downmixing a stereo stream to mono */ 328 celt_sig *freq2; 329 freq2 = out_syn[0]+overlap/2; 330 denormalise_bands(mode, X, freq, oldBandE, start, effEnd, M, 331 downsample, silence); 332 /* Use the output buffer as temp array before downmixing. */ 333 denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M, 334 downsample, silence); 335 for (i=0;i<N;i++) 336 freq[i] = HALF32(ADD32(freq[i],freq2[i])); 337 for (b=0;b<B;b++) 338 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch); 339 } else { 340 /* Normal case (mono or stereo) */ 341 c=0; do { 342 denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M, 343 downsample, silence); 344 for (b=0;b<B;b++) 345 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch); 346 } while (++c<CC); 347 } 348 RESTORE_STACK; 349 } 350 351 static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM, ec_dec *dec) 352 { 353 int i, curr, tf_select; 354 int tf_select_rsv; 355 int tf_changed; 356 int logp; 357 opus_uint32 budget; 358 opus_uint32 tell; 359 360 budget = dec->storage*8; 361 tell = ec_tell(dec); 362 logp = isTransient ? 2 : 4; 363 tf_select_rsv = LM>0 && tell+logp+1<=budget; 364 budget -= tf_select_rsv; 365 tf_changed = curr = 0; 366 for (i=start;i<end;i++) 367 { 368 if (tell+logp<=budget) 369 { 370 curr ^= ec_dec_bit_logp(dec, logp); 371 tell = ec_tell(dec); 372 tf_changed |= curr; 373 } 374 tf_res[i] = curr; 375 logp = isTransient ? 4 : 5; 376 } 377 tf_select = 0; 378 if (tf_select_rsv && 379 tf_select_table[LM][4*isTransient+0+tf_changed] != 380 tf_select_table[LM][4*isTransient+2+tf_changed]) 381 { 382 tf_select = ec_dec_bit_logp(dec, 1); 383 } 384 for (i=start;i<end;i++) 385 { 386 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]]; 387 } 388 } 389 390 /* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save 391 CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The 392 current value corresponds to a pitch of 66.67 Hz. */ 393 #define PLC_PITCH_LAG_MAX (720) 394 /* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a 395 pitch of 480 Hz. */ 396 #define PLC_PITCH_LAG_MIN (100) 397 398 static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch) 399 { 400 int pitch_index; 401 VARDECL( opus_val16, lp_pitch_buf ); 402 SAVE_STACK; 403 ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 ); 404 pitch_downsample(decode_mem, lp_pitch_buf, 405 DECODE_BUFFER_SIZE, C, arch); 406 pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf, 407 DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX, 408 PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, arch); 409 pitch_index = PLC_PITCH_LAG_MAX-pitch_index; 410 RESTORE_STACK; 411 return pitch_index; 412 } 413 414 static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) 415 { 416 int c; 417 int i; 418 const int C = st->channels; 419 celt_sig *decode_mem[2]; 420 celt_sig *out_syn[2]; 421 opus_val16 *lpc; 422 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; 423 const OpusCustomMode *mode; 424 int nbEBands; 425 int overlap; 426 int start; 427 int loss_count; 428 int noise_based; 429 const opus_int16 *eBands; 430 SAVE_STACK; 431 432 mode = st->mode; 433 nbEBands = mode->nbEBands; 434 overlap = mode->overlap; 435 eBands = mode->eBands; 436 437 c=0; do { 438 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); 439 out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N; 440 } while (++c<C); 441 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C); 442 oldBandE = lpc+C*LPC_ORDER; 443 oldLogE = oldBandE + 2*nbEBands; 444 oldLogE2 = oldLogE + 2*nbEBands; 445 backgroundLogE = oldLogE2 + 2*nbEBands; 446 447 loss_count = st->loss_count; 448 start = st->start; 449 noise_based = loss_count >= 5 || start != 0 || st->skip_plc; 450 if (noise_based) 451 { 452 /* Noise-based PLC/CNG */ 453 #ifdef NORM_ALIASING_HACK 454 celt_norm *X; 455 #else 456 VARDECL(celt_norm, X); 457 #endif 458 opus_uint32 seed; 459 int end; 460 int effEnd; 461 opus_val16 decay; 462 end = st->end; 463 effEnd = IMAX(start, IMIN(end, mode->effEBands)); 464 465 #ifdef NORM_ALIASING_HACK 466 /* This is an ugly hack that breaks aliasing rules and would be easily broken, 467 but it saves almost 4kB of stack. */ 468 X = (celt_norm*)(out_syn[C-1]+overlap/2); 469 #else 470 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ 471 #endif 472 473 /* Energy decay */ 474 decay = loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); 475 c=0; do 476 { 477 for (i=start;i<end;i++) 478 oldBandE[c*nbEBands+i] = MAX16(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay); 479 } while (++c<C); 480 seed = st->rng; 481 for (c=0;c<C;c++) 482 { 483 for (i=start;i<effEnd;i++) 484 { 485 int j; 486 int boffs; 487 int blen; 488 boffs = N*c+(eBands[i]<<LM); 489 blen = (eBands[i+1]-eBands[i])<<LM; 490 for (j=0;j<blen;j++) 491 { 492 seed = celt_lcg_rand(seed); 493 X[boffs+j] = (celt_norm)((opus_int32)seed>>20); 494 } 495 renormalise_vector(X+boffs, blen, Q15ONE, st->arch); 496 } 497 } 498 st->rng = seed; 499 500 c=0; do { 501 OPUS_MOVE(decode_mem[c], decode_mem[c]+N, 502 DECODE_BUFFER_SIZE-N+(overlap>>1)); 503 } while (++c<C); 504 505 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch); 506 } else { 507 /* Pitch-based PLC */ 508 const opus_val16 *window; 509 opus_val16 fade = Q15ONE; 510 int pitch_index; 511 VARDECL(opus_val32, etmp); 512 VARDECL(opus_val16, exc); 513 514 if (loss_count == 0) 515 { 516 st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch); 517 } else { 518 pitch_index = st->last_pitch_index; 519 fade = QCONST16(.8f,15); 520 } 521 522 ALLOC(etmp, overlap, opus_val32); 523 ALLOC(exc, MAX_PERIOD, opus_val16); 524 window = mode->window; 525 c=0; do { 526 opus_val16 decay; 527 opus_val16 attenuation; 528 opus_val32 S1=0; 529 celt_sig *buf; 530 int extrapolation_offset; 531 int extrapolation_len; 532 int exc_length; 533 int j; 534 535 buf = decode_mem[c]; 536 for (i=0;i<MAX_PERIOD;i++) { 537 exc[i] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD+i], SIG_SHIFT); 538 } 539 540 if (loss_count == 0) 541 { 542 opus_val32 ac[LPC_ORDER+1]; 543 /* Compute LPC coefficients for the last MAX_PERIOD samples before 544 the first loss so we can work in the excitation-filter domain. */ 545 _celt_autocorr(exc, ac, window, overlap, 546 LPC_ORDER, MAX_PERIOD, st->arch); 547 /* Add a noise floor of -40 dB. */ 548 #ifdef FIXED_POINT 549 ac[0] += SHR32(ac[0],13); 550 #else 551 ac[0] *= 1.0001f; 552 #endif 553 /* Use lag windowing to stabilize the Levinson-Durbin recursion. */ 554 for (i=1;i<=LPC_ORDER;i++) 555 { 556 /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ 557 #ifdef FIXED_POINT 558 ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); 559 #else 560 ac[i] -= ac[i]*(0.008f*0.008f)*i*i; 561 #endif 562 } 563 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER); 564 } 565 /* We want the excitation for 2 pitch periods in order to look for a 566 decaying signal, but we can't get more than MAX_PERIOD. */ 567 exc_length = IMIN(2*pitch_index, MAX_PERIOD); 568 /* Initialize the LPC history with the samples just before the start 569 of the region for which we're computing the excitation. */ 570 { 571 opus_val16 lpc_mem[LPC_ORDER]; 572 for (i=0;i<LPC_ORDER;i++) 573 { 574 lpc_mem[i] = 575 ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT); 576 } 577 /* Compute the excitation for exc_length samples before the loss. */ 578 celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER, 579 exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem, st->arch); 580 } 581 582 /* Check if the waveform is decaying, and if so how fast. 583 We do this to avoid adding energy when concealing in a segment 584 with decaying energy. */ 585 { 586 opus_val32 E1=1, E2=1; 587 int decay_length; 588 #ifdef FIXED_POINT 589 int shift = IMAX(0,2*celt_zlog2(celt_maxabs16(&exc[MAX_PERIOD-exc_length], exc_length))-20); 590 #endif 591 decay_length = exc_length>>1; 592 for (i=0;i<decay_length;i++) 593 { 594 opus_val16 e; 595 e = exc[MAX_PERIOD-decay_length+i]; 596 E1 += SHR32(MULT16_16(e, e), shift); 597 e = exc[MAX_PERIOD-2*decay_length+i]; 598 E2 += SHR32(MULT16_16(e, e), shift); 599 } 600 E1 = MIN32(E1, E2); 601 decay = celt_sqrt(frac_div32(SHR32(E1, 1), E2)); 602 } 603 604 /* Move the decoder memory one frame to the left to give us room to 605 add the data for the new frame. We ignore the overlap that extends 606 past the end of the buffer, because we aren't going to use it. */ 607 OPUS_MOVE(buf, buf+N, DECODE_BUFFER_SIZE-N); 608 609 /* Extrapolate from the end of the excitation with a period of 610 "pitch_index", scaling down each period by an additional factor of 611 "decay". */ 612 extrapolation_offset = MAX_PERIOD-pitch_index; 613 /* We need to extrapolate enough samples to cover a complete MDCT 614 window (including overlap/2 samples on both sides). */ 615 extrapolation_len = N+overlap; 616 /* We also apply fading if this is not the first loss. */ 617 attenuation = MULT16_16_Q15(fade, decay); 618 for (i=j=0;i<extrapolation_len;i++,j++) 619 { 620 opus_val16 tmp; 621 if (j >= pitch_index) { 622 j -= pitch_index; 623 attenuation = MULT16_16_Q15(attenuation, decay); 624 } 625 buf[DECODE_BUFFER_SIZE-N+i] = 626 SHL32(EXTEND32(MULT16_16_Q15(attenuation, 627 exc[extrapolation_offset+j])), SIG_SHIFT); 628 /* Compute the energy of the previously decoded signal whose 629 excitation we're copying. */ 630 tmp = ROUND16( 631 buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j], 632 SIG_SHIFT); 633 S1 += SHR32(MULT16_16(tmp, tmp), 8); 634 } 635 636 { 637 opus_val16 lpc_mem[LPC_ORDER]; 638 /* Copy the last decoded samples (prior to the overlap region) to 639 synthesis filter memory so we can have a continuous signal. */ 640 for (i=0;i<LPC_ORDER;i++) 641 lpc_mem[i] = ROUND16(buf[DECODE_BUFFER_SIZE-N-1-i], SIG_SHIFT); 642 /* Apply the synthesis filter to convert the excitation back into 643 the signal domain. */ 644 celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER, 645 buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER, 646 lpc_mem, st->arch); 647 } 648 649 /* Check if the synthesis energy is higher than expected, which can 650 happen with the signal changes during our window. If so, 651 attenuate. */ 652 { 653 opus_val32 S2=0; 654 for (i=0;i<extrapolation_len;i++) 655 { 656 opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT); 657 S2 += SHR32(MULT16_16(tmp, tmp), 8); 658 } 659 /* This checks for an "explosion" in the synthesis. */ 660 #ifdef FIXED_POINT 661 if (!(S1 > SHR32(S2,2))) 662 #else 663 /* The float test is written this way to catch NaNs in the output 664 of the IIR filter at the same time. */ 665 if (!(S1 > 0.2f*S2)) 666 #endif 667 { 668 for (i=0;i<extrapolation_len;i++) 669 buf[DECODE_BUFFER_SIZE-N+i] = 0; 670 } else if (S1 < S2) 671 { 672 opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1)); 673 for (i=0;i<overlap;i++) 674 { 675 opus_val16 tmp_g = Q15ONE 676 - MULT16_16_Q15(window[i], Q15ONE-ratio); 677 buf[DECODE_BUFFER_SIZE-N+i] = 678 MULT16_32_Q15(tmp_g, buf[DECODE_BUFFER_SIZE-N+i]); 679 } 680 for (i=overlap;i<extrapolation_len;i++) 681 { 682 buf[DECODE_BUFFER_SIZE-N+i] = 683 MULT16_32_Q15(ratio, buf[DECODE_BUFFER_SIZE-N+i]); 684 } 685 } 686 } 687 688 /* Apply the pre-filter to the MDCT overlap for the next frame because 689 the post-filter will be re-applied in the decoder after the MDCT 690 overlap. */ 691 comb_filter(etmp, buf+DECODE_BUFFER_SIZE, 692 st->postfilter_period, st->postfilter_period, overlap, 693 -st->postfilter_gain, -st->postfilter_gain, 694 st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch); 695 696 /* Simulate TDAC on the concealed audio so that it blends with the 697 MDCT of the next frame. */ 698 for (i=0;i<overlap/2;i++) 699 { 700 buf[DECODE_BUFFER_SIZE+i] = 701 MULT16_32_Q15(window[i], etmp[overlap-1-i]) 702 + MULT16_32_Q15(window[overlap-i-1], etmp[i]); 703 } 704 } while (++c<C); 705 } 706 707 st->loss_count = loss_count+1; 708 709 RESTORE_STACK; 710 } 711 712 int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, 713 int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec, int accum) 714 { 715 int c, i, N; 716 int spread_decision; 717 opus_int32 bits; 718 ec_dec _dec; 719 #ifdef NORM_ALIASING_HACK 720 celt_norm *X; 721 #else 722 VARDECL(celt_norm, X); 723 #endif 724 VARDECL(int, fine_quant); 725 VARDECL(int, pulses); 726 VARDECL(int, cap); 727 VARDECL(int, offsets); 728 VARDECL(int, fine_priority); 729 VARDECL(int, tf_res); 730 VARDECL(unsigned char, collapse_masks); 731 celt_sig *decode_mem[2]; 732 celt_sig *out_syn[2]; 733 opus_val16 *lpc; 734 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; 735 736 int shortBlocks; 737 int isTransient; 738 int intra_ener; 739 const int CC = st->channels; 740 int LM, M; 741 int start; 742 int end; 743 int effEnd; 744 int codedBands; 745 int alloc_trim; 746 int postfilter_pitch; 747 opus_val16 postfilter_gain; 748 int intensity=0; 749 int dual_stereo=0; 750 opus_int32 total_bits; 751 opus_int32 balance; 752 opus_int32 tell; 753 int dynalloc_logp; 754 int postfilter_tapset; 755 int anti_collapse_rsv; 756 int anti_collapse_on=0; 757 int silence; 758 int C = st->stream_channels; 759 const OpusCustomMode *mode; 760 int nbEBands; 761 int overlap; 762 const opus_int16 *eBands; 763 ALLOC_STACK; 764 765 mode = st->mode; 766 nbEBands = mode->nbEBands; 767 overlap = mode->overlap; 768 eBands = mode->eBands; 769 start = st->start; 770 end = st->end; 771 frame_size *= st->downsample; 772 773 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC); 774 oldBandE = lpc+CC*LPC_ORDER; 775 oldLogE = oldBandE + 2*nbEBands; 776 oldLogE2 = oldLogE + 2*nbEBands; 777 backgroundLogE = oldLogE2 + 2*nbEBands; 778 779 #ifdef CUSTOM_MODES 780 if (st->signalling && data!=NULL) 781 { 782 int data0=data[0]; 783 /* Convert "standard mode" to Opus header */ 784 if (mode->Fs==48000 && mode->shortMdctSize==120) 785 { 786 data0 = fromOpus(data0); 787 if (data0<0) 788 return OPUS_INVALID_PACKET; 789 } 790 st->end = end = IMAX(1, mode->effEBands-2*(data0>>5)); 791 LM = (data0>>3)&0x3; 792 C = 1 + ((data0>>2)&0x1); 793 data++; 794 len--; 795 if (LM>mode->maxLM) 796 return OPUS_INVALID_PACKET; 797 if (frame_size < mode->shortMdctSize<<LM) 798 return OPUS_BUFFER_TOO_SMALL; 799 else 800 frame_size = mode->shortMdctSize<<LM; 801 } else { 802 #else 803 { 804 #endif 805 for (LM=0;LM<=mode->maxLM;LM++) 806 if (mode->shortMdctSize<<LM==frame_size) 807 break; 808 if (LM>mode->maxLM) 809 return OPUS_BAD_ARG; 810 } 811 M=1<<LM; 812 813 if (len<0 || len>1275 || pcm==NULL) 814 return OPUS_BAD_ARG; 815 816 N = M*mode->shortMdctSize; 817 c=0; do { 818 decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); 819 out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N; 820 } while (++c<CC); 821 822 effEnd = end; 823 if (effEnd > mode->effEBands) 824 effEnd = mode->effEBands; 825 826 if (data == NULL || len<=1) 827 { 828 celt_decode_lost(st, N, LM); 829 deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum); 830 RESTORE_STACK; 831 return frame_size/st->downsample; 832 } 833 834 /* Check if there are at least two packets received consecutively before 835 * turning on the pitch-based PLC */ 836 st->skip_plc = st->loss_count != 0; 837 838 if (dec == NULL) 839 { 840 ec_dec_init(&_dec,(unsigned char*)data,len); 841 dec = &_dec; 842 } 843 844 if (C==1) 845 { 846 for (i=0;i<nbEBands;i++) 847 oldBandE[i]=MAX16(oldBandE[i],oldBandE[nbEBands+i]); 848 } 849 850 total_bits = len*8; 851 tell = ec_tell(dec); 852 853 if (tell >= total_bits) 854 silence = 1; 855 else if (tell==1) 856 silence = ec_dec_bit_logp(dec, 15); 857 else 858 silence = 0; 859 if (silence) 860 { 861 /* Pretend we've read all the remaining bits */ 862 tell = len*8; 863 dec->nbits_total+=tell-ec_tell(dec); 864 } 865 866 postfilter_gain = 0; 867 postfilter_pitch = 0; 868 postfilter_tapset = 0; 869 if (start==0 && tell+16 <= total_bits) 870 { 871 if(ec_dec_bit_logp(dec, 1)) 872 { 873 int qg, octave; 874 octave = ec_dec_uint(dec, 6); 875 postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1; 876 qg = ec_dec_bits(dec, 3); 877 if (ec_tell(dec)+2<=total_bits) 878 postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2); 879 postfilter_gain = QCONST16(.09375f,15)*(qg+1); 880 } 881 tell = ec_tell(dec); 882 } 883 884 if (LM > 0 && tell+3 <= total_bits) 885 { 886 isTransient = ec_dec_bit_logp(dec, 3); 887 tell = ec_tell(dec); 888 } 889 else 890 isTransient = 0; 891 892 if (isTransient) 893 shortBlocks = M; 894 else 895 shortBlocks = 0; 896 897 /* Decode the global flags (first symbols in the stream) */ 898 intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0; 899 /* Get band energies */ 900 unquant_coarse_energy(mode, start, end, oldBandE, 901 intra_ener, dec, C, LM); 902 903 ALLOC(tf_res, nbEBands, int); 904 tf_decode(start, end, isTransient, tf_res, LM, dec); 905 906 tell = ec_tell(dec); 907 spread_decision = SPREAD_NORMAL; 908 if (tell+4 <= total_bits) 909 spread_decision = ec_dec_icdf(dec, spread_icdf, 5); 910 911 ALLOC(cap, nbEBands, int); 912 913 init_caps(mode,cap,LM,C); 914 915 ALLOC(offsets, nbEBands, int); 916 917 dynalloc_logp = 6; 918 total_bits<<=BITRES; 919 tell = ec_tell_frac(dec); 920 for (i=start;i<end;i++) 921 { 922 int width, quanta; 923 int dynalloc_loop_logp; 924 int boost; 925 width = C*(eBands[i+1]-eBands[i])<<LM; 926 /* quanta is 6 bits, but no more than 1 bit/sample 927 and no less than 1/8 bit/sample */ 928 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width)); 929 dynalloc_loop_logp = dynalloc_logp; 930 boost = 0; 931 while (tell+(dynalloc_loop_logp<<BITRES) < total_bits && boost < cap[i]) 932 { 933 int flag; 934 flag = ec_dec_bit_logp(dec, dynalloc_loop_logp); 935 tell = ec_tell_frac(dec); 936 if (!flag) 937 break; 938 boost += quanta; 939 total_bits -= quanta; 940 dynalloc_loop_logp = 1; 941 } 942 offsets[i] = boost; 943 /* Making dynalloc more likely */ 944 if (boost>0) 945 dynalloc_logp = IMAX(2, dynalloc_logp-1); 946 } 947 948 ALLOC(fine_quant, nbEBands, int); 949 alloc_trim = tell+(6<<BITRES) <= total_bits ? 950 ec_dec_icdf(dec, trim_icdf, 7) : 5; 951 952 bits = (((opus_int32)len*8)<<BITRES) - ec_tell_frac(dec) - 1; 953 anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0; 954 bits -= anti_collapse_rsv; 955 956 ALLOC(pulses, nbEBands, int); 957 ALLOC(fine_priority, nbEBands, int); 958 959 codedBands = compute_allocation(mode, start, end, offsets, cap, 960 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, 961 fine_quant, fine_priority, C, LM, dec, 0, 0, 0); 962 963 unquant_fine_energy(mode, start, end, oldBandE, fine_quant, dec, C); 964 965 c=0; do { 966 OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2); 967 } while (++c<CC); 968 969 /* Decode fixed codebook */ 970 ALLOC(collapse_masks, C*nbEBands, unsigned char); 971 972 #ifdef NORM_ALIASING_HACK 973 /* This is an ugly hack that breaks aliasing rules and would be easily broken, 974 but it saves almost 4kB of stack. */ 975 X = (celt_norm*)(out_syn[CC-1]+overlap/2); 976 #else 977 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ 978 #endif 979 980 quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks, 981 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, 982 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, st->arch); 983 984 if (anti_collapse_rsv > 0) 985 { 986 anti_collapse_on = ec_dec_bits(dec, 1); 987 } 988 989 unquant_energy_finalise(mode, start, end, oldBandE, 990 fine_quant, fine_priority, len*8-ec_tell(dec), dec, C); 991 992 if (anti_collapse_on) 993 anti_collapse(mode, X, collapse_masks, LM, C, N, 994 start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng, st->arch); 995 996 if (silence) 997 { 998 for (i=0;i<C*nbEBands;i++) 999 oldBandE[i] = -QCONST16(28.f,DB_SHIFT); 1000 } 1001 1002 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, 1003 C, CC, isTransient, LM, st->downsample, silence, st->arch); 1004 1005 c=0; do { 1006 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); 1007 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD); 1008 comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize, 1009 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset, 1010 mode->window, overlap, st->arch); 1011 if (LM!=0) 1012 comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize, 1013 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset, 1014 mode->window, overlap, st->arch); 1015 1016 } while (++c<CC); 1017 st->postfilter_period_old = st->postfilter_period; 1018 st->postfilter_gain_old = st->postfilter_gain; 1019 st->postfilter_tapset_old = st->postfilter_tapset; 1020 st->postfilter_period = postfilter_pitch; 1021 st->postfilter_gain = postfilter_gain; 1022 st->postfilter_tapset = postfilter_tapset; 1023 if (LM!=0) 1024 { 1025 st->postfilter_period_old = st->postfilter_period; 1026 st->postfilter_gain_old = st->postfilter_gain; 1027 st->postfilter_tapset_old = st->postfilter_tapset; 1028 } 1029 1030 if (C==1) 1031 OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands); 1032 1033 /* In case start or end were to change */ 1034 if (!isTransient) 1035 { 1036 opus_val16 max_background_increase; 1037 OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands); 1038 OPUS_COPY(oldLogE, oldBandE, 2*nbEBands); 1039 /* In normal circumstances, we only allow the noise floor to increase by 1040 up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB 1041 increase for each update.*/ 1042 if (st->loss_count < 10) 1043 max_background_increase = M*QCONST16(0.001f,DB_SHIFT); 1044 else 1045 max_background_increase = QCONST16(1.f,DB_SHIFT); 1046 for (i=0;i<2*nbEBands;i++) 1047 backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]); 1048 } else { 1049 for (i=0;i<2*nbEBands;i++) 1050 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); 1051 } 1052 c=0; do 1053 { 1054 for (i=0;i<start;i++) 1055 { 1056 oldBandE[c*nbEBands+i]=0; 1057 oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); 1058 } 1059 for (i=end;i<nbEBands;i++) 1060 { 1061 oldBandE[c*nbEBands+i]=0; 1062 oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); 1063 } 1064 } while (++c<2); 1065 st->rng = dec->rng; 1066 1067 deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum); 1068 st->loss_count = 0; 1069 RESTORE_STACK; 1070 if (ec_tell(dec) > 8*len) 1071 return OPUS_INTERNAL_ERROR; 1072 if(ec_get_error(dec)) 1073 st->error = 1; 1074 return frame_size/st->downsample; 1075 } 1076 1077 1078 #ifdef CUSTOM_MODES 1079 1080 #ifdef FIXED_POINT 1081 int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size) 1082 { 1083 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0); 1084 } 1085 1086 #ifndef DISABLE_FLOAT_API 1087 int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size) 1088 { 1089 int j, ret, C, N; 1090 VARDECL(opus_int16, out); 1091 ALLOC_STACK; 1092 1093 if (pcm==NULL) 1094 return OPUS_BAD_ARG; 1095 1096 C = st->channels; 1097 N = frame_size; 1098 1099 ALLOC(out, C*N, opus_int16); 1100 ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0); 1101 if (ret>0) 1102 for (j=0;j<C*ret;j++) 1103 pcm[j]=out[j]*(1.f/32768.f); 1104 1105 RESTORE_STACK; 1106 return ret; 1107 } 1108 #endif /* DISABLE_FLOAT_API */ 1109 1110 #else 1111 1112 int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size) 1113 { 1114 return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL, 0); 1115 } 1116 1117 int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size) 1118 { 1119 int j, ret, C, N; 1120 VARDECL(celt_sig, out); 1121 ALLOC_STACK; 1122 1123 if (pcm==NULL) 1124 return OPUS_BAD_ARG; 1125 1126 C = st->channels; 1127 N = frame_size; 1128 ALLOC(out, C*N, celt_sig); 1129 1130 ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL, 0); 1131 1132 if (ret>0) 1133 for (j=0;j<C*ret;j++) 1134 pcm[j] = FLOAT2INT16 (out[j]); 1135 1136 RESTORE_STACK; 1137 return ret; 1138 } 1139 1140 #endif 1141 #endif /* CUSTOM_MODES */ 1142 1143 int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...) 1144 { 1145 va_list ap; 1146 1147 va_start(ap, request); 1148 switch (request) 1149 { 1150 case CELT_SET_START_BAND_REQUEST: 1151 { 1152 opus_int32 value = va_arg(ap, opus_int32); 1153 if (value<0 || value>=st->mode->nbEBands) 1154 goto bad_arg; 1155 st->start = value; 1156 } 1157 break; 1158 case CELT_SET_END_BAND_REQUEST: 1159 { 1160 opus_int32 value = va_arg(ap, opus_int32); 1161 if (value<1 || value>st->mode->nbEBands) 1162 goto bad_arg; 1163 st->end = value; 1164 } 1165 break; 1166 case CELT_SET_CHANNELS_REQUEST: 1167 { 1168 opus_int32 value = va_arg(ap, opus_int32); 1169 if (value<1 || value>2) 1170 goto bad_arg; 1171 st->stream_channels = value; 1172 } 1173 break; 1174 case CELT_GET_AND_CLEAR_ERROR_REQUEST: 1175 { 1176 opus_int32 *value = va_arg(ap, opus_int32*); 1177 if (value==NULL) 1178 goto bad_arg; 1179 *value=st->error; 1180 st->error = 0; 1181 } 1182 break; 1183 case OPUS_GET_LOOKAHEAD_REQUEST: 1184 { 1185 opus_int32 *value = va_arg(ap, opus_int32*); 1186 if (value==NULL) 1187 goto bad_arg; 1188 *value = st->overlap/st->downsample; 1189 } 1190 break; 1191 case OPUS_RESET_STATE: 1192 { 1193 int i; 1194 opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2; 1195 lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels); 1196 oldBandE = lpc+st->channels*LPC_ORDER; 1197 oldLogE = oldBandE + 2*st->mode->nbEBands; 1198 oldLogE2 = oldLogE + 2*st->mode->nbEBands; 1199 OPUS_CLEAR((char*)&st->DECODER_RESET_START, 1200 opus_custom_decoder_get_size(st->mode, st->channels)- 1201 ((char*)&st->DECODER_RESET_START - (char*)st)); 1202 for (i=0;i<2*st->mode->nbEBands;i++) 1203 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); 1204 st->skip_plc = 1; 1205 } 1206 break; 1207 case OPUS_GET_PITCH_REQUEST: 1208 { 1209 opus_int32 *value = va_arg(ap, opus_int32*); 1210 if (value==NULL) 1211 goto bad_arg; 1212 *value = st->postfilter_period; 1213 } 1214 break; 1215 case CELT_GET_MODE_REQUEST: 1216 { 1217 const CELTMode ** value = va_arg(ap, const CELTMode**); 1218 if (value==0) 1219 goto bad_arg; 1220 *value=st->mode; 1221 } 1222 break; 1223 case CELT_SET_SIGNALLING_REQUEST: 1224 { 1225 opus_int32 value = va_arg(ap, opus_int32); 1226 st->signalling = value; 1227 } 1228 break; 1229 case OPUS_GET_FINAL_RANGE_REQUEST: 1230 { 1231 opus_uint32 * value = va_arg(ap, opus_uint32 *); 1232 if (value==0) 1233 goto bad_arg; 1234 *value=st->rng; 1235 } 1236 break; 1237 default: 1238 goto bad_request; 1239 } 1240 va_end(ap); 1241 return OPUS_OK; 1242 bad_arg: 1243 va_end(ap); 1244 return OPUS_BAD_ARG; 1245 bad_request: 1246 va_end(ap); 1247 return OPUS_UNIMPLEMENTED; 1248 } 1249