unsafe_libopus/celt/
celt_decoder.rs

1use crate::celt::bands::{
2    anti_collapse, celt_lcg_rand, denormalise_bands, quant_all_bands, SPREAD_NORMAL,
3};
4use crate::opus_custom_decoder_ctl;
5
6pub mod arch_h {
7    pub type opus_val16 = f32;
8    pub type opus_val32 = f32;
9    pub type celt_sig = f32;
10    pub type celt_norm = f32;
11    pub type celt_ener = f32;
12    pub const Q15ONE: f32 = 1.0f32;
13    pub const VERY_SMALL: f32 = 1e-30f32;
14    pub const CELT_SIG_SCALE: f32 = 32768.0f32;
15}
16
17pub mod cpu_support_h {
18    #[inline]
19    pub unsafe fn opus_select_arch() -> i32 {
20        return 0;
21    }
22}
23pub mod stddef_h {
24    pub const NULL: i32 = 0;
25}
26pub use self::arch_h::{
27    celt_ener, celt_norm, celt_sig, opus_val16, opus_val32, CELT_SIG_SCALE, Q15ONE, VERY_SMALL,
28};
29pub use self::cpu_support_h::opus_select_arch;
30pub use self::stddef_h::NULL;
31use crate::celt::celt::{
32    comb_filter, init_caps, resampling_factor, spread_icdf, tapset_icdf, tf_select_table, trim_icdf,
33};
34use crate::celt::celt::{
35    CELT_GET_AND_CLEAR_ERROR_REQUEST, CELT_GET_MODE_REQUEST, CELT_SET_CHANNELS_REQUEST,
36    CELT_SET_END_BAND_REQUEST, CELT_SET_SIGNALLING_REQUEST, CELT_SET_START_BAND_REQUEST,
37};
38use crate::celt::celt_lpc::{_celt_autocorr, _celt_lpc, celt_fir_c, celt_iir, LPC_ORDER};
39use crate::celt::entcode::{ec_get_error, ec_tell, ec_tell_frac, BITRES};
40use crate::celt::entdec::{
41    ec_dec, ec_dec_bit_logp, ec_dec_bits, ec_dec_icdf, ec_dec_init, ec_dec_uint,
42};
43use crate::celt::mathops::celt_sqrt;
44use crate::celt::mdct::clt_mdct_backward_c;
45use crate::celt::modes::{opus_custom_mode_create, OpusCustomMode, MAX_PERIOD};
46use crate::celt::pitch::{pitch_downsample, pitch_search};
47use crate::celt::quant_bands::{
48    unquant_coarse_energy, unquant_energy_finalise, unquant_fine_energy,
49};
50use crate::celt::rate::clt_compute_allocation;
51use crate::celt::vq::renormalise_vector;
52use crate::externs::{memcpy, memmove, memset};
53use crate::src::opus_defines::{
54    OPUS_ALLOC_FAIL, OPUS_BAD_ARG, OPUS_GET_FINAL_RANGE_REQUEST, OPUS_GET_LOOKAHEAD_REQUEST,
55    OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_PITCH_REQUEST, OPUS_INTERNAL_ERROR,
56    OPUS_OK, OPUS_RESET_STATE, OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_UNIMPLEMENTED,
57};
58use crate::varargs::VarArgs;
59
60#[derive(Copy, Clone)]
61#[repr(C)]
62pub struct OpusCustomDecoder {
63    pub mode: *const OpusCustomMode,
64    pub overlap: i32,
65    pub channels: i32,
66    pub stream_channels: i32,
67    pub downsample: i32,
68    pub start: i32,
69    pub end: i32,
70    pub signalling: i32,
71    pub disable_inv: i32,
72    pub arch: i32,
73    pub rng: u32,
74    pub error: i32,
75    pub last_pitch_index: i32,
76    pub loss_count: i32,
77    pub skip_plc: i32,
78    pub postfilter_period: i32,
79    pub postfilter_period_old: i32,
80    pub postfilter_gain: opus_val16,
81    pub postfilter_gain_old: opus_val16,
82    pub postfilter_tapset: i32,
83    pub postfilter_tapset_old: i32,
84    pub preemph_memD: [celt_sig; 2],
85    pub _decode_mem: [celt_sig; 1],
86}
87pub const PLC_PITCH_LAG_MAX: i32 = 720;
88pub const PLC_PITCH_LAG_MIN: i32 = 100;
89pub const DECODE_BUFFER_SIZE: i32 = 2048;
90pub unsafe fn validate_celt_decoder(st: *mut OpusCustomDecoder) {
91    assert!(
92        (*st).mode == opus_custom_mode_create(48000, 960, 0 as *mut i32) as *const OpusCustomMode
93    );
94    assert!((*st).overlap == 120);
95    assert!((*st).channels == 1 || (*st).channels == 2);
96    assert!((*st).stream_channels == 1 || (*st).stream_channels == 2);
97    assert!((*st).downsample > 0);
98    assert!((*st).start == 0 || (*st).start == 17);
99    assert!((*st).start < (*st).end);
100    assert!((*st).end <= 21);
101    assert!((*st).arch >= 0);
102    assert!((*st).arch <= 0);
103    assert!((*st).last_pitch_index <= 720);
104    assert!((*st).last_pitch_index >= 100 || (*st).last_pitch_index == 0);
105    assert!((*st).postfilter_period < 1024);
106    assert!((*st).postfilter_period >= 15 || (*st).postfilter_period == 0);
107    assert!((*st).postfilter_period_old < 1024);
108    assert!((*st).postfilter_period_old >= 15 || (*st).postfilter_period_old == 0);
109    assert!((*st).postfilter_tapset <= 2);
110    assert!((*st).postfilter_tapset >= 0);
111    assert!((*st).postfilter_tapset_old <= 2);
112    assert!((*st).postfilter_tapset_old >= 0);
113}
114pub unsafe fn celt_decoder_get_size(channels: i32) -> i32 {
115    let mode: *const OpusCustomMode = opus_custom_mode_create(48000, 960, NULL as *mut i32);
116    return opus_custom_decoder_get_size(mode, channels);
117}
118#[inline]
119unsafe fn opus_custom_decoder_get_size(mode: *const OpusCustomMode, channels: i32) -> i32 {
120    let size: i32 = (::core::mem::size_of::<OpusCustomDecoder>() as u64)
121        .wrapping_add(
122            ((channels * (DECODE_BUFFER_SIZE + (*mode).overlap) - 1) as u64)
123                .wrapping_mul(::core::mem::size_of::<celt_sig>() as u64),
124        )
125        .wrapping_add(
126            ((channels * LPC_ORDER) as u64)
127                .wrapping_mul(::core::mem::size_of::<opus_val16>() as u64),
128        )
129        .wrapping_add(
130            ((4 * 2 * (*mode).nbEBands) as u64)
131                .wrapping_mul(::core::mem::size_of::<opus_val16>() as u64),
132        ) as i32;
133    return size;
134}
135pub unsafe fn celt_decoder_init(
136    st: *mut OpusCustomDecoder,
137    sampling_rate: i32,
138    channels: i32,
139) -> i32 {
140    let mut ret: i32 = 0;
141    ret = opus_custom_decoder_init(
142        st,
143        opus_custom_mode_create(48000, 960, NULL as *mut i32),
144        channels,
145    );
146    if ret != OPUS_OK {
147        return ret;
148    }
149    (*st).downsample = resampling_factor(sampling_rate);
150    if (*st).downsample == 0 {
151        return OPUS_BAD_ARG;
152    } else {
153        return OPUS_OK;
154    };
155}
156#[inline]
157unsafe fn opus_custom_decoder_init(
158    st: *mut OpusCustomDecoder,
159    mode: *const OpusCustomMode,
160    channels: i32,
161) -> i32 {
162    if channels < 0 || channels > 2 {
163        return OPUS_BAD_ARG;
164    }
165    if st.is_null() {
166        return OPUS_ALLOC_FAIL;
167    }
168    memset(
169        st as *mut i8 as *mut core::ffi::c_void,
170        0,
171        (opus_custom_decoder_get_size(mode, channels) as u64)
172            .wrapping_mul(::core::mem::size_of::<i8>() as u64),
173    );
174    (*st).mode = mode;
175    (*st).overlap = (*mode).overlap;
176    (*st).channels = channels;
177    (*st).stream_channels = (*st).channels;
178    (*st).downsample = 1;
179    (*st).start = 0;
180    (*st).end = (*(*st).mode).effEBands;
181    (*st).signalling = 1;
182    (*st).disable_inv = (channels == 1) as i32;
183    (*st).arch = opus_select_arch();
184    opus_custom_decoder_ctl!(st, OPUS_RESET_STATE);
185    return OPUS_OK;
186}
187unsafe fn deemphasis_stereo_simple(
188    in_0: *mut *mut celt_sig,
189    pcm: *mut opus_val16,
190    N: i32,
191    coef0: opus_val16,
192    mem: *mut celt_sig,
193) {
194    let mut x0: *mut celt_sig = 0 as *mut celt_sig;
195    let mut x1: *mut celt_sig = 0 as *mut celt_sig;
196    let mut m0: celt_sig = 0.;
197    let mut m1: celt_sig = 0.;
198    let mut j: i32 = 0;
199    x0 = *in_0.offset(0 as isize);
200    x1 = *in_0.offset(1 as isize);
201    m0 = *mem.offset(0 as isize);
202    m1 = *mem.offset(1 as isize);
203    j = 0;
204    while j < N {
205        let mut tmp0: celt_sig = 0.;
206        let mut tmp1: celt_sig = 0.;
207        tmp0 = *x0.offset(j as isize) + VERY_SMALL + m0;
208        tmp1 = *x1.offset(j as isize) + VERY_SMALL + m1;
209        m0 = coef0 * tmp0;
210        m1 = coef0 * tmp1;
211        *pcm.offset((2 * j) as isize) = tmp0 * (1 as f32 / CELT_SIG_SCALE);
212        *pcm.offset((2 * j + 1) as isize) = tmp1 * (1 as f32 / CELT_SIG_SCALE);
213        j += 1;
214    }
215    *mem.offset(0 as isize) = m0;
216    *mem.offset(1 as isize) = m1;
217}
218unsafe fn deemphasis(
219    in_0: *mut *mut celt_sig,
220    pcm: *mut opus_val16,
221    N: i32,
222    C: i32,
223    downsample: i32,
224    coef: *const opus_val16,
225    mem: *mut celt_sig,
226    accum: i32,
227) {
228    let mut c: i32 = 0;
229    let mut Nd: i32 = 0;
230    let mut apply_downsampling: i32 = 0;
231    let mut coef0: opus_val16 = 0.;
232    if downsample == 1 && C == 2 && accum == 0 {
233        deemphasis_stereo_simple(in_0, pcm, N, *coef.offset(0 as isize), mem);
234        return;
235    }
236    assert!(accum == 0);
237    let vla = N as usize;
238    let mut scratch: Vec<celt_sig> = ::std::vec::from_elem(0., vla);
239    coef0 = *coef.offset(0 as isize);
240    Nd = N / downsample;
241    c = 0;
242    loop {
243        let mut j: i32 = 0;
244        let mut x: *mut celt_sig = 0 as *mut celt_sig;
245        let mut y: *mut opus_val16 = 0 as *mut opus_val16;
246        let mut m: celt_sig = *mem.offset(c as isize);
247        x = *in_0.offset(c as isize);
248        y = pcm.offset(c as isize);
249        if downsample > 1 {
250            j = 0;
251            while j < N {
252                let tmp: celt_sig = *x.offset(j as isize) + VERY_SMALL + m;
253                m = coef0 * tmp;
254                *scratch.as_mut_ptr().offset(j as isize) = tmp;
255                j += 1;
256            }
257            apply_downsampling = 1;
258        } else {
259            j = 0;
260            while j < N {
261                let tmp_0: celt_sig = *x.offset(j as isize) + VERY_SMALL + m;
262                m = coef0 * tmp_0;
263                *y.offset((j * C) as isize) = tmp_0 * (1 as f32 / CELT_SIG_SCALE);
264                j += 1;
265            }
266        }
267        *mem.offset(c as isize) = m;
268        if apply_downsampling != 0 {
269            j = 0;
270            while j < Nd {
271                *y.offset((j * C) as isize) =
272                    *scratch.as_mut_ptr().offset((j * downsample) as isize)
273                        * (1 as f32 / CELT_SIG_SCALE);
274                j += 1;
275            }
276        }
277        c += 1;
278        if !(c < C) {
279            break;
280        }
281    }
282}
283unsafe fn celt_synthesis(
284    mode: *const OpusCustomMode,
285    X: *mut celt_norm,
286    out_syn: *mut *mut celt_sig,
287    oldBandE: *mut opus_val16,
288    start: i32,
289    effEnd: i32,
290    C: i32,
291    CC: i32,
292    isTransient: i32,
293    LM: i32,
294    downsample: i32,
295    silence: i32,
296    arch: i32,
297) {
298    let mut c: i32 = 0;
299    let mut i: i32 = 0;
300    let mut M: i32 = 0;
301    let mut b: i32 = 0;
302    let mut B: i32 = 0;
303    let mut N: i32 = 0;
304    let mut NB: i32 = 0;
305    let mut shift: i32 = 0;
306    let mut nbEBands: i32 = 0;
307    let mut overlap: i32 = 0;
308    overlap = (*mode).overlap;
309    nbEBands = (*mode).nbEBands;
310    N = (*mode).shortMdctSize << LM;
311    let vla = N as usize;
312    let mut freq: Vec<celt_sig> = ::std::vec::from_elem(0., vla);
313    M = (1) << LM;
314    if isTransient != 0 {
315        B = M;
316        NB = (*mode).shortMdctSize;
317        shift = (*mode).maxLM;
318    } else {
319        B = 1;
320        NB = (*mode).shortMdctSize << LM;
321        shift = (*mode).maxLM - LM;
322    }
323    if CC == 2 && C == 1 {
324        let mut freq2: *mut celt_sig = 0 as *mut celt_sig;
325        denormalise_bands(
326            mode,
327            X,
328            freq.as_mut_ptr(),
329            oldBandE,
330            start,
331            effEnd,
332            M,
333            downsample,
334            silence,
335        );
336        freq2 = (*out_syn.offset(1 as isize)).offset((overlap / 2) as isize);
337        memcpy(
338            freq2 as *mut core::ffi::c_void,
339            freq.as_mut_ptr() as *const core::ffi::c_void,
340            (N as u64)
341                .wrapping_mul(::core::mem::size_of::<celt_sig>() as u64)
342                .wrapping_add((0 * freq2.offset_from(freq.as_mut_ptr()) as i64) as u64),
343        );
344        b = 0;
345        while b < B {
346            clt_mdct_backward_c(
347                &(*mode).mdct,
348                &mut *freq2.offset(b as isize),
349                (*out_syn.offset(0 as isize)).offset((NB * b) as isize),
350                (*mode).window,
351                overlap,
352                shift,
353                B,
354                arch,
355            );
356            b += 1;
357        }
358        b = 0;
359        while b < B {
360            clt_mdct_backward_c(
361                &(*mode).mdct,
362                &mut *freq.as_mut_ptr().offset(b as isize),
363                (*out_syn.offset(1 as isize)).offset((NB * b) as isize),
364                (*mode).window,
365                overlap,
366                shift,
367                B,
368                arch,
369            );
370            b += 1;
371        }
372    } else if CC == 1 && C == 2 {
373        let mut freq2_0: *mut celt_sig = 0 as *mut celt_sig;
374        freq2_0 = (*out_syn.offset(0 as isize)).offset((overlap / 2) as isize);
375        denormalise_bands(
376            mode,
377            X,
378            freq.as_mut_ptr(),
379            oldBandE,
380            start,
381            effEnd,
382            M,
383            downsample,
384            silence,
385        );
386        denormalise_bands(
387            mode,
388            X.offset(N as isize),
389            freq2_0,
390            oldBandE.offset(nbEBands as isize),
391            start,
392            effEnd,
393            M,
394            downsample,
395            silence,
396        );
397        i = 0;
398        while i < N {
399            *freq.as_mut_ptr().offset(i as isize) = 0.5f32 * *freq.as_mut_ptr().offset(i as isize)
400                + 0.5f32 * *freq2_0.offset(i as isize);
401            i += 1;
402        }
403        b = 0;
404        while b < B {
405            clt_mdct_backward_c(
406                &(*mode).mdct,
407                &mut *freq.as_mut_ptr().offset(b as isize),
408                (*out_syn.offset(0 as isize)).offset((NB * b) as isize),
409                (*mode).window,
410                overlap,
411                shift,
412                B,
413                arch,
414            );
415            b += 1;
416        }
417    } else {
418        c = 0;
419        loop {
420            denormalise_bands(
421                mode,
422                X.offset((c * N) as isize),
423                freq.as_mut_ptr(),
424                oldBandE.offset((c * nbEBands) as isize),
425                start,
426                effEnd,
427                M,
428                downsample,
429                silence,
430            );
431            b = 0;
432            while b < B {
433                clt_mdct_backward_c(
434                    &(*mode).mdct,
435                    &mut *freq.as_mut_ptr().offset(b as isize),
436                    (*out_syn.offset(c as isize)).offset((NB * b) as isize),
437                    (*mode).window,
438                    overlap,
439                    shift,
440                    B,
441                    arch,
442                );
443                b += 1;
444            }
445            c += 1;
446            if !(c < CC) {
447                break;
448            }
449        }
450    }
451    c = 0;
452    loop {
453        i = 0;
454        while i < N {
455            *(*out_syn.offset(c as isize)).offset(i as isize) =
456                *(*out_syn.offset(c as isize)).offset(i as isize);
457            i += 1;
458        }
459        c += 1;
460        if !(c < CC) {
461            break;
462        }
463    }
464}
465unsafe fn tf_decode(
466    start: i32,
467    end: i32,
468    isTransient: i32,
469    tf_res: *mut i32,
470    LM: i32,
471    dec: &mut ec_dec,
472) {
473    let mut i: i32 = 0;
474    let mut curr: i32 = 0;
475    let mut tf_select: i32 = 0;
476    let mut tf_select_rsv: i32 = 0;
477    let mut tf_changed: i32 = 0;
478    let mut logp: i32 = 0;
479    let mut budget: u32 = 0;
480    let mut tell: u32 = 0;
481    budget = dec.storage.wrapping_mul(8);
482    tell = ec_tell(dec) as u32;
483    logp = if isTransient != 0 { 2 } else { 4 };
484    tf_select_rsv = (LM > 0 && tell.wrapping_add(logp as u32).wrapping_add(1) <= budget) as i32;
485    budget = budget.wrapping_sub(tf_select_rsv as u32);
486    curr = 0;
487    tf_changed = curr;
488    i = start;
489    while i < end {
490        if tell.wrapping_add(logp as u32) <= budget {
491            curr ^= ec_dec_bit_logp(dec, logp as u32);
492            tell = ec_tell(dec) as u32;
493            tf_changed |= curr;
494        }
495        *tf_res.offset(i as isize) = curr;
496        logp = if isTransient != 0 { 4 } else { 5 };
497        i += 1;
498    }
499    tf_select = 0;
500    if tf_select_rsv != 0
501        && tf_select_table[LM as usize][(4 * isTransient + 0 + tf_changed) as usize] as i32
502            != tf_select_table[LM as usize][(4 * isTransient + 2 + tf_changed) as usize] as i32
503    {
504        tf_select = ec_dec_bit_logp(dec, 1);
505    }
506    i = start;
507    while i < end {
508        *tf_res.offset(i as isize) = tf_select_table[LM as usize]
509            [(4 * isTransient + 2 * tf_select + *tf_res.offset(i as isize)) as usize]
510            as i32;
511        i += 1;
512    }
513}
514unsafe fn celt_plc_pitch_search(decode_mem: *mut *mut celt_sig, C: i32, arch: i32) -> i32 {
515    let mut pitch_index: i32 = 0;
516    let mut lp_pitch_buf: [opus_val16; 1024] = [0.; 1024];
517    pitch_downsample(
518        decode_mem as *mut *mut celt_sig,
519        lp_pitch_buf.as_mut_ptr(),
520        DECODE_BUFFER_SIZE,
521        C,
522        arch,
523    );
524    pitch_search(
525        lp_pitch_buf
526            .as_mut_ptr()
527            .offset((PLC_PITCH_LAG_MAX >> 1) as isize),
528        lp_pitch_buf.as_mut_ptr(),
529        DECODE_BUFFER_SIZE - PLC_PITCH_LAG_MAX,
530        PLC_PITCH_LAG_MAX - PLC_PITCH_LAG_MIN,
531        &mut pitch_index,
532        arch,
533    );
534    pitch_index = PLC_PITCH_LAG_MAX - pitch_index;
535    return pitch_index;
536}
537unsafe fn celt_decode_lost(st: *mut OpusCustomDecoder, N: i32, LM: i32) {
538    let mut c: i32 = 0;
539    let mut i: i32 = 0;
540    let C: i32 = (*st).channels;
541    let mut decode_mem: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2];
542    let mut out_syn: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2];
543    let mut lpc: *mut opus_val16 = 0 as *mut opus_val16;
544    let mut oldBandE: *mut opus_val16 = 0 as *mut opus_val16;
545    let mut oldLogE: *mut opus_val16 = 0 as *mut opus_val16;
546    let mut oldLogE2: *mut opus_val16 = 0 as *mut opus_val16;
547    let mut backgroundLogE: *mut opus_val16 = 0 as *mut opus_val16;
548    let mut mode: *const OpusCustomMode = 0 as *const OpusCustomMode;
549    let mut nbEBands: i32 = 0;
550    let mut overlap: i32 = 0;
551    let mut start: i32 = 0;
552    let mut loss_count: i32 = 0;
553    let mut noise_based: i32 = 0;
554    let mut eBands: *const i16 = 0 as *const i16;
555    mode = (*st).mode;
556    nbEBands = (*mode).nbEBands;
557    overlap = (*mode).overlap;
558    eBands = (*mode).eBands;
559    c = 0;
560    loop {
561        decode_mem[c as usize] = ((*st)._decode_mem)
562            .as_mut_ptr()
563            .offset((c * (DECODE_BUFFER_SIZE + overlap)) as isize);
564        out_syn[c as usize] = (decode_mem[c as usize])
565            .offset(DECODE_BUFFER_SIZE as isize)
566            .offset(-(N as isize));
567        c += 1;
568        if !(c < C) {
569            break;
570        }
571    }
572    lpc = ((*st)._decode_mem)
573        .as_mut_ptr()
574        .offset(((DECODE_BUFFER_SIZE + overlap) * C) as isize) as *mut opus_val16;
575    oldBandE = lpc.offset((C * LPC_ORDER) as isize);
576    oldLogE = oldBandE.offset((2 * nbEBands) as isize);
577    oldLogE2 = oldLogE.offset((2 * nbEBands) as isize);
578    backgroundLogE = oldLogE2.offset((2 * nbEBands) as isize);
579    loss_count = (*st).loss_count;
580    start = (*st).start;
581    noise_based = (loss_count >= 5 || start != 0 || (*st).skip_plc != 0) as i32;
582    if noise_based != 0 {
583        let mut seed: u32 = 0;
584        let mut end: i32 = 0;
585        let mut effEnd: i32 = 0;
586        let mut decay: opus_val16 = 0.;
587        end = (*st).end;
588        effEnd = if start
589            > (if end < (*mode).effEBands {
590                end
591            } else {
592                (*mode).effEBands
593            }) {
594            start
595        } else if end < (*mode).effEBands {
596            end
597        } else {
598            (*mode).effEBands
599        };
600        let vla = (C * N) as usize;
601        let mut X: Vec<celt_norm> = ::std::vec::from_elem(0., vla);
602        decay = if loss_count == 0 { 1.5f32 } else { 0.5f32 };
603        c = 0;
604        loop {
605            i = start;
606            while i < end {
607                *oldBandE.offset((c * nbEBands + i) as isize) = if *backgroundLogE
608                    .offset((c * nbEBands + i) as isize)
609                    > *oldBandE.offset((c * nbEBands + i) as isize) - decay
610                {
611                    *backgroundLogE.offset((c * nbEBands + i) as isize)
612                } else {
613                    *oldBandE.offset((c * nbEBands + i) as isize) - decay
614                };
615                i += 1;
616            }
617            c += 1;
618            if !(c < C) {
619                break;
620            }
621        }
622        seed = (*st).rng;
623        c = 0;
624        while c < C {
625            i = start;
626            while i < effEnd {
627                let mut j: i32 = 0;
628                let mut boffs: i32 = 0;
629                let mut blen: i32 = 0;
630                boffs = N * c + ((*eBands.offset(i as isize) as i32) << LM);
631                blen = (*eBands.offset((i + 1) as isize) as i32
632                    - *eBands.offset(i as isize) as i32)
633                    << LM;
634                j = 0;
635                while j < blen {
636                    seed = celt_lcg_rand(seed);
637                    *X.as_mut_ptr().offset((boffs + j) as isize) = (seed as i32 >> 20) as celt_norm;
638                    j += 1;
639                }
640                renormalise_vector(
641                    X.as_mut_ptr().offset(boffs as isize),
642                    blen,
643                    Q15ONE,
644                    (*st).arch,
645                );
646                i += 1;
647            }
648            c += 1;
649        }
650        (*st).rng = seed;
651        c = 0;
652        loop {
653            memmove(
654                decode_mem[c as usize] as *mut core::ffi::c_void,
655                (decode_mem[c as usize]).offset(N as isize) as *const core::ffi::c_void,
656                ((2048 - N + (overlap >> 1)) as u64)
657                    .wrapping_mul(::core::mem::size_of::<celt_sig>() as u64)
658                    .wrapping_add(
659                        (0 * (decode_mem[c as usize])
660                            .offset_from((decode_mem[c as usize]).offset(N as isize))
661                            as i64) as u64,
662                    ),
663            );
664            c += 1;
665            if !(c < C) {
666                break;
667            }
668        }
669        celt_synthesis(
670            mode,
671            X.as_mut_ptr(),
672            out_syn.as_mut_ptr(),
673            oldBandE,
674            start,
675            effEnd,
676            C,
677            C,
678            0,
679            LM,
680            (*st).downsample,
681            0,
682            (*st).arch,
683        );
684    } else {
685        let mut exc_length: i32 = 0;
686        let mut window: *const opus_val16 = 0 as *const opus_val16;
687        let mut exc: *mut opus_val16 = 0 as *mut opus_val16;
688        let mut fade: opus_val16 = Q15ONE;
689        let mut pitch_index: i32 = 0;
690        if loss_count == 0 {
691            pitch_index = celt_plc_pitch_search(decode_mem.as_mut_ptr(), C, (*st).arch);
692            (*st).last_pitch_index = pitch_index;
693        } else {
694            pitch_index = (*st).last_pitch_index;
695            fade = 0.8f32;
696        }
697        exc_length = if 2 * pitch_index < 1024 {
698            2 * pitch_index
699        } else {
700            1024
701        };
702        let vla_0 = overlap as usize;
703        let mut etmp: Vec<opus_val32> = ::std::vec::from_elem(0., vla_0);
704        let mut _exc: [opus_val16; 1048] = [0.; 1048];
705        let vla_1 = exc_length as usize;
706        let mut fir_tmp: Vec<opus_val16> = ::std::vec::from_elem(0., vla_1);
707        exc = _exc.as_mut_ptr().offset(LPC_ORDER as isize);
708        window = (*mode).window;
709        c = 0;
710        loop {
711            let mut decay_0: opus_val16 = 0.;
712            let mut attenuation: opus_val16 = 0.;
713            let mut S1: opus_val32 = 0 as opus_val32;
714            let mut buf: *mut celt_sig = 0 as *mut celt_sig;
715            let mut extrapolation_offset: i32 = 0;
716            let mut extrapolation_len: i32 = 0;
717            let mut j_0: i32 = 0;
718            buf = decode_mem[c as usize];
719            i = 0;
720            while i < MAX_PERIOD + LPC_ORDER {
721                *exc.offset((i - LPC_ORDER) as isize) =
722                    *buf.offset((2048 - 1024 - 24 + i) as isize);
723                i += 1;
724            }
725            if loss_count == 0 {
726                let mut ac: [opus_val32; 25] = [0.; 25];
727                _celt_autocorr(
728                    exc,
729                    ac.as_mut_ptr(),
730                    window,
731                    overlap,
732                    LPC_ORDER,
733                    MAX_PERIOD,
734                    (*st).arch,
735                );
736                ac[0 as usize] *= 1.0001f32;
737                i = 1;
738                while i <= LPC_ORDER {
739                    ac[i as usize] -= ac[i as usize] * (0.008f32 * 0.008f32) * i as f32 * i as f32;
740                    i += 1;
741                }
742                _celt_lpc(
743                    lpc.offset((c * LPC_ORDER) as isize),
744                    ac.as_mut_ptr(),
745                    LPC_ORDER,
746                );
747            }
748            celt_fir_c(
749                exc.offset(1024 as isize).offset(-(exc_length as isize)),
750                lpc.offset((c * 24) as isize),
751                fir_tmp.as_mut_ptr(),
752                exc_length,
753                24,
754                (*st).arch,
755            );
756            memcpy(
757                exc.offset(1024 as isize).offset(-(exc_length as isize)) as *mut core::ffi::c_void,
758                fir_tmp.as_mut_ptr() as *const core::ffi::c_void,
759                (exc_length as u64)
760                    .wrapping_mul(::core::mem::size_of::<opus_val16>() as u64)
761                    .wrapping_add(
762                        (0 * exc
763                            .offset(1024 as isize)
764                            .offset(-(exc_length as isize))
765                            .offset_from(fir_tmp.as_mut_ptr()) as i64)
766                            as u64,
767                    ),
768            );
769            let mut E1: opus_val32 = 1 as opus_val32;
770            let mut E2: opus_val32 = 1 as opus_val32;
771            let mut decay_length: i32 = 0;
772            decay_length = exc_length >> 1;
773            i = 0;
774            while i < decay_length {
775                let mut e: opus_val16 = 0.;
776                e = *exc.offset((MAX_PERIOD - decay_length + i) as isize);
777                E1 += e * e;
778                e = *exc.offset((MAX_PERIOD - 2 * decay_length + i) as isize);
779                E2 += e * e;
780                i += 1;
781            }
782            E1 = if E1 < E2 { E1 } else { E2 };
783            decay_0 = celt_sqrt(E1 / E2);
784            memmove(
785                buf as *mut core::ffi::c_void,
786                buf.offset(N as isize) as *const core::ffi::c_void,
787                ((2048 - N) as u64)
788                    .wrapping_mul(::core::mem::size_of::<celt_sig>() as u64)
789                    .wrapping_add((0 * buf.offset_from(buf.offset(N as isize)) as i64) as u64),
790            );
791            extrapolation_offset = MAX_PERIOD - pitch_index;
792            extrapolation_len = N + overlap;
793            attenuation = fade * decay_0;
794            j_0 = 0;
795            i = j_0;
796            while i < extrapolation_len {
797                let mut tmp: opus_val16 = 0.;
798                if j_0 >= pitch_index {
799                    j_0 -= pitch_index;
800                    attenuation = attenuation * decay_0;
801                }
802                *buf.offset((DECODE_BUFFER_SIZE - N + i) as isize) =
803                    attenuation * *exc.offset((extrapolation_offset + j_0) as isize);
804                tmp = *buf.offset((2048 - 1024 - N + extrapolation_offset + j_0) as isize);
805                S1 += tmp * tmp;
806                i += 1;
807                j_0 += 1;
808            }
809            let mut lpc_mem: [opus_val16; 24] = [0.; 24];
810            i = 0;
811            while i < LPC_ORDER {
812                lpc_mem[i as usize] = *buf.offset((2048 - N - 1 - i) as isize);
813                i += 1;
814            }
815            celt_iir(
816                buf.offset(DECODE_BUFFER_SIZE as isize)
817                    .offset(-(N as isize)),
818                lpc.offset((c * LPC_ORDER) as isize),
819                buf.offset(DECODE_BUFFER_SIZE as isize)
820                    .offset(-(N as isize)),
821                extrapolation_len,
822                LPC_ORDER,
823                lpc_mem.as_mut_ptr(),
824                (*st).arch,
825            );
826            let mut S2: opus_val32 = 0 as opus_val32;
827            i = 0;
828            while i < extrapolation_len {
829                let tmp_0: opus_val16 = *buf.offset((2048 - N + i) as isize);
830                S2 += tmp_0 * tmp_0;
831                i += 1;
832            }
833            if !(S1 > 0.2f32 * S2) {
834                i = 0;
835                while i < extrapolation_len {
836                    *buf.offset((DECODE_BUFFER_SIZE - N + i) as isize) = 0 as celt_sig;
837                    i += 1;
838                }
839            } else if S1 < S2 {
840                let ratio: opus_val16 = celt_sqrt((S1 + 1 as f32) / (S2 + 1 as f32));
841                i = 0;
842                while i < overlap {
843                    let tmp_g: opus_val16 = Q15ONE - *window.offset(i as isize) * (1.0f32 - ratio);
844                    *buf.offset((DECODE_BUFFER_SIZE - N + i) as isize) =
845                        tmp_g * *buf.offset((2048 - N + i) as isize);
846                    i += 1;
847                }
848                i = overlap;
849                while i < extrapolation_len {
850                    *buf.offset((DECODE_BUFFER_SIZE - N + i) as isize) =
851                        ratio * *buf.offset((2048 - N + i) as isize);
852                    i += 1;
853                }
854            }
855            comb_filter(
856                etmp.as_mut_ptr(),
857                buf.offset(DECODE_BUFFER_SIZE as isize),
858                (*st).postfilter_period,
859                (*st).postfilter_period,
860                overlap,
861                -(*st).postfilter_gain,
862                -(*st).postfilter_gain,
863                (*st).postfilter_tapset,
864                (*st).postfilter_tapset,
865                NULL as *const opus_val16,
866                0,
867                (*st).arch,
868            );
869            i = 0;
870            while i < overlap / 2 {
871                *buf.offset((DECODE_BUFFER_SIZE + i) as isize) = *window.offset(i as isize)
872                    * *etmp.as_mut_ptr().offset((overlap - 1 - i) as isize)
873                    + *window.offset((overlap - i - 1) as isize)
874                        * *etmp.as_mut_ptr().offset(i as isize);
875                i += 1;
876            }
877            c += 1;
878            if !(c < C) {
879                break;
880            }
881        }
882    }
883    (*st).loss_count = loss_count + 1;
884}
885pub unsafe fn celt_decode_with_ec(
886    st: *mut OpusCustomDecoder,
887    data: *const u8,
888    len: i32,
889    pcm: *mut opus_val16,
890    mut frame_size: i32,
891    dec: Option<&mut ec_dec>,
892    accum: i32,
893) -> i32 {
894    let mut c: i32 = 0;
895    let mut i: i32 = 0;
896    let mut N: i32 = 0;
897    let mut spread_decision: i32 = 0;
898    let mut bits: i32 = 0;
899    let mut _dec: ec_dec = ec_dec {
900        buf: &mut [],
901        storage: 0,
902        end_offs: 0,
903        end_window: 0,
904        nend_bits: 0,
905        nbits_total: 0,
906        offs: 0,
907        rng: 0,
908        val: 0,
909        ext: 0,
910        rem: 0,
911        error: 0,
912    };
913    let mut decode_mem: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2];
914    let mut out_syn: [*mut celt_sig; 2] = [0 as *mut celt_sig; 2];
915    let mut lpc: *mut opus_val16 = 0 as *mut opus_val16;
916    let mut oldBandE: *mut opus_val16 = 0 as *mut opus_val16;
917    let mut oldLogE: *mut opus_val16 = 0 as *mut opus_val16;
918    let mut oldLogE2: *mut opus_val16 = 0 as *mut opus_val16;
919    let mut backgroundLogE: *mut opus_val16 = 0 as *mut opus_val16;
920    let mut shortBlocks: i32 = 0;
921    let mut isTransient: i32 = 0;
922    let mut intra_ener: i32 = 0;
923    let CC: i32 = (*st).channels;
924    let mut LM: i32 = 0;
925    let mut M: i32 = 0;
926    let mut start: i32 = 0;
927    let mut end: i32 = 0;
928    let mut effEnd: i32 = 0;
929    let mut codedBands: i32 = 0;
930    let mut alloc_trim: i32 = 0;
931    let mut postfilter_pitch: i32 = 0;
932    let mut postfilter_gain: opus_val16 = 0.;
933    let mut intensity: i32 = 0;
934    let mut dual_stereo: i32 = 0;
935    let mut total_bits: i32 = 0;
936    let mut balance: i32 = 0;
937    let mut tell: i32 = 0;
938    let mut dynalloc_logp: i32 = 0;
939    let mut postfilter_tapset: i32 = 0;
940    let mut anti_collapse_rsv: i32 = 0;
941    let mut anti_collapse_on: i32 = 0;
942    let mut silence: i32 = 0;
943    let C: i32 = (*st).stream_channels;
944    let mut mode: *const OpusCustomMode = 0 as *const OpusCustomMode;
945    let mut nbEBands: i32 = 0;
946    let mut overlap: i32 = 0;
947    let mut eBands: *const i16 = 0 as *const i16;
948    validate_celt_decoder(st);
949    mode = (*st).mode;
950    nbEBands = (*mode).nbEBands;
951    overlap = (*mode).overlap;
952    eBands = (*mode).eBands;
953    start = (*st).start;
954    end = (*st).end;
955    frame_size *= (*st).downsample;
956    lpc = ((*st)._decode_mem)
957        .as_mut_ptr()
958        .offset(((DECODE_BUFFER_SIZE + overlap) * CC) as isize) as *mut opus_val16;
959    oldBandE = lpc.offset((CC * LPC_ORDER) as isize);
960    oldLogE = oldBandE.offset((2 * nbEBands) as isize);
961    oldLogE2 = oldLogE.offset((2 * nbEBands) as isize);
962    backgroundLogE = oldLogE2.offset((2 * nbEBands) as isize);
963    LM = 0;
964    while LM <= (*mode).maxLM {
965        if (*mode).shortMdctSize << LM == frame_size {
966            break;
967        }
968        LM += 1;
969    }
970    if LM > (*mode).maxLM {
971        return OPUS_BAD_ARG;
972    }
973    M = (1) << LM;
974    if len < 0 || len > 1275 || pcm.is_null() {
975        return OPUS_BAD_ARG;
976    }
977    N = M * (*mode).shortMdctSize;
978    c = 0;
979    loop {
980        decode_mem[c as usize] = ((*st)._decode_mem)
981            .as_mut_ptr()
982            .offset((c * (DECODE_BUFFER_SIZE + overlap)) as isize);
983        out_syn[c as usize] = (decode_mem[c as usize])
984            .offset(DECODE_BUFFER_SIZE as isize)
985            .offset(-(N as isize));
986        c += 1;
987        if !(c < CC) {
988            break;
989        }
990    }
991    effEnd = end;
992    if effEnd > (*mode).effEBands {
993        effEnd = (*mode).effEBands;
994    }
995    if data.is_null() || len <= 1 {
996        celt_decode_lost(st, N, LM);
997        deemphasis(
998            out_syn.as_mut_ptr(),
999            pcm,
1000            N,
1001            CC,
1002            (*st).downsample,
1003            ((*mode).preemph).as_ptr(),
1004            ((*st).preemph_memD).as_mut_ptr(),
1005            accum,
1006        );
1007        return frame_size / (*st).downsample;
1008    }
1009    (*st).skip_plc = ((*st).loss_count != 0) as i32;
1010    let dec = if let Some(dec) = dec {
1011        dec
1012    } else {
1013        _dec = ec_dec_init(std::slice::from_raw_parts_mut(
1014            data as *mut u8,
1015            len as usize,
1016        ));
1017        &mut _dec
1018    };
1019    if C == 1 {
1020        i = 0;
1021        while i < nbEBands {
1022            *oldBandE.offset(i as isize) =
1023                if *oldBandE.offset(i as isize) > *oldBandE.offset((nbEBands + i) as isize) {
1024                    *oldBandE.offset(i as isize)
1025                } else {
1026                    *oldBandE.offset((nbEBands + i) as isize)
1027                };
1028            i += 1;
1029        }
1030    }
1031    total_bits = len * 8;
1032    tell = ec_tell(dec);
1033    if tell >= total_bits {
1034        silence = 1;
1035    } else if tell == 1 {
1036        silence = ec_dec_bit_logp(dec, 15);
1037    } else {
1038        silence = 0;
1039    }
1040    if silence != 0 {
1041        tell = len * 8;
1042        (*dec).nbits_total += tell - ec_tell(dec);
1043    }
1044    postfilter_gain = 0 as opus_val16;
1045    postfilter_pitch = 0;
1046    postfilter_tapset = 0;
1047    if start == 0 && tell + 16 <= total_bits {
1048        if ec_dec_bit_logp(dec, 1) != 0 {
1049            let mut qg: i32 = 0;
1050            let mut octave: i32 = 0;
1051            octave = ec_dec_uint(dec, 6) as i32;
1052            postfilter_pitch = (((16) << octave) as u32)
1053                .wrapping_add(ec_dec_bits(dec, (4 + octave) as u32))
1054                .wrapping_sub(1) as i32;
1055            qg = ec_dec_bits(dec, 3) as i32;
1056            if ec_tell(dec) + 2 <= total_bits {
1057                postfilter_tapset = ec_dec_icdf(dec, &tapset_icdf, 2);
1058            }
1059            postfilter_gain = 0.09375f32 * (qg + 1) as f32;
1060        }
1061        tell = ec_tell(dec);
1062    }
1063    if LM > 0 && tell + 3 <= total_bits {
1064        isTransient = ec_dec_bit_logp(dec, 3);
1065        tell = ec_tell(dec);
1066    } else {
1067        isTransient = 0;
1068    }
1069    if isTransient != 0 {
1070        shortBlocks = M;
1071    } else {
1072        shortBlocks = 0;
1073    }
1074    intra_ener = if tell + 3 <= total_bits {
1075        ec_dec_bit_logp(dec, 3)
1076    } else {
1077        0
1078    };
1079    unquant_coarse_energy(mode, start, end, oldBandE, intra_ener, dec, C, LM);
1080    let vla = nbEBands as usize;
1081    let mut tf_res: Vec<i32> = ::std::vec::from_elem(0, vla);
1082    tf_decode(start, end, isTransient, tf_res.as_mut_ptr(), LM, dec);
1083    tell = ec_tell(dec);
1084    spread_decision = SPREAD_NORMAL;
1085    if tell + 4 <= total_bits {
1086        spread_decision = ec_dec_icdf(dec, &spread_icdf, 5);
1087    }
1088    let vla_0 = nbEBands as usize;
1089    let mut cap: Vec<i32> = ::std::vec::from_elem(0, vla_0);
1090    init_caps(mode, cap.as_mut_ptr(), LM, C);
1091    let vla_1 = nbEBands as usize;
1092    let mut offsets: Vec<i32> = ::std::vec::from_elem(0, vla_1);
1093    dynalloc_logp = 6;
1094    total_bits <<= BITRES;
1095    tell = ec_tell_frac(dec) as i32;
1096    i = start;
1097    while i < end {
1098        let mut width: i32 = 0;
1099        let mut quanta: i32 = 0;
1100        let mut dynalloc_loop_logp: i32 = 0;
1101        let mut boost: i32 = 0;
1102        width =
1103            C * (*eBands.offset((i + 1) as isize) as i32 - *eBands.offset(i as isize) as i32) << LM;
1104        quanta = if (width << 3) < (if (6) << 3 > width { (6) << 3 } else { width }) {
1105            width << 3
1106        } else if (6) << 3 > width {
1107            (6) << 3
1108        } else {
1109            width
1110        };
1111        dynalloc_loop_logp = dynalloc_logp;
1112        boost = 0;
1113        while tell + (dynalloc_loop_logp << BITRES) < total_bits
1114            && boost < *cap.as_mut_ptr().offset(i as isize)
1115        {
1116            let mut flag: i32 = 0;
1117            flag = ec_dec_bit_logp(dec, dynalloc_loop_logp as u32);
1118            tell = ec_tell_frac(dec) as i32;
1119            if flag == 0 {
1120                break;
1121            }
1122            boost += quanta;
1123            total_bits -= quanta;
1124            dynalloc_loop_logp = 1;
1125        }
1126        *offsets.as_mut_ptr().offset(i as isize) = boost;
1127        if boost > 0 {
1128            dynalloc_logp = if 2 > dynalloc_logp - 1 {
1129                2
1130            } else {
1131                dynalloc_logp - 1
1132            };
1133        }
1134        i += 1;
1135    }
1136    let vla_2 = nbEBands as usize;
1137    let mut fine_quant: Vec<i32> = ::std::vec::from_elem(0, vla_2);
1138    alloc_trim = if tell + ((6) << BITRES) <= total_bits {
1139        ec_dec_icdf(dec, &trim_icdf, 7)
1140    } else {
1141        5
1142    };
1143    bits = (((len * 8) << BITRES) as u32)
1144        .wrapping_sub(ec_tell_frac(dec))
1145        .wrapping_sub(1) as i32;
1146    anti_collapse_rsv = if isTransient != 0 && LM >= 2 && bits >= (LM + 2) << BITRES {
1147        (1) << BITRES
1148    } else {
1149        0
1150    };
1151    bits -= anti_collapse_rsv;
1152    let vla_3 = nbEBands as usize;
1153    let mut pulses: Vec<i32> = ::std::vec::from_elem(0, vla_3);
1154    let vla_4 = nbEBands as usize;
1155    let mut fine_priority: Vec<i32> = ::std::vec::from_elem(0, vla_4);
1156    codedBands = clt_compute_allocation(
1157        mode,
1158        start,
1159        end,
1160        offsets.as_mut_ptr(),
1161        cap.as_mut_ptr(),
1162        alloc_trim,
1163        &mut intensity,
1164        &mut dual_stereo,
1165        bits,
1166        &mut balance,
1167        pulses.as_mut_ptr(),
1168        fine_quant.as_mut_ptr(),
1169        fine_priority.as_mut_ptr(),
1170        C,
1171        LM,
1172        dec,
1173        0,
1174        0,
1175        0,
1176    );
1177    unquant_fine_energy(mode, start, end, oldBandE, fine_quant.as_mut_ptr(), dec, C);
1178    c = 0;
1179    loop {
1180        memmove(
1181            decode_mem[c as usize] as *mut core::ffi::c_void,
1182            (decode_mem[c as usize]).offset(N as isize) as *const core::ffi::c_void,
1183            ((2048 - N + overlap / 2) as u64)
1184                .wrapping_mul(::core::mem::size_of::<celt_sig>() as u64)
1185                .wrapping_add(
1186                    (0 * (decode_mem[c as usize])
1187                        .offset_from((decode_mem[c as usize]).offset(N as isize))
1188                        as i64) as u64,
1189                ),
1190        );
1191        c += 1;
1192        if !(c < CC) {
1193            break;
1194        }
1195    }
1196    let vla_5 = (C * nbEBands) as usize;
1197    let mut collapse_masks: Vec<u8> = ::std::vec::from_elem(0, vla_5);
1198    let vla_6 = (C * N) as usize;
1199    let mut X: Vec<celt_norm> = ::std::vec::from_elem(0., vla_6);
1200    quant_all_bands(
1201        0,
1202        mode,
1203        start,
1204        end,
1205        X.as_mut_ptr(),
1206        if C == 2 {
1207            X.as_mut_ptr().offset(N as isize)
1208        } else {
1209            NULL as *mut celt_norm
1210        },
1211        collapse_masks.as_mut_ptr(),
1212        NULL as *const celt_ener,
1213        pulses.as_mut_ptr(),
1214        shortBlocks,
1215        spread_decision,
1216        dual_stereo,
1217        intensity,
1218        tf_res.as_mut_ptr(),
1219        len * ((8) << BITRES) - anti_collapse_rsv,
1220        balance,
1221        dec,
1222        LM,
1223        codedBands,
1224        &mut (*st).rng,
1225        0,
1226        (*st).arch,
1227        (*st).disable_inv,
1228    );
1229    if anti_collapse_rsv > 0 {
1230        anti_collapse_on = ec_dec_bits(dec, 1) as i32;
1231    }
1232    unquant_energy_finalise(
1233        mode,
1234        start,
1235        end,
1236        oldBandE,
1237        fine_quant.as_mut_ptr(),
1238        fine_priority.as_mut_ptr(),
1239        len * 8 - ec_tell(dec),
1240        dec,
1241        C,
1242    );
1243    if anti_collapse_on != 0 {
1244        anti_collapse(
1245            mode,
1246            X.as_mut_ptr(),
1247            collapse_masks.as_mut_ptr(),
1248            LM,
1249            C,
1250            N,
1251            start,
1252            end,
1253            oldBandE,
1254            oldLogE,
1255            oldLogE2,
1256            pulses.as_mut_ptr(),
1257            (*st).rng,
1258            (*st).arch,
1259        );
1260    }
1261    if silence != 0 {
1262        i = 0;
1263        while i < C * nbEBands {
1264            *oldBandE.offset(i as isize) = -28.0f32;
1265            i += 1;
1266        }
1267    }
1268    celt_synthesis(
1269        mode,
1270        X.as_mut_ptr(),
1271        out_syn.as_mut_ptr(),
1272        oldBandE,
1273        start,
1274        effEnd,
1275        C,
1276        CC,
1277        isTransient,
1278        LM,
1279        (*st).downsample,
1280        silence,
1281        (*st).arch,
1282    );
1283    c = 0;
1284    loop {
1285        (*st).postfilter_period = if (*st).postfilter_period > 15 {
1286            (*st).postfilter_period
1287        } else {
1288            15
1289        };
1290        (*st).postfilter_period_old = if (*st).postfilter_period_old > 15 {
1291            (*st).postfilter_period_old
1292        } else {
1293            15
1294        };
1295        comb_filter(
1296            out_syn[c as usize],
1297            out_syn[c as usize],
1298            (*st).postfilter_period_old,
1299            (*st).postfilter_period,
1300            (*mode).shortMdctSize,
1301            (*st).postfilter_gain_old,
1302            (*st).postfilter_gain,
1303            (*st).postfilter_tapset_old,
1304            (*st).postfilter_tapset,
1305            (*mode).window,
1306            overlap,
1307            (*st).arch,
1308        );
1309        if LM != 0 {
1310            comb_filter(
1311                (out_syn[c as usize]).offset((*mode).shortMdctSize as isize),
1312                (out_syn[c as usize]).offset((*mode).shortMdctSize as isize),
1313                (*st).postfilter_period,
1314                postfilter_pitch,
1315                N - (*mode).shortMdctSize,
1316                (*st).postfilter_gain,
1317                postfilter_gain,
1318                (*st).postfilter_tapset,
1319                postfilter_tapset,
1320                (*mode).window,
1321                overlap,
1322                (*st).arch,
1323            );
1324        }
1325        c += 1;
1326        if !(c < CC) {
1327            break;
1328        }
1329    }
1330    (*st).postfilter_period_old = (*st).postfilter_period;
1331    (*st).postfilter_gain_old = (*st).postfilter_gain;
1332    (*st).postfilter_tapset_old = (*st).postfilter_tapset;
1333    (*st).postfilter_period = postfilter_pitch;
1334    (*st).postfilter_gain = postfilter_gain;
1335    (*st).postfilter_tapset = postfilter_tapset;
1336    if LM != 0 {
1337        (*st).postfilter_period_old = (*st).postfilter_period;
1338        (*st).postfilter_gain_old = (*st).postfilter_gain;
1339        (*st).postfilter_tapset_old = (*st).postfilter_tapset;
1340    }
1341    if C == 1 {
1342        memcpy(
1343            &mut *oldBandE.offset(nbEBands as isize) as *mut opus_val16 as *mut core::ffi::c_void,
1344            oldBandE as *const core::ffi::c_void,
1345            (nbEBands as u64)
1346                .wrapping_mul(::core::mem::size_of::<opus_val16>() as u64)
1347                .wrapping_add(
1348                    (0 * (&mut *oldBandE.offset(nbEBands as isize) as *mut opus_val16)
1349                        .offset_from(oldBandE) as i64) as u64,
1350                ),
1351        );
1352    }
1353    if isTransient == 0 {
1354        let mut max_background_increase: opus_val16 = 0.;
1355        memcpy(
1356            oldLogE2 as *mut core::ffi::c_void,
1357            oldLogE as *const core::ffi::c_void,
1358            ((2 * nbEBands) as u64)
1359                .wrapping_mul(::core::mem::size_of::<opus_val16>() as u64)
1360                .wrapping_add((0 * oldLogE2.offset_from(oldLogE) as i64) as u64),
1361        );
1362        memcpy(
1363            oldLogE as *mut core::ffi::c_void,
1364            oldBandE as *const core::ffi::c_void,
1365            ((2 * nbEBands) as u64)
1366                .wrapping_mul(::core::mem::size_of::<opus_val16>() as u64)
1367                .wrapping_add((0 * oldLogE.offset_from(oldBandE) as i64) as u64),
1368        );
1369        if (*st).loss_count < 10 {
1370            max_background_increase = M as f32 * 0.001f32;
1371        } else {
1372            max_background_increase = 1.0f32;
1373        }
1374        i = 0;
1375        while i < 2 * nbEBands {
1376            *backgroundLogE.offset(i as isize) = if *backgroundLogE.offset(i as isize)
1377                + max_background_increase
1378                < *oldBandE.offset(i as isize)
1379            {
1380                *backgroundLogE.offset(i as isize) + max_background_increase
1381            } else {
1382                *oldBandE.offset(i as isize)
1383            };
1384            i += 1;
1385        }
1386    } else {
1387        i = 0;
1388        while i < 2 * nbEBands {
1389            *oldLogE.offset(i as isize) =
1390                if *oldLogE.offset(i as isize) < *oldBandE.offset(i as isize) {
1391                    *oldLogE.offset(i as isize)
1392                } else {
1393                    *oldBandE.offset(i as isize)
1394                };
1395            i += 1;
1396        }
1397    }
1398    c = 0;
1399    loop {
1400        i = 0;
1401        while i < start {
1402            *oldBandE.offset((c * nbEBands + i) as isize) = 0 as opus_val16;
1403            let ref mut fresh0 = *oldLogE2.offset((c * nbEBands + i) as isize);
1404            *fresh0 = -28.0f32;
1405            *oldLogE.offset((c * nbEBands + i) as isize) = *fresh0;
1406            i += 1;
1407        }
1408        i = end;
1409        while i < nbEBands {
1410            *oldBandE.offset((c * nbEBands + i) as isize) = 0 as opus_val16;
1411            let ref mut fresh1 = *oldLogE2.offset((c * nbEBands + i) as isize);
1412            *fresh1 = -28.0f32;
1413            *oldLogE.offset((c * nbEBands + i) as isize) = *fresh1;
1414            i += 1;
1415        }
1416        c += 1;
1417        if !(c < 2) {
1418            break;
1419        }
1420    }
1421    (*st).rng = (*dec).rng;
1422    deemphasis(
1423        out_syn.as_mut_ptr(),
1424        pcm,
1425        N,
1426        CC,
1427        (*st).downsample,
1428        ((*mode).preemph).as_ptr(),
1429        ((*st).preemph_memD).as_mut_ptr(),
1430        accum,
1431    );
1432    (*st).loss_count = 0;
1433    if ec_tell(dec) > 8 * len {
1434        return OPUS_INTERNAL_ERROR;
1435    }
1436    if ec_get_error(dec) != 0 {
1437        (*st).error = 1;
1438    }
1439    return frame_size / (*st).downsample;
1440}
1441pub unsafe fn opus_custom_decoder_ctl_impl(
1442    st: *mut OpusCustomDecoder,
1443    request: i32,
1444    args: VarArgs,
1445) -> i32 {
1446    let current_block: u64;
1447    let mut ap = args;
1448    match request {
1449        CELT_SET_START_BAND_REQUEST => {
1450            let value: i32 = ap.arg::<i32>();
1451            if value < 0 || value >= (*(*st).mode).nbEBands {
1452                current_block = 7990025728955927862;
1453            } else {
1454                (*st).start = value;
1455                current_block = 3689906465960840878;
1456            }
1457        }
1458        CELT_SET_END_BAND_REQUEST => {
1459            let value_0: i32 = ap.arg::<i32>();
1460            if value_0 < 1 || value_0 > (*(*st).mode).nbEBands {
1461                current_block = 7990025728955927862;
1462            } else {
1463                (*st).end = value_0;
1464                current_block = 3689906465960840878;
1465            }
1466        }
1467        CELT_SET_CHANNELS_REQUEST => {
1468            let value_1: i32 = ap.arg::<i32>();
1469            if value_1 < 1 || value_1 > 2 {
1470                current_block = 7990025728955927862;
1471            } else {
1472                (*st).stream_channels = value_1;
1473                current_block = 3689906465960840878;
1474            }
1475        }
1476        CELT_GET_AND_CLEAR_ERROR_REQUEST => {
1477            let value_2: &mut i32 = ap.arg::<&mut i32>();
1478            *value_2 = (*st).error;
1479            (*st).error = 0;
1480            current_block = 3689906465960840878;
1481        }
1482        OPUS_GET_LOOKAHEAD_REQUEST => {
1483            let value_3 = ap.arg::<&mut i32>();
1484            *value_3 = (*st).overlap / (*st).downsample;
1485            current_block = 3689906465960840878;
1486        }
1487        OPUS_RESET_STATE => {
1488            let mut i: i32 = 0;
1489            let mut lpc: *mut opus_val16 = 0 as *mut opus_val16;
1490            let mut oldBandE: *mut opus_val16 = 0 as *mut opus_val16;
1491            let mut oldLogE: *mut opus_val16 = 0 as *mut opus_val16;
1492            let mut oldLogE2: *mut opus_val16 = 0 as *mut opus_val16;
1493            lpc = ((*st)._decode_mem)
1494                .as_mut_ptr()
1495                .offset(((DECODE_BUFFER_SIZE + (*st).overlap) * (*st).channels) as isize)
1496                as *mut opus_val16;
1497            oldBandE = lpc.offset(((*st).channels * LPC_ORDER) as isize);
1498            oldLogE = oldBandE.offset((2 * (*(*st).mode).nbEBands) as isize);
1499            oldLogE2 = oldLogE.offset((2 * (*(*st).mode).nbEBands) as isize);
1500            memset(
1501                &mut (*st).rng as *mut u32 as *mut i8 as *mut core::ffi::c_void,
1502                0,
1503                ((opus_custom_decoder_get_size((*st).mode, (*st).channels) as i64
1504                    - (&mut (*st).rng as *mut u32 as *mut i8).offset_from(st as *mut i8) as i64)
1505                    as u64)
1506                    .wrapping_mul(::core::mem::size_of::<i8>() as u64),
1507            );
1508            i = 0;
1509            while i < 2 * (*(*st).mode).nbEBands {
1510                let ref mut fresh2 = *oldLogE2.offset(i as isize);
1511                *fresh2 = -28.0f32;
1512                *oldLogE.offset(i as isize) = *fresh2;
1513                i += 1;
1514            }
1515            (*st).skip_plc = 1;
1516            current_block = 3689906465960840878;
1517        }
1518        OPUS_GET_PITCH_REQUEST => {
1519            let value_4 = ap.arg::<&mut i32>();
1520            *value_4 = (*st).postfilter_period;
1521            current_block = 3689906465960840878;
1522        }
1523        CELT_GET_MODE_REQUEST => {
1524            let value_5 = ap.arg::<&mut *const OpusCustomMode>();
1525            *value_5 = (*st).mode;
1526            current_block = 3689906465960840878;
1527        }
1528        CELT_SET_SIGNALLING_REQUEST => {
1529            let value_6: i32 = ap.arg::<i32>();
1530            (*st).signalling = value_6;
1531            current_block = 3689906465960840878;
1532        }
1533        OPUS_GET_FINAL_RANGE_REQUEST => {
1534            let value_7 = ap.arg::<&mut u32>();
1535            *value_7 = (*st).rng;
1536            current_block = 3689906465960840878;
1537        }
1538        OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST => {
1539            let value_8: i32 = ap.arg::<i32>();
1540            if value_8 < 0 || value_8 > 1 {
1541                current_block = 7990025728955927862;
1542            } else {
1543                (*st).disable_inv = value_8;
1544                current_block = 3689906465960840878;
1545            }
1546        }
1547        OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST => {
1548            let value_9 = ap.arg::<&mut i32>();
1549            *value_9 = (*st).disable_inv;
1550            current_block = 3689906465960840878;
1551        }
1552        _ => return OPUS_UNIMPLEMENTED,
1553    }
1554    match current_block {
1555        3689906465960840878 => return OPUS_OK,
1556        _ => return OPUS_BAD_ARG,
1557    };
1558}
1559#[macro_export]
1560macro_rules! opus_custom_decoder_ctl {
1561    ($st:expr, $request:expr, $($arg:expr),*) => {
1562        $crate::opus_custom_decoder_ctl_impl($st, $request, $crate::varargs!($($arg),*))
1563    };
1564    ($st:expr, $request:expr) => {
1565        opus_custom_decoder_ctl!($st, $request,)
1566    };
1567    ($st:expr, $request:expr, $($arg:expr),*,) => {
1568        opus_custom_decoder_ctl!($st, $request, $($arg),*)
1569    };
1570}